|
|
|
@ -15,7 +15,7 @@ import {
|
|
|
|
|
getElementAbsoluteCoords,
|
|
|
|
|
getCursorForResizingElement,
|
|
|
|
|
getPerfectElementSize,
|
|
|
|
|
resizePerfectLineForNWHandler
|
|
|
|
|
resizePerfectLineForNWHandler,
|
|
|
|
|
} from "./element";
|
|
|
|
|
import {
|
|
|
|
|
clearSelection,
|
|
|
|
@ -31,7 +31,7 @@ import {
|
|
|
|
|
hasStroke,
|
|
|
|
|
hasText,
|
|
|
|
|
exportCanvas,
|
|
|
|
|
importFromBackend
|
|
|
|
|
importFromBackend,
|
|
|
|
|
} from "./scene";
|
|
|
|
|
|
|
|
|
|
import { renderScene } from "./renderer";
|
|
|
|
@ -71,7 +71,7 @@ import {
|
|
|
|
|
actionLoadScene,
|
|
|
|
|
actionSaveScene,
|
|
|
|
|
actionCopyStyles,
|
|
|
|
|
actionPasteStyles
|
|
|
|
|
actionPasteStyles,
|
|
|
|
|
} from "./actions";
|
|
|
|
|
import { Action, ActionResult } from "./actions/types";
|
|
|
|
|
import { getDefaultAppState } from "./appState";
|
|
|
|
@ -100,7 +100,7 @@ const ELEMENT_TRANSLATE_AMOUNT = 1;
|
|
|
|
|
const TEXT_TO_CENTER_SNAP_THRESHOLD = 30;
|
|
|
|
|
const CURSOR_TYPE = {
|
|
|
|
|
TEXT: "text",
|
|
|
|
|
CROSSHAIR: "crosshair"
|
|
|
|
|
CROSSHAIR: "crosshair",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let lastCanvasWidth = -1;
|
|
|
|
@ -110,7 +110,7 @@ let lastMouseUp: ((e: any) => void) | null = null;
|
|
|
|
|
|
|
|
|
|
export function viewportCoordsToSceneCoords(
|
|
|
|
|
{ clientX, clientY }: { clientX: number; clientY: number },
|
|
|
|
|
{ scrollX, scrollY }: { scrollX: number; scrollY: number }
|
|
|
|
|
{ scrollX, scrollY }: { scrollX: number; scrollY: number },
|
|
|
|
|
) {
|
|
|
|
|
const x = clientX - CANVAS_WINDOW_OFFSET_LEFT - scrollX;
|
|
|
|
|
const y = clientY - CANVAS_WINDOW_OFFSET_TOP - scrollY;
|
|
|
|
@ -118,7 +118,7 @@ export function viewportCoordsToSceneCoords(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function pickAppStatePropertiesForHistory(
|
|
|
|
|
appState: AppState
|
|
|
|
|
appState: AppState,
|
|
|
|
|
): Partial<AppState> {
|
|
|
|
|
return {
|
|
|
|
|
exportBackground: appState.exportBackground,
|
|
|
|
@ -126,7 +126,7 @@ function pickAppStatePropertiesForHistory(
|
|
|
|
|
currentItemBackgroundColor: appState.currentItemBackgroundColor,
|
|
|
|
|
currentItemFont: appState.currentItemFont,
|
|
|
|
|
viewBackgroundColor: appState.viewBackgroundColor,
|
|
|
|
|
name: appState.name
|
|
|
|
|
name: appState.name,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -186,8 +186,8 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
JSON.stringify(
|
|
|
|
|
elements
|
|
|
|
|
.filter(element => element.isSelected)
|
|
|
|
|
.map(({ shape, ...el }) => el)
|
|
|
|
|
)
|
|
|
|
|
.map(({ shape, ...el }) => el),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
elements = deleteSelectedElements(elements);
|
|
|
|
|
this.forceUpdate();
|
|
|
|
@ -200,8 +200,8 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
JSON.stringify(
|
|
|
|
|
elements
|
|
|
|
|
.filter(element => element.isSelected)
|
|
|
|
|
.map(({ shape, ...el }) => el)
|
|
|
|
|
)
|
|
|
|
|
.map(({ shape, ...el }) => el),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
};
|
|
|
|
@ -257,7 +257,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
document.removeEventListener(
|
|
|
|
|
"mousemove",
|
|
|
|
|
this.getCurrentCursorPosition,
|
|
|
|
|
false
|
|
|
|
|
false,
|
|
|
|
|
);
|
|
|
|
|
window.removeEventListener("resize", this.onResize, false);
|
|
|
|
|
window.removeEventListener("unload", this.onUnload, false);
|
|
|
|
@ -354,7 +354,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
const text = JSON.stringify(
|
|
|
|
|
elements
|
|
|
|
|
.filter(element => element.isSelected)
|
|
|
|
|
.map(({ shape, ...el }) => el)
|
|
|
|
|
.map(({ shape, ...el }) => el),
|
|
|
|
|
);
|
|
|
|
|
navigator.clipboard.writeText(text);
|
|
|
|
|
}
|
|
|
|
@ -393,7 +393,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
t
|
|
|
|
|
t,
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{(hasBackground(elements) ||
|
|
|
|
@ -404,7 +404,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
t
|
|
|
|
|
t,
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{this.actionManager.renderAction(
|
|
|
|
@ -412,7 +412,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
t
|
|
|
|
|
t,
|
|
|
|
|
)}
|
|
|
|
|
<hr />
|
|
|
|
|
</>
|
|
|
|
@ -426,7 +426,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
t
|
|
|
|
|
t,
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{this.actionManager.renderAction(
|
|
|
|
@ -434,7 +434,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
t
|
|
|
|
|
t,
|
|
|
|
|
)}
|
|
|
|
|
<hr />
|
|
|
|
|
</>
|
|
|
|
@ -447,7 +447,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
t
|
|
|
|
|
t,
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{this.actionManager.renderAction(
|
|
|
|
@ -455,7 +455,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
t
|
|
|
|
|
t,
|
|
|
|
|
)}
|
|
|
|
|
<hr />
|
|
|
|
|
</>
|
|
|
|
@ -466,7 +466,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
t
|
|
|
|
|
t,
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{this.actionManager.renderAction(
|
|
|
|
@ -474,7 +474,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
t
|
|
|
|
|
t,
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</Island>
|
|
|
|
@ -533,14 +533,14 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
t
|
|
|
|
|
t,
|
|
|
|
|
)}
|
|
|
|
|
{this.actionManager.renderAction(
|
|
|
|
|
"saveScene",
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
t
|
|
|
|
|
t,
|
|
|
|
|
)}
|
|
|
|
|
<ExportDialog
|
|
|
|
|
elements={elements}
|
|
|
|
@ -553,7 +553,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
exportBackground: this.state.exportBackground,
|
|
|
|
|
name: this.state.name,
|
|
|
|
|
viewBackgroundColor: this.state.viewBackgroundColor,
|
|
|
|
|
scale
|
|
|
|
|
scale,
|
|
|
|
|
});
|
|
|
|
|
}}
|
|
|
|
|
onExportToClipboard={(exportedElements, scale) => {
|
|
|
|
@ -562,7 +562,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
exportBackground: this.state.exportBackground,
|
|
|
|
|
name: this.state.name,
|
|
|
|
|
viewBackgroundColor: this.state.viewBackgroundColor,
|
|
|
|
|
scale
|
|
|
|
|
scale,
|
|
|
|
|
});
|
|
|
|
|
}}
|
|
|
|
|
onExportToBackend={exportedElements => {
|
|
|
|
@ -571,10 +571,10 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
"backend",
|
|
|
|
|
exportedElements.map(element => ({
|
|
|
|
|
...element,
|
|
|
|
|
isSelected: false
|
|
|
|
|
isSelected: false,
|
|
|
|
|
})),
|
|
|
|
|
this.canvas,
|
|
|
|
|
this.state
|
|
|
|
|
this.state,
|
|
|
|
|
);
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
@ -583,7 +583,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
t
|
|
|
|
|
t,
|
|
|
|
|
)}
|
|
|
|
|
</Stack.Row>
|
|
|
|
|
{this.actionManager.renderAction(
|
|
|
|
@ -591,7 +591,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
t
|
|
|
|
|
t,
|
|
|
|
|
)}
|
|
|
|
|
</Stack.Col>
|
|
|
|
|
);
|
|
|
|
@ -626,7 +626,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
id="canvas"
|
|
|
|
|
style={{
|
|
|
|
|
width: canvasWidth,
|
|
|
|
|
height: canvasHeight
|
|
|
|
|
height: canvasHeight,
|
|
|
|
|
}}
|
|
|
|
|
width={canvasWidth * window.devicePixelRatio}
|
|
|
|
|
height={canvasHeight * window.devicePixelRatio}
|
|
|
|
@ -641,7 +641,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
}
|
|
|
|
|
if (canvas) {
|
|
|
|
|
canvas.addEventListener("wheel", this.handleWheel, {
|
|
|
|
|
passive: false
|
|
|
|
|
passive: false,
|
|
|
|
|
});
|
|
|
|
|
this.removeWheelEventListener = () =>
|
|
|
|
|
canvas.removeEventListener("wheel", this.handleWheel);
|
|
|
|
@ -670,18 +670,18 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
options: [
|
|
|
|
|
navigator.clipboard && {
|
|
|
|
|
label: t("labels.paste"),
|
|
|
|
|
action: () => this.pasteFromClipboard()
|
|
|
|
|
action: () => this.pasteFromClipboard(),
|
|
|
|
|
},
|
|
|
|
|
...this.actionManager.getContextMenuItems(
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
action => this.canvasOnlyActions.includes(action),
|
|
|
|
|
t
|
|
|
|
|
)
|
|
|
|
|
t,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
top: e.clientY,
|
|
|
|
|
left: e.clientX
|
|
|
|
|
left: e.clientX,
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -696,22 +696,22 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
options: [
|
|
|
|
|
navigator.clipboard && {
|
|
|
|
|
label: t("labels.copy"),
|
|
|
|
|
action: this.copyToClipboard
|
|
|
|
|
action: this.copyToClipboard,
|
|
|
|
|
},
|
|
|
|
|
navigator.clipboard && {
|
|
|
|
|
label: t("labels.paste"),
|
|
|
|
|
action: () => this.pasteFromClipboard()
|
|
|
|
|
action: () => this.pasteFromClipboard(),
|
|
|
|
|
},
|
|
|
|
|
...this.actionManager.getContextMenuItems(
|
|
|
|
|
elements,
|
|
|
|
|
this.state,
|
|
|
|
|
this.syncActionResult,
|
|
|
|
|
action => !this.canvasOnlyActions.includes(action),
|
|
|
|
|
t
|
|
|
|
|
)
|
|
|
|
|
t,
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
top: e.clientY,
|
|
|
|
|
left: e.clientX
|
|
|
|
|
left: e.clientX,
|
|
|
|
|
});
|
|
|
|
|
}}
|
|
|
|
|
onMouseDown={e => {
|
|
|
|
@ -733,7 +733,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
lastY = e.clientY;
|
|
|
|
|
this.setState(state => ({
|
|
|
|
|
scrollX: state.scrollX - deltaX,
|
|
|
|
|
scrollY: state.scrollY - deltaY
|
|
|
|
|
scrollY: state.scrollY - deltaY,
|
|
|
|
|
}));
|
|
|
|
|
};
|
|
|
|
|
const onMouseUp = (lastMouseUp = (e: MouseEvent) => {
|
|
|
|
@ -743,7 +743,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
window.removeEventListener("mouseup", onMouseUp);
|
|
|
|
|
});
|
|
|
|
|
window.addEventListener("mousemove", onMouseMove, {
|
|
|
|
|
passive: true
|
|
|
|
|
passive: true,
|
|
|
|
|
});
|
|
|
|
|
window.addEventListener("mouseup", onMouseUp);
|
|
|
|
|
return;
|
|
|
|
@ -763,7 +763,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
// Handle scrollbars dragging
|
|
|
|
|
const {
|
|
|
|
|
isOverHorizontalScrollBar,
|
|
|
|
|
isOverVerticalScrollBar
|
|
|
|
|
isOverVerticalScrollBar,
|
|
|
|
|
} = isOverScrollBars(
|
|
|
|
|
elements,
|
|
|
|
|
e.clientX - CANVAS_WINDOW_OFFSET_LEFT,
|
|
|
|
@ -771,7 +771,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
canvasWidth,
|
|
|
|
|
canvasHeight,
|
|
|
|
|
this.state.scrollX,
|
|
|
|
|
this.state.scrollY
|
|
|
|
|
this.state.scrollY,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const { x, y } = viewportCoordsToSceneCoords(e, this.state);
|
|
|
|
@ -785,7 +785,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
"hachure",
|
|
|
|
|
1,
|
|
|
|
|
1,
|
|
|
|
|
100
|
|
|
|
|
100,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (isTextElement(element)) {
|
|
|
|
@ -802,16 +802,16 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
const resizeElement = getElementWithResizeHandler(
|
|
|
|
|
elements,
|
|
|
|
|
{ x, y },
|
|
|
|
|
this.state
|
|
|
|
|
this.state,
|
|
|
|
|
);
|
|
|
|
|
this.setState({
|
|
|
|
|
resizingElement: resizeElement ? resizeElement.element : null
|
|
|
|
|
resizingElement: resizeElement ? resizeElement.element : null,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (resizeElement) {
|
|
|
|
|
resizeHandle = resizeElement.resizeHandle;
|
|
|
|
|
document.documentElement.style.cursor = getCursorForResizingElement(
|
|
|
|
|
resizeElement
|
|
|
|
|
resizeElement,
|
|
|
|
|
);
|
|
|
|
|
isResizingElements = true;
|
|
|
|
|
} else {
|
|
|
|
@ -837,7 +837,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elements = [
|
|
|
|
|
...elements.map(element => ({
|
|
|
|
|
...element,
|
|
|
|
|
isSelected: false
|
|
|
|
|
isSelected: false,
|
|
|
|
|
})),
|
|
|
|
|
...elements
|
|
|
|
|
.filter(element => element.isSelected)
|
|
|
|
@ -845,7 +845,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
const newElement = duplicateElement(element);
|
|
|
|
|
newElement.isSelected = true;
|
|
|
|
|
return newElement;
|
|
|
|
|
})
|
|
|
|
|
}),
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -860,7 +860,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
if (!e.altKey) {
|
|
|
|
|
const snappedToCenterPosition = this.getTextWysiwygSnappedToCenterPosition(
|
|
|
|
|
x,
|
|
|
|
|
y
|
|
|
|
|
y,
|
|
|
|
|
);
|
|
|
|
|
if (snappedToCenterPosition) {
|
|
|
|
|
element.x = snappedToCenterPosition.elementCenterX;
|
|
|
|
@ -884,22 +884,22 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
...newTextElement(
|
|
|
|
|
element,
|
|
|
|
|
text,
|
|
|
|
|
this.state.currentItemFont
|
|
|
|
|
this.state.currentItemFont,
|
|
|
|
|
),
|
|
|
|
|
isSelected: true
|
|
|
|
|
}
|
|
|
|
|
isSelected: true,
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
this.setState({
|
|
|
|
|
draggingElement: null,
|
|
|
|
|
editingElement: null,
|
|
|
|
|
elementType: "selection"
|
|
|
|
|
elementType: "selection",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
this.setState({
|
|
|
|
|
elementType: "selection",
|
|
|
|
|
editingElement: element
|
|
|
|
|
editingElement: element,
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -993,7 +993,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
const { width, height } = getPerfectElementSize(
|
|
|
|
|
element.type,
|
|
|
|
|
x - element.x,
|
|
|
|
|
y - element.y
|
|
|
|
|
y - element.y,
|
|
|
|
|
);
|
|
|
|
|
element.width = width;
|
|
|
|
|
element.height = height;
|
|
|
|
@ -1023,7 +1023,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
document.documentElement.style.cursor = getCursorForResizingElement(
|
|
|
|
|
{ element, resizeHandle }
|
|
|
|
|
{ element, resizeHandle },
|
|
|
|
|
);
|
|
|
|
|
el.x = element.x;
|
|
|
|
|
el.y = element.y;
|
|
|
|
@ -1078,11 +1078,11 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
if (e.shiftKey) {
|
|
|
|
|
let {
|
|
|
|
|
width: newWidth,
|
|
|
|
|
height: newHeight
|
|
|
|
|
height: newHeight,
|
|
|
|
|
} = getPerfectElementSize(
|
|
|
|
|
this.state.elementType,
|
|
|
|
|
width,
|
|
|
|
|
height
|
|
|
|
|
height,
|
|
|
|
|
);
|
|
|
|
|
draggingElement.width = newWidth;
|
|
|
|
|
draggingElement.height = newHeight;
|
|
|
|
@ -1099,7 +1099,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
}
|
|
|
|
|
const elementsWithinSelection = getElementsWithinSelection(
|
|
|
|
|
elements,
|
|
|
|
|
draggingElement
|
|
|
|
|
draggingElement,
|
|
|
|
|
);
|
|
|
|
|
elementsWithinSelection.forEach(element => {
|
|
|
|
|
element.isSelected = true;
|
|
|
|
@ -1115,7 +1115,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
draggingElement,
|
|
|
|
|
resizingElement,
|
|
|
|
|
elementType,
|
|
|
|
|
elementLocked
|
|
|
|
|
elementLocked,
|
|
|
|
|
} = this.state;
|
|
|
|
|
|
|
|
|
|
lastMouseUp = null;
|
|
|
|
@ -1130,7 +1130,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
// remove invisible element which was added in onMouseDown
|
|
|
|
|
elements = elements.slice(0, -1);
|
|
|
|
|
this.setState({
|
|
|
|
|
draggingElement: null
|
|
|
|
|
draggingElement: null,
|
|
|
|
|
});
|
|
|
|
|
this.forceUpdate();
|
|
|
|
|
return;
|
|
|
|
@ -1179,7 +1179,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
|
draggingElement: null,
|
|
|
|
|
elementType: "selection"
|
|
|
|
|
elementType: "selection",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1214,10 +1214,10 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
"hachure",
|
|
|
|
|
1,
|
|
|
|
|
1,
|
|
|
|
|
100
|
|
|
|
|
100,
|
|
|
|
|
),
|
|
|
|
|
"", // default text
|
|
|
|
|
this.state.currentItemFont // default font
|
|
|
|
|
this.state.currentItemFont, // default font
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
this.setState({ editingElement: element });
|
|
|
|
@ -1227,7 +1227,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
|
|
|
|
|
if (elementAtPosition && isTextElement(elementAtPosition)) {
|
|
|
|
|
elements = elements.filter(
|
|
|
|
|
element => element.id !== elementAtPosition.id
|
|
|
|
|
element => element.id !== elementAtPosition.id,
|
|
|
|
|
);
|
|
|
|
|
this.forceUpdate();
|
|
|
|
|
|
|
|
|
@ -1248,7 +1248,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
} else if (!e.altKey) {
|
|
|
|
|
const snappedToCenterPosition = this.getTextWysiwygSnappedToCenterPosition(
|
|
|
|
|
x,
|
|
|
|
|
y
|
|
|
|
|
y,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (snappedToCenterPosition) {
|
|
|
|
@ -1273,16 +1273,16 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
// we need to recreate the element to update dimensions &
|
|
|
|
|
// position
|
|
|
|
|
...newTextElement(element, text, element.font),
|
|
|
|
|
isSelected: true
|
|
|
|
|
}
|
|
|
|
|
isSelected: true,
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
this.setState({
|
|
|
|
|
draggingElement: null,
|
|
|
|
|
editingElement: null,
|
|
|
|
|
elementType: "selection"
|
|
|
|
|
elementType: "selection",
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}}
|
|
|
|
|
onMouseMove={e => {
|
|
|
|
@ -1296,11 +1296,11 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
const resizeElement = getElementWithResizeHandler(
|
|
|
|
|
elements,
|
|
|
|
|
{ x, y },
|
|
|
|
|
this.state
|
|
|
|
|
this.state,
|
|
|
|
|
);
|
|
|
|
|
if (resizeElement && resizeElement.resizeHandle) {
|
|
|
|
|
document.documentElement.style.cursor = getCursorForResizingElement(
|
|
|
|
|
resizeElement
|
|
|
|
|
resizeElement,
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -1327,7 +1327,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
const { deltaX, deltaY } = e;
|
|
|
|
|
this.setState(state => ({
|
|
|
|
|
scrollX: state.scrollX - deltaX,
|
|
|
|
|
scrollY: state.scrollY - deltaY
|
|
|
|
|
scrollY: state.scrollY - deltaY,
|
|
|
|
|
}));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -1384,7 +1384,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
duplicate.x += dx - minX;
|
|
|
|
|
duplicate.y += dy - minY;
|
|
|
|
|
return duplicate;
|
|
|
|
|
})
|
|
|
|
|
}),
|
|
|
|
|
];
|
|
|
|
|
this.forceUpdate();
|
|
|
|
|
}
|
|
|
|
@ -1399,7 +1399,7 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
elementClickedInside.y + elementClickedInside.height / 2;
|
|
|
|
|
const distanceToCenter = Math.hypot(
|
|
|
|
|
x - elementCenterX,
|
|
|
|
|
y - elementCenterY
|
|
|
|
|
y - elementCenterY,
|
|
|
|
|
);
|
|
|
|
|
const isSnappedToCenter =
|
|
|
|
|
distanceToCenter < TEXT_TO_CENTER_SNAP_THRESHOLD;
|
|
|
|
@ -1427,15 +1427,15 @@ export class App extends React.Component<any, AppState> {
|
|
|
|
|
renderScene(elements, this.rc!, this.canvas!, {
|
|
|
|
|
scrollX: this.state.scrollX,
|
|
|
|
|
scrollY: this.state.scrollY,
|
|
|
|
|
viewBackgroundColor: this.state.viewBackgroundColor
|
|
|
|
|
viewBackgroundColor: this.state.viewBackgroundColor,
|
|
|
|
|
});
|
|
|
|
|
this.saveDebounced();
|
|
|
|
|
if (history.isRecording()) {
|
|
|
|
|
history.pushEntry(
|
|
|
|
|
history.generateCurrentEntry(
|
|
|
|
|
pickAppStatePropertiesForHistory(this.state),
|
|
|
|
|
elements
|
|
|
|
|
)
|
|
|
|
|
elements,
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1453,7 +1453,7 @@ class TopErrorBoundary extends React.Component {
|
|
|
|
|
return {
|
|
|
|
|
hasError: true,
|
|
|
|
|
localStorage: JSON.stringify({ ...localStorage }),
|
|
|
|
|
stack: error.stack
|
|
|
|
|
stack: error.stack,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1471,7 +1471,7 @@ class TopErrorBoundary extends React.Component {
|
|
|
|
|
} catch {}
|
|
|
|
|
|
|
|
|
|
window.open(
|
|
|
|
|
`https://github.com/excalidraw/excalidraw/issues/new?body=${body}`
|
|
|
|
|
`https://github.com/excalidraw/excalidraw/issues/new?body=${body}`,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1539,5 +1539,5 @@ ReactDOM.render(
|
|
|
|
|
<TopErrorBoundary>
|
|
|
|
|
<AppWithTrans />
|
|
|
|
|
</TopErrorBoundary>,
|
|
|
|
|
rootElement
|
|
|
|
|
rootElement,
|
|
|
|
|
);
|
|
|
|
|