feat: Added penMode for palm rejection ()

Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
zsviczian 2022-02-02 14:31:38 +01:00 committed by GitHub
parent edfbac9d7d
commit 4486fbc2c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 305 additions and 4 deletions

@ -58,6 +58,8 @@ export const actionClearCanvas = register({
files: {}, files: {},
theme: appState.theme, theme: appState.theme,
elementLocked: appState.elementLocked, elementLocked: appState.elementLocked,
penMode: appState.penMode,
penDetected: appState.penDetected,
exportBackground: appState.exportBackground, exportBackground: appState.exportBackground,
exportEmbedScene: appState.exportEmbedScene, exportEmbedScene: appState.exportEmbedScene,
gridSize: appState.gridSize, gridSize: appState.gridSize,

@ -43,6 +43,8 @@ export const getDefaultAppState = (): Omit<
editingLinearElement: null, editingLinearElement: null,
elementLocked: false, elementLocked: false,
elementType: "selection", elementType: "selection",
penMode: false,
penDetected: false,
errorMessage: null, errorMessage: null,
exportBackground: true, exportBackground: true,
exportScale: defaultExportScale, exportScale: defaultExportScale,
@ -129,6 +131,8 @@ const APP_STATE_STORAGE_CONF = (<
editingLinearElement: { browser: false, export: false, server: false }, editingLinearElement: { browser: false, export: false, server: false },
elementLocked: { browser: true, export: false, server: false }, elementLocked: { browser: true, export: false, server: false },
elementType: { browser: true, export: false, server: false }, elementType: { browser: true, export: false, server: false },
penMode: { browser: false, export: false, server: false },
penDetected: { browser: false, export: false, server: false },
errorMessage: { browser: false, export: false, server: false }, errorMessage: { browser: false, export: false, server: false },
exportBackground: { browser: true, export: false, server: false }, exportBackground: { browser: true, export: false, server: false },
exportEmbedScene: { browser: true, export: false, server: false }, exportEmbedScene: { browser: true, export: false, server: false },

@ -467,6 +467,7 @@ class App extends React.Component<AppProps, AppState> {
elements={this.scene.getElements()} elements={this.scene.getElements()}
onCollabButtonClick={onCollabButtonClick} onCollabButtonClick={onCollabButtonClick}
onLockToggle={this.toggleLock} onLockToggle={this.toggleLock}
onPenModeToggle={this.togglePenMode}
onInsertElements={(elements) => onInsertElements={(elements) =>
this.addElementsFromPasteOrLibrary({ this.addElementsFromPasteOrLibrary({
elements, elements,
@ -1501,6 +1502,14 @@ class App extends React.Component<AppProps, AppState> {
}); });
}; };
togglePenMode = () => {
this.setState((prevState) => {
return {
penMode: !prevState.penMode,
};
});
};
toggleZenMode = () => { toggleZenMode = () => {
this.actionManager.executeAction(actionToggleZenMode); this.actionManager.executeAction(actionToggleZenMode);
}; };
@ -2324,7 +2333,10 @@ class App extends React.Component<AppProps, AppState> {
gesture.lastCenter = center; gesture.lastCenter = center;
const distance = getDistance(Array.from(gesture.pointers.values())); const distance = getDistance(Array.from(gesture.pointers.values()));
const scaleFactor = distance / gesture.initialDistance; const scaleFactor =
this.state.elementType === "freedraw" && this.state.penMode
? 1
: distance / gesture.initialDistance;
const nextZoom = scaleFactor const nextZoom = scaleFactor
? getNormalizedZoom(initialScale * scaleFactor) ? getNormalizedZoom(initialScale * scaleFactor)
@ -2586,6 +2598,17 @@ class App extends React.Component<AppProps, AppState> {
this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event); this.maybeOpenContextMenuAfterPointerDownOnTouchDevices(event);
this.maybeCleanupAfterMissingPointerUp(event); this.maybeCleanupAfterMissingPointerUp(event);
//fires only once, if pen is detected, penMode is enabled
//the user can disable this by toggling the penMode button
if (!this.state.penDetected && event.pointerType === "pen") {
this.setState((prevState) => {
return {
penMode: true,
penDetected: true,
};
});
}
if (isPanning) { if (isPanning) {
return; return;
} }
@ -2630,6 +2653,17 @@ class App extends React.Component<AppProps, AppState> {
return; return;
} }
const allowOnPointerDown =
!this.state.penMode ||
event.pointerType !== "touch" ||
this.state.elementType === "selection" ||
this.state.elementType === "text" ||
this.state.elementType === "image";
if (!allowOnPointerDown) {
return;
}
if (this.state.elementType === "text") { if (this.state.elementType === "text") {
this.handleTextOnPointerDown(event, pointerDownState); this.handleTextOnPointerDown(event, pointerDownState);
return; return;

@ -36,6 +36,7 @@ import { LibraryMenu } from "./LibraryMenu";
import "./LayerUI.scss"; import "./LayerUI.scss";
import "./Toolbar.scss"; import "./Toolbar.scss";
import { PenModeButton } from "./PenModeButton";
interface LayerUIProps { interface LayerUIProps {
actionManager: ActionManager; actionManager: ActionManager;
@ -46,6 +47,7 @@ interface LayerUIProps {
elements: readonly NonDeletedExcalidrawElement[]; elements: readonly NonDeletedExcalidrawElement[];
onCollabButtonClick?: () => void; onCollabButtonClick?: () => void;
onLockToggle: () => void; onLockToggle: () => void;
onPenModeToggle: () => void;
onInsertElements: (elements: readonly NonDeletedExcalidrawElement[]) => void; onInsertElements: (elements: readonly NonDeletedExcalidrawElement[]) => void;
zenModeEnabled: boolean; zenModeEnabled: boolean;
showExitZenModeBtn: boolean; showExitZenModeBtn: boolean;
@ -76,6 +78,7 @@ const LayerUI = ({
elements, elements,
onCollabButtonClick, onCollabButtonClick,
onLockToggle, onLockToggle,
onPenModeToggle,
onInsertElements, onInsertElements,
zenModeEnabled, zenModeEnabled,
showExitZenModeBtn, showExitZenModeBtn,
@ -313,6 +316,13 @@ const LayerUI = ({
"zen-mode": zenModeEnabled, "zen-mode": zenModeEnabled,
})} })}
> >
<PenModeButton
zenModeEnabled={zenModeEnabled}
checked={appState.penMode}
onChange={onPenModeToggle}
title={t("toolBar.penMode")}
penDetected={appState.penDetected}
/>
<LockButton <LockButton
zenModeEnabled={zenModeEnabled} zenModeEnabled={zenModeEnabled}
checked={appState.elementLocked} checked={appState.elementLocked}
@ -498,6 +508,7 @@ const LayerUI = ({
setAppState={setAppState} setAppState={setAppState}
onCollabButtonClick={onCollabButtonClick} onCollabButtonClick={onCollabButtonClick}
onLockToggle={onLockToggle} onLockToggle={onLockToggle}
onPenModeToggle={onPenModeToggle}
canvas={canvas} canvas={canvas}
isCollaborating={isCollaborating} isCollaborating={isCollaborating}
renderCustomFooter={renderCustomFooter} renderCustomFooter={renderCustomFooter}

@ -17,6 +17,7 @@ import { LockButton } from "./LockButton";
import { UserList } from "./UserList"; import { UserList } from "./UserList";
import { BackgroundPickerAndDarkModeToggle } from "./BackgroundPickerAndDarkModeToggle"; import { BackgroundPickerAndDarkModeToggle } from "./BackgroundPickerAndDarkModeToggle";
import { LibraryButton } from "./LibraryButton"; import { LibraryButton } from "./LibraryButton";
import { PenModeButton } from "./PenModeButton";
type MobileMenuProps = { type MobileMenuProps = {
appState: AppState; appState: AppState;
@ -28,6 +29,7 @@ type MobileMenuProps = {
libraryMenu: JSX.Element | null; libraryMenu: JSX.Element | null;
onCollabButtonClick?: () => void; onCollabButtonClick?: () => void;
onLockToggle: () => void; onLockToggle: () => void;
onPenModeToggle: () => void;
canvas: HTMLCanvasElement | null; canvas: HTMLCanvasElement | null;
isCollaborating: boolean; isCollaborating: boolean;
renderCustomFooter?: (isMobile: boolean, appState: AppState) => JSX.Element; renderCustomFooter?: (isMobile: boolean, appState: AppState) => JSX.Element;
@ -50,6 +52,7 @@ export const MobileMenu = ({
setAppState, setAppState,
onCollabButtonClick, onCollabButtonClick,
onLockToggle, onLockToggle,
onPenModeToggle,
canvas, canvas,
isCollaborating, isCollaborating,
renderCustomFooter, renderCustomFooter,
@ -92,6 +95,13 @@ export const MobileMenu = ({
setAppState={setAppState} setAppState={setAppState}
isMobile isMobile
/> />
<PenModeButton
checked={appState.penMode}
onChange={onPenModeToggle}
title={t("toolBar.penMode")}
isMobile
penDetected={appState.penDetected}
/>
</Stack.Row> </Stack.Row>
{libraryMenu} {libraryMenu}
</Stack.Col> </Stack.Col>

@ -0,0 +1,91 @@
import "./ToolIcon.scss";
import clsx from "clsx";
import { ToolButtonSize } from "./ToolButton";
type PenModeIconProps = {
title?: string;
name?: string;
checked: boolean;
onChange?(): void;
zenModeEnabled?: boolean;
isMobile?: boolean;
penDetected: boolean;
};
const DEFAULT_SIZE: ToolButtonSize = "medium";
const ICONS = {
CHECKED: (
<svg
width="205"
height="205"
viewBox="0 0 205 205"
xmlns="http://www.w3.org/2000/svg"
>
<path d="m35 195-25-29.17V50h50v115l-25 30" />
<path d="M10 40V10h50v30H10" />
<path d="M125 145h70v50h-70" />
<path d="M190 145v-30l-10-20h-40l-10 20v30h15v-30l5-5h20l5 5v30h15" />
</svg>
),
UNCHECKED: (
<svg
width="205"
height="205"
viewBox="0 0 205 205"
xmlns="http://www.w3.org/2000/svg"
className="unlocked-icon rtl-mirror"
>
<path d="m35 195-25-29.17V50h50v115l-25 30" />
<path d="M10 40V10h50v30H10" />
<path d="M125 145h70v50h-70" />
<path d="M145 145v-30l-10-20H95l-10 20v30h15v-30l5-5h20l5 5v30h15" />
</svg>
),
};
export const PenModeButton = (props: PenModeIconProps) => {
if (!props.penDetected) {
if (props.isMobile) {
return null;
}
return (
<label
className={clsx(
"ToolIcon ToolIcon__penMode ToolIcon_type_floating",
`ToolIcon_size_${DEFAULT_SIZE}`,
{
"is-mobile": props.isMobile,
},
)}
>
<div className="ToolIcon__icon ToolIcon__hidden" />
</label>
);
}
return (
<label
className={clsx(
"ToolIcon ToolIcon__penMode ToolIcon_type_floating",
`ToolIcon_size_${DEFAULT_SIZE}`,
{
"is-mobile": props.isMobile,
},
)}
title={`${props.title}`}
>
<input
className="ToolIcon_type_checkbox"
type="checkbox"
name={props.name}
onChange={props.onChange}
checked={props.checked}
aria-label={props.title}
/>
<div className="ToolIcon__icon">
{props.checked ? ICONS.CHECKED : ICONS.UNCHECKED}
</div>
</label>
);
};

@ -219,6 +219,10 @@
margin-inline-end: 0; margin-inline-end: 0;
top: 60px; top: 60px;
} }
.ToolIcon.ToolIcon__penMode {
margin-inline-end: 0;
top: 140px;
}
} }
.unlocked-icon { .unlocked-icon {

@ -46,6 +46,10 @@
} }
} }
.ToolIcon__hidden {
box-shadow: none !important;
}
.ToolIcon.ToolIcon__lock { .ToolIcon.ToolIcon__lock {
margin-inline-end: var(--space-factor); margin-inline-end: var(--space-factor);
&.ToolIcon_type_floating { &.ToolIcon_type_floating {

@ -187,7 +187,8 @@
"freedraw": "Draw", "freedraw": "Draw",
"text": "Text", "text": "Text",
"library": "Library", "library": "Library",
"lock": "Keep selected tool active after drawing" "lock": "Keep selected tool active after drawing",
"penMode": "Prevent pinch-zoom and accept freedraw input only from pen"
}, },
"headings": { "headings": {
"canvasActions": "Canvas actions", "canvasActions": "Canvas actions",

@ -49,6 +49,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -215,6 +217,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -532,6 +536,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -849,6 +855,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -1015,6 +1023,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -1215,6 +1225,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -1470,6 +1482,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id1": true, "id1": true,
@ -1805,6 +1819,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -2556,6 +2572,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -2873,6 +2891,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -3190,6 +3210,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id1": true, "id1": true,
@ -3583,6 +3605,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -3844,6 +3868,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -4182,6 +4208,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -4281,6 +4309,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -4358,6 +4388,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,

@ -49,6 +49,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -527,6 +529,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -1011,6 +1015,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -1820,6 +1826,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -2028,6 +2036,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -2503,6 +2513,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -2762,6 +2774,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -2928,6 +2942,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id2": true, "id2": true,
@ -3386,6 +3402,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -3628,6 +3646,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -3836,6 +3856,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -4086,6 +4108,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id1": true, "id1": true,
@ -4344,6 +4368,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id2": true, "id2": true,
@ -4739,6 +4765,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -5042,6 +5070,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -5322,6 +5352,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -5534,6 +5566,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -5700,6 +5734,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -6170,6 +6206,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -6497,6 +6535,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -8615,6 +8655,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -8988,6 +9030,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -9247,6 +9291,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -9469,6 +9515,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -9756,6 +9804,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -9922,6 +9972,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -10088,6 +10140,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -10254,6 +10308,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -10450,6 +10506,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -10646,6 +10704,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -10860,6 +10920,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -11056,6 +11118,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -11222,6 +11286,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -11388,6 +11454,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -11584,6 +11652,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -11750,6 +11820,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -11964,6 +12036,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -12709,6 +12783,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -12968,6 +13044,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -13069,6 +13147,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -13168,6 +13248,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -13337,6 +13419,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -13667,6 +13751,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -13871,6 +13957,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -14728,6 +14816,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -14827,6 +14917,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id0": true, "id0": true,
@ -15615,6 +15707,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id1": true, "id1": true,
@ -16033,6 +16127,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object { "previousSelectedElementIds": Object {
"id1": true, "id1": true,
@ -16313,6 +16409,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -16414,6 +16512,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -16927,6 +17027,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,
@ -17026,6 +17128,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,

@ -47,6 +47,8 @@ Object {
"data": null, "data": null,
"shown": false, "shown": false,
}, },
"penDetected": false,
"penMode": false,
"pendingImageElement": null, "pendingImageElement": null,
"previousSelectedElementIds": Object {}, "previousSelectedElementIds": Object {},
"resizingElement": null, "resizingElement": null,

@ -79,6 +79,8 @@ export type AppState = {
editingLinearElement: LinearElementEditor | null; editingLinearElement: LinearElementEditor | null;
elementType: typeof SHAPES[number]["value"]; elementType: typeof SHAPES[number]["value"];
elementLocked: boolean; elementLocked: boolean;
penMode: boolean;
penDetected: boolean;
exportBackground: boolean; exportBackground: boolean;
exportEmbedScene: boolean; exportEmbedScene: boolean;
exportWithDarkMode: boolean; exportWithDarkMode: boolean;