mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Add free draw mode (#1570)
This commit is contained in:
parent
36e0c439fb
commit
9ec43d2626
21 changed files with 344 additions and 49 deletions
|
@ -94,11 +94,11 @@ export function ShapesSwitcher({
|
|||
}) {
|
||||
return (
|
||||
<>
|
||||
{SHAPES.map(({ value, icon }, index) => {
|
||||
{SHAPES.map(({ value, icon, key }, index) => {
|
||||
const label = t(`toolBar.${value}`);
|
||||
const shortcut = `${capitalizeString(value)[0]} ${t(
|
||||
"shortcutsDialog.or",
|
||||
)} ${index + 1}`;
|
||||
const shortcut = `${capitalizeString(key)} ${t("shortcutsDialog.or")} ${
|
||||
index + 1
|
||||
}`;
|
||||
return (
|
||||
<ToolButton
|
||||
key={value}
|
||||
|
@ -109,7 +109,7 @@ export function ShapesSwitcher({
|
|||
title={`${capitalizeString(label)} — ${shortcut}`}
|
||||
keyBindingLabel={`${index + 1}`}
|
||||
aria-label={capitalizeString(label)}
|
||||
aria-keyshortcuts={`${label[0]} ${index + 1}`}
|
||||
aria-keyshortcuts={`${key} ${index + 1}`}
|
||||
data-testid={value}
|
||||
onChange={() => {
|
||||
setAppState({
|
||||
|
|
|
@ -3,6 +3,7 @@ import React from "react";
|
|||
import socketIOClient from "socket.io-client";
|
||||
import rough from "roughjs/bin/rough";
|
||||
import { RoughCanvas } from "roughjs/bin/canvas";
|
||||
import { simplify, Point } from "points-on-curve";
|
||||
import { FlooredNumber, SocketUpdateData } from "../types";
|
||||
|
||||
import {
|
||||
|
@ -1981,6 +1982,7 @@ class App extends React.Component<any, AppState> {
|
|||
return;
|
||||
} else if (
|
||||
this.state.elementType === "arrow" ||
|
||||
this.state.elementType === "draw" ||
|
||||
this.state.elementType === "line"
|
||||
) {
|
||||
if (this.state.multiElement) {
|
||||
|
@ -2122,7 +2124,7 @@ class App extends React.Component<any, AppState> {
|
|||
window.devicePixelRatio,
|
||||
);
|
||||
|
||||
// for arrows, don't start dragging until a given threshold
|
||||
// for arrows/lines, don't start dragging until a given threshold
|
||||
// to ensure we don't create a 2-point arrow by mistake when
|
||||
// user clicks mouse in a way that it moves a tiny bit (thus
|
||||
// triggering pointermove)
|
||||
|
@ -2249,9 +2251,15 @@ class App extends React.Component<any, AppState> {
|
|||
if (points.length === 1) {
|
||||
mutateElement(draggingElement, { points: [...points, [dx, dy]] });
|
||||
} else if (points.length > 1) {
|
||||
mutateElement(draggingElement, {
|
||||
points: [...points.slice(0, -1), [dx, dy]],
|
||||
});
|
||||
if (draggingElement.type === "draw") {
|
||||
mutateElement(draggingElement, {
|
||||
points: simplify([...(points as Point[]), [dx, dy]], 0.7),
|
||||
});
|
||||
} else {
|
||||
mutateElement(draggingElement, {
|
||||
points: [...points.slice(0, -1), [dx, dy]],
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (getResizeWithSidesSameLengthKey(event)) {
|
||||
|
@ -2330,6 +2338,10 @@ class App extends React.Component<any, AppState> {
|
|||
window.removeEventListener(EVENT.POINTER_MOVE, onPointerMove);
|
||||
window.removeEventListener(EVENT.POINTER_UP, onPointerUp);
|
||||
|
||||
if (draggingElement?.type === "draw") {
|
||||
this.actionManager.executeAction(actionFinalize);
|
||||
return;
|
||||
}
|
||||
if (isLinearElement(draggingElement)) {
|
||||
if (draggingElement!.points.length > 1) {
|
||||
history.resumeRecording();
|
||||
|
|
|
@ -22,6 +22,10 @@ const getHints = ({ appState, elements }: Hint) => {
|
|||
return t("hints.linearElementMulti");
|
||||
}
|
||||
|
||||
if (elementType === "draw") {
|
||||
return t("hints.freeDraw");
|
||||
}
|
||||
|
||||
const selectedElements = getSelectedElements(elements, appState);
|
||||
if (
|
||||
isResizing &&
|
||||
|
|
|
@ -184,7 +184,8 @@ export const ShortcutsDialog = ({ onClose }: { onClose?: () => void }) => {
|
|||
<Shortcut label={t("toolBar.ellipse")} shortcuts={["E", "4"]} />
|
||||
<Shortcut label={t("toolBar.arrow")} shortcuts={["A", "5"]} />
|
||||
<Shortcut label={t("toolBar.line")} shortcuts={["L", "6"]} />
|
||||
<Shortcut label={t("toolBar.text")} shortcuts={["T", "7"]} />
|
||||
<Shortcut label={t("toolBar.draw")} shortcuts={["X", "7"]} />
|
||||
<Shortcut label={t("toolBar.text")} shortcuts={["T", "8"]} />
|
||||
<Shortcut
|
||||
label={t("shortcutsDialog.textNewLine")}
|
||||
shortcuts={[
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue