mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Toggle shapeSnap
This commit is contained in:
parent
452373d769
commit
5ac50bdc88
8 changed files with 188 additions and 113 deletions
|
@ -121,6 +121,8 @@ import {
|
|||
ArrowheadCrowfootIcon,
|
||||
ArrowheadCrowfootOneIcon,
|
||||
ArrowheadCrowfootOneOrManyIcon,
|
||||
snapShapeEnabledIcon,
|
||||
snapShapeDisabledIcon,
|
||||
} from "../components/icons";
|
||||
|
||||
import { Fonts } from "../fonts";
|
||||
|
@ -1818,3 +1820,41 @@ export const actionChangeArrowType = register({
|
|||
);
|
||||
},
|
||||
});
|
||||
|
||||
export const actionToggleShapeSnap = register({
|
||||
name: "toggleShapeSnap",
|
||||
label: "Toggle Snap to Shape",
|
||||
trackEvent: false,
|
||||
perform: (elements, appState) => {
|
||||
return {
|
||||
elements,
|
||||
appState: {
|
||||
...appState,
|
||||
isShapeSnapEnabled: !appState.isShapeSnapEnabled,
|
||||
},
|
||||
captureUpdate: CaptureUpdateAction.IMMEDIATELY,
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ appState, updateData }) => (
|
||||
<fieldset>
|
||||
<legend>{t("labels.shapeSnap")}</legend>
|
||||
<ButtonIconSelect
|
||||
group="button"
|
||||
options={[
|
||||
{
|
||||
value: false,
|
||||
text: t("labels.shapeSnapDisable"),
|
||||
icon: snapShapeDisabledIcon,
|
||||
},
|
||||
{
|
||||
value: true,
|
||||
text: t("labels.shapeSnapEnable"),
|
||||
icon: snapShapeEnabledIcon,
|
||||
},
|
||||
]}
|
||||
value={appState.isShapeSnapEnabled}
|
||||
onChange={(value) => updateData(value)}
|
||||
/>
|
||||
</fieldset>
|
||||
),
|
||||
});
|
||||
|
|
|
@ -125,6 +125,7 @@ export type ActionName =
|
|||
| "toggleLinearEditor"
|
||||
| "toggleEraserTool"
|
||||
| "toggleHandTool"
|
||||
| "toggleShapeSnap"
|
||||
| "selectAllElementsInFrame"
|
||||
| "removeAllElementsFromFrame"
|
||||
| "updateFrameRendering"
|
||||
|
|
|
@ -188,7 +188,7 @@ const APP_STATE_STORAGE_CONF = (<
|
|||
gridModeEnabled: { browser: true, export: true, server: true },
|
||||
height: { browser: false, export: false, server: false },
|
||||
isBindingEnabled: { browser: false, export: false, server: false },
|
||||
isShapeSnapEnabled: { browser: false, export: false, server: false },
|
||||
isShapeSnapEnabled: { browser: true, export: false, server: false },
|
||||
defaultSidebarDockedPreference: {
|
||||
browser: true,
|
||||
export: false,
|
||||
|
|
|
@ -169,9 +169,12 @@ export const SelectedShapeActions = ({
|
|||
renderAction("changeStrokeWidth")}
|
||||
|
||||
{(appState.activeTool.type === "freedraw" ||
|
||||
targetElements.some((element) => element.type === "freedraw")) &&
|
||||
renderAction("changeStrokeShape")}
|
||||
|
||||
targetElements.some((element) => element.type === "freedraw")) && (
|
||||
<>
|
||||
{renderAction("changeStrokeShape")}
|
||||
{renderAction("toggleShapeSnap")}
|
||||
</>
|
||||
)}
|
||||
{(hasStrokeStyle(appState.activeTool.type) ||
|
||||
targetElements.some((element) => hasStrokeStyle(element.type))) && (
|
||||
<>
|
||||
|
|
|
@ -8959,7 +8959,19 @@ class App extends React.Component<AppProps, AppState> {
|
|||
|
||||
if (this.state.isShapeSnapEnabled) {
|
||||
const detectedElement = convertToShape(newElement);
|
||||
|
||||
if (detectedElement !== newElement) {
|
||||
if (detectedElement.type === "arrow") {
|
||||
mutateElement(
|
||||
detectedElement,
|
||||
{
|
||||
startArrowhead: this.state.currentItemStartArrowhead,
|
||||
endArrowhead: this.state.currentItemEndArrowhead,
|
||||
},
|
||||
// TODO: Make arrows bind to nearby elements if possible
|
||||
);
|
||||
}
|
||||
|
||||
this.scene.replaceAllElements([
|
||||
...this.scene
|
||||
.getElementsIncludingDeleted()
|
||||
|
|
|
@ -1887,6 +1887,23 @@ export const eyeClosedIcon = createIcon(
|
|||
tablerIconProps,
|
||||
);
|
||||
|
||||
export const snapShapeEnabledIcon = createIcon(
|
||||
<g stroke="currentColor" fill="none" strokeWidth="1.5">
|
||||
<rect x="4" y="4" width="16" height="16" rx="2" />
|
||||
<circle cx="16" cy="8" r="1.5" fill="currentColor" />
|
||||
</g>,
|
||||
tablerIconProps,
|
||||
);
|
||||
|
||||
export const snapShapeDisabledIcon = createIcon(
|
||||
<g stroke="currentColor" fill="none" strokeWidth="1.5">
|
||||
<rect x="4" y="4" width="16" height="16" rx="2" />
|
||||
<line x1="4" y1="4" x2="20" y2="20" />
|
||||
<line x1="4" y1="20" x2="20" y2="4" />
|
||||
</g>,
|
||||
tablerIconProps,
|
||||
);
|
||||
|
||||
export const brainIcon = createIcon(
|
||||
<g stroke="currentColor" fill="none">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
|
|
|
@ -103,6 +103,9 @@
|
|||
"loadingScene": "Loading scene…",
|
||||
"loadScene": "Load scene from file",
|
||||
"align": "Align",
|
||||
"shapeSnap": "Snap to shapes",
|
||||
"shapeSnapDisable": "Disable snap to shapes",
|
||||
"shapeSnapEnable": "Enable snap to shapes",
|
||||
"alignTop": "Align top",
|
||||
"alignBottom": "Align bottom",
|
||||
"alignLeft": "Align left",
|
||||
|
|
|
@ -390,7 +390,6 @@ export const convertToShape = (
|
|||
return newArrowElement({
|
||||
...freeDrawElement,
|
||||
type: recognizedShape.type,
|
||||
endArrowhead: "arrow", // TODO: Get correct state
|
||||
points: [
|
||||
recognizedShape.simplified[0],
|
||||
recognizedShape.simplified[recognizedShape.simplified.length - 2]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue