Make gesture.pointers a Map instead of an array of pointers (#877)
This commit is contained in:
parent
92ba401da8
commit
8d8f9f23bd
@ -118,7 +118,7 @@ let currentScrollBars: ScrollBars = { horizontal: null, vertical: null };
|
|||||||
|
|
||||||
let lastPointerUp: ((event: any) => void) | null = null;
|
let lastPointerUp: ((event: any) => void) | null = null;
|
||||||
const gesture: Gesture = {
|
const gesture: Gesture = {
|
||||||
pointers: [],
|
pointers: new Map(),
|
||||||
lastCenter: null,
|
lastCenter: null,
|
||||||
initialDistance: null,
|
initialDistance: null,
|
||||||
initialScale: null,
|
initialScale: null,
|
||||||
@ -354,7 +354,7 @@ export class App extends React.Component<any, AppState> {
|
|||||||
this.state.draggingElement === null
|
this.state.draggingElement === null
|
||||||
) {
|
) {
|
||||||
this.selectShapeTool(shape);
|
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;
|
isHoldingSpace = true;
|
||||||
document.documentElement.style.cursor = CURSOR_TYPE.GRABBING;
|
document.documentElement.style.cursor = CURSOR_TYPE.GRABBING;
|
||||||
}
|
}
|
||||||
@ -465,9 +465,7 @@ export class App extends React.Component<any, AppState> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
removePointer = (event: React.PointerEvent<HTMLElement>) => {
|
removePointer = (event: React.PointerEvent<HTMLElement>) => {
|
||||||
gesture.pointers = gesture.pointers.filter(
|
gesture.pointers.delete(event.pointerId);
|
||||||
pointer => pointer.id !== event.pointerId,
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
@ -722,23 +720,18 @@ export class App extends React.Component<any, AppState> {
|
|||||||
private handleCanvasPointerMove = (
|
private handleCanvasPointerMove = (
|
||||||
event: React.PointerEvent<HTMLCanvasElement>,
|
event: React.PointerEvent<HTMLCanvasElement>,
|
||||||
) => {
|
) => {
|
||||||
gesture.pointers = gesture.pointers.map(pointer =>
|
gesture.pointers.set(event.pointerId, {
|
||||||
pointer.id === event.pointerId
|
|
||||||
? {
|
|
||||||
id: event.pointerId,
|
|
||||||
x: event.clientX,
|
x: event.clientX,
|
||||||
y: event.clientY,
|
y: event.clientY,
|
||||||
}
|
});
|
||||||
: pointer,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (gesture.pointers.length === 2) {
|
if (gesture.pointers.size === 2) {
|
||||||
const center = getCenter(gesture.pointers);
|
const center = getCenter(gesture.pointers);
|
||||||
const deltaX = center.x - gesture.lastCenter!.x;
|
const deltaX = center.x - gesture.lastCenter!.x;
|
||||||
const deltaY = center.y - gesture.lastCenter!.y;
|
const deltaY = center.y - gesture.lastCenter!.y;
|
||||||
gesture.lastCenter = center;
|
gesture.lastCenter = center;
|
||||||
|
|
||||||
const distance = getDistance(gesture.pointers);
|
const distance = getDistance(Array.from(gesture.pointers.values()));
|
||||||
const scaleFactor = distance / gesture.initialDistance!;
|
const scaleFactor = distance / gesture.initialDistance!;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
@ -835,7 +828,7 @@ export class App extends React.Component<any, AppState> {
|
|||||||
|
|
||||||
// pan canvas on wheel button drag or space+drag
|
// pan canvas on wheel button drag or space+drag
|
||||||
if (
|
if (
|
||||||
gesture.pointers.length === 0 &&
|
gesture.pointers.size === 0 &&
|
||||||
(event.button === POINTER_BUTTON.WHEEL ||
|
(event.button === POINTER_BUTTON.WHEEL ||
|
||||||
(event.button === POINTER_BUTTON.MAIN && isHoldingSpace))
|
(event.button === POINTER_BUTTON.MAIN && isHoldingSpace))
|
||||||
) {
|
) {
|
||||||
@ -883,15 +876,17 @@ export class App extends React.Component<any, AppState> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gesture.pointers.push({
|
gesture.pointers.set(event.pointerId, {
|
||||||
id: event.pointerId,
|
|
||||||
x: event.clientX,
|
x: event.clientX,
|
||||||
y: event.clientY,
|
y: event.clientY,
|
||||||
});
|
});
|
||||||
if (gesture.pointers.length === 2) {
|
|
||||||
|
if (gesture.pointers.size === 2) {
|
||||||
gesture.lastCenter = getCenter(gesture.pointers);
|
gesture.lastCenter = getCenter(gesture.pointers);
|
||||||
gesture.initialScale = this.state.zoom;
|
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
|
// fixes pointermove causing selection of UI texts #32
|
||||||
@ -904,7 +899,7 @@ export class App extends React.Component<any, AppState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// don't select while panning
|
// don't select while panning
|
||||||
if (gesture.pointers.length > 1) {
|
if (gesture.pointers.size > 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
import { Pointer } from "./types";
|
import { PointerCoords } from "./types";
|
||||||
import { normalizeScroll } from "./scene";
|
import { normalizeScroll } from "./scene";
|
||||||
|
|
||||||
export function getCenter(pointers: readonly Pointer[]) {
|
export function getCenter(pointers: Map<number, PointerCoords>) {
|
||||||
|
const allCoords = Array.from(pointers.values());
|
||||||
return {
|
return {
|
||||||
x: normalizeScroll(sum(pointers, pointer => pointer.x) / pointers.length),
|
x: normalizeScroll(sum(allCoords, coords => coords.x) / allCoords.length),
|
||||||
y: normalizeScroll(sum(pointers, pointer => pointer.y) / pointers.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);
|
return Math.hypot(a.x - b.x, a.y - b.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,14 +36,13 @@ export type AppState = {
|
|||||||
selectedElementIds: { [id: string]: boolean };
|
selectedElementIds: { [id: string]: boolean };
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Pointer = Readonly<{
|
export type PointerCoords = Readonly<{
|
||||||
id: number;
|
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type Gesture = {
|
export type Gesture = {
|
||||||
pointers: Array<Pointer>;
|
pointers: Map<number, PointerCoords>;
|
||||||
lastCenter: { x: number; y: number } | null;
|
lastCenter: { x: number; y: number } | null;
|
||||||
initialDistance: number | null;
|
initialDistance: number | null;
|
||||||
initialScale: number | null;
|
initialScale: number | null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user