From 8d8f9f23bda650f9e377a291ed5d5cbbaa8dfe2c Mon Sep 17 00:00:00 2001 From: Pete Hunt Date: Sun, 8 Mar 2020 19:25:16 -0700 Subject: [PATCH] Make gesture.pointers a Map instead of an array of pointers (#877) --- src/components/App.tsx | 39 +++++++++++++++++---------------------- src/gesture.ts | 11 ++++++----- src/types.ts | 5 ++--- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index 5ea6a0f4..c2f53f5d 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -118,7 +118,7 @@ let currentScrollBars: ScrollBars = { horizontal: null, vertical: null }; let lastPointerUp: ((event: any) => void) | null = null; const gesture: Gesture = { - pointers: [], + pointers: new Map(), lastCenter: null, initialDistance: null, initialScale: null, @@ -354,7 +354,7 @@ export class App extends React.Component { this.state.draggingElement === null ) { this.selectShapeTool(shape); - } else if (event.key === KEYS.SPACE && gesture.pointers.length === 0) { + } else if (event.key === KEYS.SPACE && gesture.pointers.size === 0) { isHoldingSpace = true; document.documentElement.style.cursor = CURSOR_TYPE.GRABBING; } @@ -465,9 +465,7 @@ export class App extends React.Component { }; removePointer = (event: React.PointerEvent) => { - gesture.pointers = gesture.pointers.filter( - pointer => pointer.id !== event.pointerId, - ); + gesture.pointers.delete(event.pointerId); }; public render() { @@ -722,23 +720,18 @@ export class App extends React.Component { private handleCanvasPointerMove = ( event: React.PointerEvent, ) => { - gesture.pointers = gesture.pointers.map(pointer => - pointer.id === event.pointerId - ? { - id: event.pointerId, - x: event.clientX, - y: event.clientY, - } - : pointer, - ); + gesture.pointers.set(event.pointerId, { + x: event.clientX, + y: event.clientY, + }); - if (gesture.pointers.length === 2) { + if (gesture.pointers.size === 2) { const center = getCenter(gesture.pointers); const deltaX = center.x - gesture.lastCenter!.x; const deltaY = center.y - gesture.lastCenter!.y; gesture.lastCenter = center; - const distance = getDistance(gesture.pointers); + const distance = getDistance(Array.from(gesture.pointers.values())); const scaleFactor = distance / gesture.initialDistance!; this.setState({ @@ -835,7 +828,7 @@ export class App extends React.Component { // pan canvas on wheel button drag or space+drag if ( - gesture.pointers.length === 0 && + gesture.pointers.size === 0 && (event.button === POINTER_BUTTON.WHEEL || (event.button === POINTER_BUTTON.MAIN && isHoldingSpace)) ) { @@ -883,15 +876,17 @@ export class App extends React.Component { return; } - gesture.pointers.push({ - id: event.pointerId, + gesture.pointers.set(event.pointerId, { x: event.clientX, y: event.clientY, }); - if (gesture.pointers.length === 2) { + + if (gesture.pointers.size === 2) { gesture.lastCenter = getCenter(gesture.pointers); gesture.initialScale = this.state.zoom; - gesture.initialDistance = getDistance(gesture.pointers); + gesture.initialDistance = getDistance( + Array.from(gesture.pointers.values()), + ); } // fixes pointermove causing selection of UI texts #32 @@ -904,7 +899,7 @@ export class App extends React.Component { } // don't select while panning - if (gesture.pointers.length > 1) { + if (gesture.pointers.size > 1) { return; } diff --git a/src/gesture.ts b/src/gesture.ts index 7b6280a2..617fa98e 100644 --- a/src/gesture.ts +++ b/src/gesture.ts @@ -1,14 +1,15 @@ -import { Pointer } from "./types"; +import { PointerCoords } from "./types"; import { normalizeScroll } from "./scene"; -export function getCenter(pointers: readonly Pointer[]) { +export function getCenter(pointers: Map) { + const allCoords = Array.from(pointers.values()); return { - x: normalizeScroll(sum(pointers, pointer => pointer.x) / pointers.length), - y: normalizeScroll(sum(pointers, pointer => pointer.y) / pointers.length), + x: normalizeScroll(sum(allCoords, coords => coords.x) / allCoords.length), + y: normalizeScroll(sum(allCoords, coords => coords.y) / allCoords.length), }; } -export function getDistance([a, b]: readonly Pointer[]) { +export function getDistance([a, b]: readonly PointerCoords[]) { return Math.hypot(a.x - b.x, a.y - b.y); } diff --git a/src/types.ts b/src/types.ts index 5f170097..9dec663d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -36,14 +36,13 @@ export type AppState = { selectedElementIds: { [id: string]: boolean }; }; -export type Pointer = Readonly<{ - id: number; +export type PointerCoords = Readonly<{ x: number; y: number; }>; export type Gesture = { - pointers: Array; + pointers: Map; lastCenter: { x: number; y: number } | null; initialDistance: number | null; initialScale: number | null;