ソースを参照

Double finger zoom should not select things (#1333)

Steven Nguyen 5 年 前
コミット
fd75b88bd3

+ 1 - 0
src/appState.ts

@@ -48,6 +48,7 @@ export const getDefaultAppState = (): AppState => {
     openMenu: null,
     lastPointerDownWith: "mouse",
     selectedElementIds: {},
+    previousSelectedElementIds: {},
     collaborators: new Map(),
     shouldCacheIgnoreZoom: false,
     showShortcutsDialog: false,

+ 50 - 0
src/components/App.tsx

@@ -675,6 +675,22 @@ class App extends React.Component<any, AppState> {
       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<any, AppState> {
 
   private onGestureStart = withBatchedUpdates((event: GestureEvent) => {
     event.preventDefault();
+    this.setState({
+      selectedElementIds: {},
+    });
     gesture.initialScale = this.state.zoom;
   });
 
@@ -1288,6 +1307,11 @@ class App extends React.Component<any, AppState> {
 
   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<any, AppState> {
                 ? 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<any, AppState> {
             hitElementWasAddedToSelection = true;
           }
         }
+
+        const { selectedElementIds } = this.state;
+        this.setState({
+          previousSelectedElementIds: selectedElementIds,
+        });
       }
     } else {
       this.setState({
@@ -2746,9 +2780,11 @@ class App extends React.Component<any, AppState> {
         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<any, AppState> {
   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<any, AppState> {
         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;
     }

+ 1 - 0
src/constants.ts

@@ -43,6 +43,7 @@ export enum EVENT {
   STATE_CHANGE = "statechange",
   WHEEL = "wheel",
   TOUCH_START = "touchstart",
+  TOUCH_END = "touchend",
 }
 
 export const ENV = {

+ 77 - 0
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,

+ 1 - 0
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,
     {