From fd75b88bd3eac012437c8f119143f31600223a18 Mon Sep 17 00:00:00 2001 From: Steven Nguyen Date: Tue, 2 Jun 2020 18:41:40 +0200 Subject: [PATCH] Double finger zoom should not select things (#1333) --- src/appState.ts | 1 + src/components/App.tsx | 50 ++++++++++++ src/constants.ts | 1 + .../regressionTests.test.tsx.snap | 77 +++++++++++++++++++ src/types.ts | 1 + 5 files changed, 130 insertions(+) diff --git a/src/appState.ts b/src/appState.ts index d6dceb639..39b3a491b 100644 --- a/src/appState.ts +++ b/src/appState.ts @@ -48,6 +48,7 @@ export const getDefaultAppState = (): AppState => { openMenu: null, lastPointerDownWith: "mouse", selectedElementIds: {}, + previousSelectedElementIds: {}, collaborators: new Map(), shouldCacheIgnoreZoom: false, showShortcutsDialog: false, diff --git a/src/components/App.tsx b/src/components/App.tsx index 5e4892c71..6412b034d 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -675,6 +675,22 @@ class App extends React.Component { clearTimeout(tappedTwiceTimer); } event.preventDefault(); + if (event.touches.length === 2) { + this.setState({ + selectedElementIds: {}, + }); + } + }; + + private onTapEnd = (event: TouchEvent) => { + event.preventDefault(); + if (event.touches.length > 0) { + const { previousSelectedElementIds } = this.state; + this.setState({ + previousSelectedElementIds: {}, + selectedElementIds: previousSelectedElementIds, + }); + } }; private pasteFromClipboard = withBatchedUpdates( @@ -1275,6 +1291,9 @@ class App extends React.Component { private onGestureStart = withBatchedUpdates((event: GestureEvent) => { event.preventDefault(); + this.setState({ + selectedElementIds: {}, + }); gesture.initialScale = this.state.zoom; }); @@ -1288,6 +1307,11 @@ class App extends React.Component { private onGestureEnd = withBatchedUpdates((event: GestureEvent) => { event.preventDefault(); + const { previousSelectedElementIds } = this.state; + this.setState({ + previousSelectedElementIds: {}, + selectedElementIds: previousSelectedElementIds, + }); gesture.initialScale = null; }); @@ -2097,6 +2121,11 @@ class App extends React.Component { ? prevState.editingGroupId : null, })); + const { selectedElementIds } = this.state; + this.setState({ + selectedElementIds: {}, + previousSelectedElementIds: selectedElementIds, + }); } // If we click on something @@ -2138,6 +2167,11 @@ class App extends React.Component { hitElementWasAddedToSelection = true; } } + + const { selectedElementIds } = this.state; + this.setState({ + previousSelectedElementIds: selectedElementIds, + }); } } else { this.setState({ @@ -2746,9 +2780,11 @@ class App extends React.Component { passive: false, }); this.canvas.addEventListener(EVENT.TOUCH_START, this.onTapStart); + this.canvas.addEventListener(EVENT.TOUCH_END, this.onTapEnd); } else { this.canvas?.removeEventListener(EVENT.WHEEL, this.handleWheel); this.canvas?.removeEventListener(EVENT.TOUCH_START, this.onTapStart); + this.canvas?.removeEventListener(EVENT.TOUCH_END, this.onTapEnd); } }; @@ -2862,6 +2898,7 @@ class App extends React.Component { private handleWheel = withBatchedUpdates((event: WheelEvent) => { event.preventDefault(); const { deltaX, deltaY } = event; + const { selectedElementIds, previousSelectedElementIds } = this.state; // note that event.ctrlKey is necessary to handle pinch zooming if (event.metaKey || event.ctrlKey) { @@ -2872,8 +2909,21 @@ class App extends React.Component { delta = MAX_STEP; } delta *= sign; + if (Object.keys(previousSelectedElementIds).length !== 0) { + setTimeout(() => { + this.setState({ + selectedElementIds: previousSelectedElementIds, + previousSelectedElementIds: {}, + }); + }, 1000); + } this.setState(({ zoom }) => ({ zoom: getNormalizedZoom(zoom - delta / 100), + selectedElementIds: {}, + previousSelectedElementIds: + Object.keys(selectedElementIds).length !== 0 + ? selectedElementIds + : previousSelectedElementIds, })); return; } diff --git a/src/constants.ts b/src/constants.ts index b5d884d26..83499f63f 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -43,6 +43,7 @@ export enum EVENT { STATE_CHANGE = "statechange", WHEEL = "wheel", TOUCH_START = "touchstart", + TOUCH_END = "touchend", } export const ENV = { diff --git a/src/tests/__snapshots__/regressionTests.test.tsx.snap b/src/tests/__snapshots__/regressionTests.test.tsx.snap index 873b01ad2..9e29fedbf 100644 --- a/src/tests/__snapshots__/regressionTests.test.tsx.snap +++ b/src/tests/__snapshots__/regressionTests.test.tsx.snap @@ -32,6 +32,10 @@ Object { "multiElement": null, "name": "Unbenannt-201933152653", "openMenu": null, + "previousSelectedElementIds": Object { + "id0": true, + "id3": true, + }, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -425,6 +429,9 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object { + "id0": true, + }, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -628,6 +635,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -750,6 +758,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -1008,6 +1017,9 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object { + "id0": true, + }, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -1166,6 +1178,10 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object { + "id0": true, + "id1": true, + }, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -1361,6 +1377,9 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object { + "id1": true, + }, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -1563,6 +1582,9 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object { + "id2": true, + }, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -1866,6 +1888,7 @@ Object { "multiElement": null, "name": "Unbenannt-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -2257,6 +2280,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -4041,6 +4065,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -4163,6 +4188,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -4285,6 +4311,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -4407,6 +4434,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -4551,6 +4579,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -4695,6 +4724,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -4839,6 +4869,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -4983,6 +5014,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -5105,6 +5137,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -5227,6 +5260,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -5371,6 +5405,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -5493,6 +5528,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -5637,6 +5673,12 @@ Object { "multiElement": null, "name": "Unbenannt-201933152653", "openMenu": null, + "previousSelectedElementIds": Object { + "id0": true, + "id1": true, + "id2": true, + "id3": true, + }, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -6268,6 +6310,10 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object { + "id0": true, + "id3": true, + }, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -6470,6 +6516,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": -6, "scrollY": 0, @@ -6533,6 +6580,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -6594,6 +6642,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -7412,6 +7461,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -7807,6 +7857,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -8119,6 +8170,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -8352,6 +8404,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -8510,6 +8563,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -9277,6 +9331,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -9945,6 +10000,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -10518,6 +10574,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -11000,6 +11057,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -11438,6 +11496,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -11791,6 +11850,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -12063,6 +12123,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -12258,6 +12319,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -13076,6 +13138,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -13793,6 +13856,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -14413,6 +14477,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -14940,6 +15005,12 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object { + "id0": true, + "id1": true, + "id2": true, + "id3": true, + }, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -15204,6 +15275,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 60, "scrollY": 60, @@ -15265,6 +15337,7 @@ Object { "multiElement": null, "name": "Unbenannt-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -15915,6 +15988,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 11, "scrollY": -5, @@ -15978,6 +16052,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -16402,6 +16477,7 @@ Object { "multiElement": null, "name": "Unbenannt-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, @@ -16474,6 +16550,7 @@ Object { "multiElement": null, "name": "Untitled-201933152653", "openMenu": null, + "previousSelectedElementIds": Object {}, "resizingElement": null, "scrollX": 0, "scrollY": 0, diff --git a/src/types.ts b/src/types.ts index a0846f233..ecdd4a631 100644 --- a/src/types.ts +++ b/src/types.ts @@ -57,6 +57,7 @@ export type AppState = { openMenu: "canvas" | "shape" | null; lastPointerDownWith: PointerType; selectedElementIds: { [id: string]: boolean }; + previousSelectedElementIds: { [id: string]: boolean }; collaborators: Map< string, {