From 238ede74f88a3bbc7a8b0be7494995c204b9459a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= Date: Mon, 3 Jun 2024 14:45:01 +0200 Subject: [PATCH 01/10] Refactor tracker --- src/web/detectors/RotationGestureDetector.ts | 14 +- src/web/detectors/ScaleGestureDetector.ts | 11 +- src/web/handlers/GestureHandler.ts | 53 +++---- src/web/handlers/NativeViewGestureHandler.ts | 10 +- src/web/handlers/PanGestureHandler.ts | 47 +++--- src/web/handlers/TapGestureHandler.ts | 30 ++-- src/web/tools/GestureHandlerOrchestrator.ts | 8 +- src/web/tools/PointerTracker.ts | 143 ++++++++----------- src/web/tools/Vector.ts | 6 +- 9 files changed, 153 insertions(+), 169 deletions(-) diff --git a/src/web/detectors/RotationGestureDetector.ts b/src/web/detectors/RotationGestureDetector.ts index 482b7a7adc..fdf3ddf5b2 100644 --- a/src/web/detectors/RotationGestureDetector.ts +++ b/src/web/detectors/RotationGestureDetector.ts @@ -39,16 +39,14 @@ export default class RotationGestureDetector const [firstPointerID, secondPointerID] = this.keyPointers; - const firstPointerX: number = tracker.getLastX(firstPointerID); - const firstPointerY: number = tracker.getLastY(firstPointerID); - const secondPointerX: number = tracker.getLastX(secondPointerID); - const secondPointerY: number = tracker.getLastY(secondPointerID); + const firstPointerCoords = tracker.getLastAbsoluteCoords(firstPointerID); + const secondPointerCoords = tracker.getLastAbsoluteCoords(secondPointerID); - const vectorX: number = secondPointerX - firstPointerX; - const vectorY: number = secondPointerY - firstPointerY; + const vectorX: number = secondPointerCoords.x - firstPointerCoords.x; + const vectorY: number = secondPointerCoords.y - firstPointerCoords.y; - this.anchorX = (firstPointerX + secondPointerX) / 2; - this.anchorY = (firstPointerY + secondPointerY) / 2; + this.anchorX = (firstPointerCoords.x + secondPointerCoords.x) / 2; + this.anchorY = (firstPointerCoords.y + secondPointerCoords.y) / 2; //Angle diff should be positive when rotating in clockwise direction const angle: number = -Math.atan2(vectorY, vectorX); diff --git a/src/web/detectors/ScaleGestureDetector.ts b/src/web/detectors/ScaleGestureDetector.ts index c338eb59fe..40ae62f8ad 100644 --- a/src/web/detectors/ScaleGestureDetector.ts +++ b/src/web/detectors/ScaleGestureDetector.ts @@ -76,11 +76,10 @@ export default class ScaleGestureDetector implements ScaleGestureListener { const div: number = pointerUp ? numOfPointers - 1 : numOfPointers; - const sumX = tracker.getSumX(ignoredPointer); - const sumY = tracker.getSumY(ignoredPointer); + const { totalX, totalY } = tracker.getAbsoluteCoordsSum(); - const focusX = sumX / div; - const focusY = sumY / div; + const focusX = totalX / div; + const focusY = totalY / div; //Determine average deviation from focal point @@ -92,8 +91,8 @@ export default class ScaleGestureDetector implements ScaleGestureListener { return; } - devSumX += Math.abs(value.lastX - focusX); - devSumY += Math.abs(value.lastY - focusY); + devSumX += Math.abs(value.abosoluteCoords.x - focusX); + devSumY += Math.abs(value.abosoluteCoords.y - focusY); }); const devX: number = devSumX / div; diff --git a/src/web/handlers/GestureHandler.ts b/src/web/handlers/GestureHandler.ts index fde4abc866..d235fe0756 100644 --- a/src/web/handlers/GestureHandler.ts +++ b/src/web/handlers/GestureHandler.ts @@ -405,10 +405,9 @@ export default abstract class GestureHandler implements IGestureHandler { nativeEvent: { numberOfPointers: this.tracker.getTrackedPointersCount(), state: newState, - pointerInside: this.delegate.isPointerInBounds({ - x: this.tracker.getLastAvgX(), - y: this.tracker.getLastAvgY(), - }), + pointerInside: this.delegate.isPointerInBounds( + this.tracker.getAbsoluteCoordsAverage() + ), ...this.transformNativeEvent(), handlerTag: this.handlerTag, target: this.viewRef, @@ -442,10 +441,10 @@ export default abstract class GestureHandler implements IGestureHandler { all.push({ id: id, - x: element.lastX - rect.pageX, - y: element.lastY - rect.pageY, - absoluteX: element.lastX, - absoluteY: element.lastY, + x: element.abosoluteCoords.x - rect.pageX, + y: element.abosoluteCoords.y - rect.pageY, + absoluteX: element.abosoluteCoords.x, + absoluteY: element.abosoluteCoords.y, }); }); @@ -465,10 +464,10 @@ export default abstract class GestureHandler implements IGestureHandler { changed.push({ id: id, - x: element.lastX - rect.pageX, - y: element.lastY - rect.pageY, - absoluteX: element.lastX, - absoluteY: element.lastY, + x: element.abosoluteCoords.x - rect.pageX, + y: element.abosoluteCoords.y - rect.pageY, + absoluteX: element.abosoluteCoords.x, + absoluteY: element.abosoluteCoords.y, }); }); } @@ -534,18 +533,18 @@ export default abstract class GestureHandler implements IGestureHandler { all.push({ id: id, - x: element.lastX - rect.pageX, - y: element.lastY - rect.pageY, - absoluteX: element.lastX, - absoluteY: element.lastY, + x: element.abosoluteCoords.x - rect.pageX, + y: element.abosoluteCoords.y - rect.pageY, + absoluteX: element.abosoluteCoords.x, + absoluteY: element.abosoluteCoords.y, }); changed.push({ id: id, - x: element.lastX - rect.pageX, - y: element.lastY - rect.pageY, - absoluteX: element.lastX, - absoluteY: element.lastY, + x: element.abosoluteCoords.x - rect.pageX, + y: element.abosoluteCoords.y - rect.pageY, + absoluteX: element.abosoluteCoords.x, + absoluteY: element.abosoluteCoords.y, }); }); @@ -570,12 +569,13 @@ export default abstract class GestureHandler implements IGestureHandler { protected transformNativeEvent(): Record { // those properties are shared by most handlers and if not this method will be overriden const rect = this.delegate.measureView(); + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); return { - x: this.tracker.getLastAvgX() - rect.pageX, - y: this.tracker.getLastAvgY() - rect.pageY, - absoluteX: this.tracker.getLastAvgX(), - absoluteY: this.tracker.getLastAvgY(), + x: lastCoords.x - rect.pageX, + y: lastCoords.y - rect.pageY, + absoluteX: lastCoords.x, + absoluteY: lastCoords.y, }; } @@ -720,8 +720,9 @@ export default abstract class GestureHandler implements IGestureHandler { } const rect = this.delegate.measureView(); - const offsetX: number = this.tracker.getLastX() - rect.pageX; - const offsetY: number = this.tracker.getLastY() - rect.pageY; + const { x, y } = this.tracker.getLastAbsoluteCoords(); + const offsetX: number = x - rect.pageX; + const offsetY: number = y - rect.pageY; if ( offsetX >= left && diff --git a/src/web/handlers/NativeViewGestureHandler.ts b/src/web/handlers/NativeViewGestureHandler.ts index df6766ad17..5c78de745c 100644 --- a/src/web/handlers/NativeViewGestureHandler.ts +++ b/src/web/handlers/NativeViewGestureHandler.ts @@ -64,8 +64,9 @@ export default class NativeViewGestureHandler extends GestureHandler { } private newPointerAction(): void { - this.startX = this.tracker.getLastAvgX(); - this.startY = this.tracker.getLastAvgY(); + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); + this.startX = lastCoords.x; + this.startY = lastCoords.y; if (this.currentState !== State.UNDETERMINED) { return; @@ -80,8 +81,9 @@ export default class NativeViewGestureHandler extends GestureHandler { protected onPointerMove(event: AdaptedEvent): void { this.tracker.track(event); - const dx = this.startX - this.tracker.getLastAvgX(); - const dy = this.startY - this.tracker.getLastAvgY(); + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); + const dx = this.startX - lastCoords.x; + const dy = this.startY - lastCoords.y; const distSq = dx * dx + dy * dy; if (distSq >= this.minDistSq) { diff --git a/src/web/handlers/PanGestureHandler.ts b/src/web/handlers/PanGestureHandler.ts index 215c138816..f6d5061355 100644 --- a/src/web/handlers/PanGestureHandler.ts +++ b/src/web/handlers/PanGestureHandler.ts @@ -219,8 +219,9 @@ export default class PanGestureHandler extends GestureHandler { this.tracker.addToTracker(event); super.onPointerDown(event); - this.lastX = this.tracker.getLastAvgX(); - this.lastY = this.tracker.getLastAvgY(); + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); + this.lastX = lastCoords.x; + this.lastY = lastCoords.y; this.startX = this.lastX; this.startY = this.lastY; @@ -239,8 +240,9 @@ export default class PanGestureHandler extends GestureHandler { this.offsetX += this.lastX - this.startX; this.offsetY += this.lastY - this.startY; - this.lastX = this.tracker.getLastAvgX(); - this.lastY = this.tracker.getLastAvgY(); + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); + this.lastX = lastCoords.x; + this.lastY = lastCoords.y; this.startX = this.lastX; this.startY = this.lastY; @@ -259,8 +261,9 @@ export default class PanGestureHandler extends GestureHandler { protected onPointerUp(event: AdaptedEvent): void { super.onPointerUp(event); if (this.currentState === State.ACTIVE) { - this.lastX = this.tracker.getLastAvgX(); - this.lastY = this.tracker.getLastAvgY(); + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); + this.lastX = lastCoords.x; + this.lastY = lastCoords.y; } this.tracker.removeFromTracker(event.pointerId); @@ -280,8 +283,9 @@ export default class PanGestureHandler extends GestureHandler { this.offsetX += this.lastX - this.startX; this.offsetY += this.lastY - this.startY; - this.lastX = this.tracker.getLastAvgX(); - this.lastY = this.tracker.getLastAvgY(); + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); + this.lastX = lastCoords.x; + this.lastY = lastCoords.y; this.startX = this.lastX; this.startY = this.lastY; @@ -299,10 +303,13 @@ export default class PanGestureHandler extends GestureHandler { protected onPointerMove(event: AdaptedEvent): void { this.tracker.track(event); - this.lastX = this.tracker.getLastAvgX(); - this.lastY = this.tracker.getLastAvgY(); - this.velocityX = this.tracker.getVelocityX(event.pointerId); - this.velocityY = this.tracker.getVelocityY(event.pointerId); + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); + this.lastX = lastCoords.x; + this.lastY = lastCoords.y; + + const velocity = this.tracker.getVelocity(event.pointerId); + this.velocityX = velocity.x; + this.velocityY = velocity.y; this.checkBegan(); @@ -316,10 +323,13 @@ export default class PanGestureHandler extends GestureHandler { this.tracker.track(event); - this.lastX = this.tracker.getLastAvgX(); - this.lastY = this.tracker.getLastAvgY(); - this.velocityX = this.tracker.getVelocityX(event.pointerId); - this.velocityY = this.tracker.getVelocityY(event.pointerId); + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); + this.lastX = lastCoords.x; + this.lastY = lastCoords.y; + + const velocity = this.tracker.getVelocity(event.pointerId); + this.velocityX = velocity.x; + this.velocityY = velocity.y; this.checkBegan(); @@ -453,8 +463,9 @@ export default class PanGestureHandler extends GestureHandler { }, this.activateAfterLongPress); } } else { - this.velocityX = this.tracker.getVelocityX(event.pointerId); - this.velocityY = this.tracker.getVelocityY(event.pointerId); + const velocity = this.tracker.getVelocity(event.pointerId); + this.velocityX = velocity.x; + this.velocityY = velocity.y; } } diff --git a/src/web/handlers/TapGestureHandler.ts b/src/web/handlers/TapGestureHandler.ts index 12fd85e6c3..992d49df1c 100644 --- a/src/web/handlers/TapGestureHandler.ts +++ b/src/web/handlers/TapGestureHandler.ts @@ -133,19 +133,22 @@ export default class TapGestureHandler extends GestureHandler { this.offsetX += this.lastX - this.startX; this.offsetY += this.lastY - this.startY; - this.lastX = this.tracker.getLastAvgX(); - this.lastY = this.tracker.getLastAvgY(); + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); + this.lastX = lastCoords.x; + this.lastY = lastCoords.y; - this.startX = this.tracker.getLastAvgX(); - this.startY = this.tracker.getLastAvgY(); + this.startX = lastCoords.x; + this.startY = lastCoords.y; this.updateState(event); } protected onPointerUp(event: AdaptedEvent): void { super.onPointerUp(event); - this.lastX = this.tracker.getLastAvgX(); - this.lastY = this.tracker.getLastAvgY(); + + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); + this.lastX = lastCoords.x; + this.lastY = lastCoords.y; this.tracker.removeFromTracker(event.pointerId); @@ -159,8 +162,9 @@ export default class TapGestureHandler extends GestureHandler { this.offsetX += this.lastX - this.startX; this.offsetY += this.lastY = this.startY; - this.lastX = this.tracker.getLastAvgX(); - this.lastY = this.tracker.getLastAvgY(); + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); + this.lastX = lastCoords.x; + this.lastY = lastCoords.y; this.startX = this.lastX; this.startY = this.lastY; @@ -172,8 +176,9 @@ export default class TapGestureHandler extends GestureHandler { this.trySettingPosition(event); this.tracker.track(event); - this.lastX = this.tracker.getLastAvgX(); - this.lastY = this.tracker.getLastAvgY(); + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); + this.lastX = lastCoords.x; + this.lastY = lastCoords.y; this.updateState(event); @@ -184,8 +189,9 @@ export default class TapGestureHandler extends GestureHandler { this.trySettingPosition(event); this.tracker.track(event); - this.lastX = this.tracker.getLastAvgX(); - this.lastY = this.tracker.getLastAvgY(); + const lastCoords = this.tracker.getAbsoluteCoordsAverage(); + this.lastX = lastCoords.x; + this.lastY = lastCoords.y; this.updateState(event); diff --git a/src/web/tools/GestureHandlerOrchestrator.ts b/src/web/tools/GestureHandlerOrchestrator.ts index b27bae97d7..95531c796a 100644 --- a/src/web/tools/GestureHandlerOrchestrator.ts +++ b/src/web/tools/GestureHandlerOrchestrator.ts @@ -335,13 +335,7 @@ export default class GestureHandlerOrchestrator { // TODO: Find better way to handle that issue, for example by activation order and handler cancelling const isPointerWithinBothBounds = (pointer: number) => { - const handlerX: number = handler.getTracker().getLastX(pointer); - const handlerY: number = handler.getTracker().getLastY(pointer); - - const point = { - x: handlerX, - y: handlerY, - }; + const point = handler.getTracker().getLastAbsoluteCoords(pointer); return ( handler.getDelegate().isPointerInBounds(point) && diff --git a/src/web/tools/PointerTracker.ts b/src/web/tools/PointerTracker.ts index bfe49bfc8a..affb7f144d 100644 --- a/src/web/tools/PointerTracker.ts +++ b/src/web/tools/PointerTracker.ts @@ -1,12 +1,10 @@ -import { AdaptedEvent } from '../interfaces'; +import { AdaptedEvent, Point } from '../interfaces'; import VelocityTracker from './VelocityTracker'; export interface TrackerElement { - lastX: number; - lastY: number; - - timeStamp: number; - + abosoluteCoords: Point; + viewRelativeCoords: Point; + timestamp: number; velocityX: number; velocityY: number; } @@ -42,9 +40,15 @@ export default class PointerTracker { this.lastMovedPointerId = event.pointerId; const newElement: TrackerElement = { - lastX: event.x, - lastY: event.y, - timeStamp: event.time, + abosoluteCoords: { + x: event.x, + y: event.y, + }, + viewRelativeCoords: { + x: event.offsetX, + y: event.offsetY, + }, + timestamp: event.time, velocityX: 0, velocityY: 0, }; @@ -52,10 +56,7 @@ export default class PointerTracker { this.trackedPointers.set(event.pointerId, newElement); this.mapTouchEventId(event.pointerId); - this.cachedAverages = { - x: this.getLastAvgX(), - y: this.getLastAvgY(), - }; + this.cachedAverages = this.getAbsoluteCoordsAverage(); } public removeFromTracker(pointerId: number): void { @@ -80,18 +81,19 @@ export default class PointerTracker { element.velocityX = velocityX; element.velocityY = velocityY; - element.lastX = event.x; - element.lastY = event.y; + element.abosoluteCoords = { + x: event.x, + y: event.y, + }; + + element.viewRelativeCoords = { + x: event.offsetX, + y: event.offsetY, + }; this.trackedPointers.set(event.pointerId, element); - const avgX: number = this.getLastAvgX(); - const avgY: number = this.getLastAvgY(); - - this.cachedAverages = { - x: avgX, - y: avgY, - }; + this.cachedAverages = this.getAbsoluteCoordsAverage(); } //Mapping TouchEvents ID @@ -121,52 +123,26 @@ export default class PointerTracker { return NaN; } - public getVelocityX(pointerId: number): number { - return this.trackedPointers.get(pointerId)?.velocityX as number; - } - public getVelocityY(pointerId: number): number { - return this.trackedPointers.get(pointerId)?.velocityY as number; - } - - /** - * Returns X coordinate of last moved pointer - */ - public getLastX(): number; - - /** - * - * @param pointerId - * Returns X coordinate of given pointer - */ - // eslint-disable-next-line @typescript-eslint/unified-signatures - public getLastX(pointerId: number): number; - - public getLastX(pointerId?: number): number { - if (pointerId !== undefined) { - return this.trackedPointers.get(pointerId)?.lastX as number; - } else { - return this.trackedPointers.get(this.lastMovedPointerId)?.lastX as number; - } + public getVelocity(pointerId: number) { + return { + x: this.trackedPointers.get(pointerId)?.velocityX as number, + y: this.trackedPointers.get(pointerId)?.velocityY as number, + }; } - /** - * Returns Y coordinate of last moved pointer - */ - public getLastY(): number; - - /** - * - * @param pointerId - * Returns Y coordinate of given pointer - */ - // eslint-disable-next-line @typescript-eslint/unified-signatures - public getLastY(pointerId: number): number; - - public getLastY(pointerId?: number): number { + public getLastAbsoluteCoords(pointerId?: number) { if (pointerId !== undefined) { - return this.trackedPointers.get(pointerId)?.lastY as number; + return { + x: this.trackedPointers.get(pointerId)?.abosoluteCoords.x as number, + y: this.trackedPointers.get(pointerId)?.abosoluteCoords.y as number, + }; } else { - return this.trackedPointers.get(this.lastMovedPointerId)?.lastY as number; + return { + x: this.trackedPointers.get(this.lastMovedPointerId)?.abosoluteCoords + .x as number, + y: this.trackedPointers.get(this.lastMovedPointerId)?.abosoluteCoords + .y as number, + }; } } @@ -174,35 +150,34 @@ export default class PointerTracker { // This may happen when pointers have already been removed from tracker (i.e. pointerup event). // In situation when NaN would be sent as a response, we return cached value. // That prevents handlers from crashing - public getLastAvgX(): number { - const avgX: number = this.getSumX() / this.trackedPointers.size; - return isNaN(avgX) ? this.cachedAverages.x : avgX; - } - public getLastAvgY(): number { - const avgY: number = this.getSumY() / this.trackedPointers.size; - return isNaN(avgY) ? this.cachedAverages.y : avgY; - } - public getSumX(ignoredPointer?: number): number { - let sumX = 0; + public getAbsoluteCoordsAverage() { + const { totalX, totalY } = this.getAbsoluteCoordsSum(); - this.trackedPointers.forEach((value, key) => { - if (key !== ignoredPointer) { - sumX += value.lastX; - } - }); + const avgX = totalX / this.trackedPointers.size; + const avgY = totalY / this.trackedPointers.size; - return sumX; + const averages = { + x: isNaN(avgX) ? this.cachedAverages.x : avgX, + y: isNaN(avgY) ? this.cachedAverages.y : avgY, + }; + + return averages; } - public getSumY(ignoredPointer?: number): number { - let sumY = 0; + + public getAbsoluteCoordsSum(ignoredPointer?: number) { + const sum = { + totalX: 0, + totalY: 0, + }; this.trackedPointers.forEach((value, key) => { if (key !== ignoredPointer) { - sumY += value.lastY; + sum.totalX += value.abosoluteCoords.x; + sum.totalY += value.abosoluteCoords.y; } }); - return sumY; + return sum; } public getTrackedPointersCount(): number { return this.trackedPointers.size; diff --git a/src/web/tools/Vector.ts b/src/web/tools/Vector.ts index cec7272e70..79967ea03e 100644 --- a/src/web/tools/Vector.ts +++ b/src/web/tools/Vector.ts @@ -25,10 +25,8 @@ export default class Vector { } static fromVelocity(tracker: PointerTracker, pointerId: number) { - return new Vector( - tracker.getVelocityX(pointerId), - tracker.getVelocityY(pointerId) - ); + const velocity = tracker.getVelocity(pointerId); + return new Vector(velocity.x, velocity.y); } get magnitude() { From bfa63b3658f45c4a44765aa9fc810b16708bcd6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= Date: Mon, 3 Jun 2024 14:56:40 +0200 Subject: [PATCH 02/10] Add view relative methods --- src/web/detectors/ScaleGestureDetector.ts | 6 +- src/web/tools/PointerTracker.ts | 67 ++++++++++++++--------- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/web/detectors/ScaleGestureDetector.ts b/src/web/detectors/ScaleGestureDetector.ts index 40ae62f8ad..47efb6a026 100644 --- a/src/web/detectors/ScaleGestureDetector.ts +++ b/src/web/detectors/ScaleGestureDetector.ts @@ -76,10 +76,10 @@ export default class ScaleGestureDetector implements ScaleGestureListener { const div: number = pointerUp ? numOfPointers - 1 : numOfPointers; - const { totalX, totalY } = tracker.getAbsoluteCoordsSum(); + const coordsSum = tracker.getAbsoluteCoordsSum(); - const focusX = totalX / div; - const focusY = totalY / div; + const focusX = coordsSum.x / div; + const focusY = coordsSum.y / div; //Determine average deviation from focal point diff --git a/src/web/tools/PointerTracker.ts b/src/web/tools/PointerTracker.ts index affb7f144d..e205f40667 100644 --- a/src/web/tools/PointerTracker.ts +++ b/src/web/tools/PointerTracker.ts @@ -40,14 +40,8 @@ export default class PointerTracker { this.lastMovedPointerId = event.pointerId; const newElement: TrackerElement = { - abosoluteCoords: { - x: event.x, - y: event.y, - }, - viewRelativeCoords: { - x: event.offsetX, - y: event.offsetY, - }, + abosoluteCoords: { x: event.x, y: event.y }, + viewRelativeCoords: { x: event.offsetX, y: event.offsetY }, timestamp: event.time, velocityX: 0, velocityY: 0, @@ -81,15 +75,8 @@ export default class PointerTracker { element.velocityX = velocityX; element.velocityY = velocityY; - element.abosoluteCoords = { - x: event.x, - y: event.y, - }; - - element.viewRelativeCoords = { - x: event.offsetX, - y: event.offsetY, - }; + element.abosoluteCoords = { x: event.x, y: event.y }; + element.viewRelativeCoords = { x: event.offsetX, y: event.offsetY }; this.trackedPointers.set(event.pointerId, element); @@ -146,15 +133,31 @@ export default class PointerTracker { } } + public getLastViewRelativeCoords(pointerId?: number) { + if (pointerId !== undefined) { + return { + x: this.trackedPointers.get(pointerId)?.viewRelativeCoords.x as number, + y: this.trackedPointers.get(pointerId)?.viewRelativeCoords.y as number, + }; + } else { + return { + x: this.trackedPointers.get(this.lastMovedPointerId)?.viewRelativeCoords + .x as number, + y: this.trackedPointers.get(this.lastMovedPointerId)?.viewRelativeCoords + .y as number, + }; + } + } + // Some handlers use these methods to send average values in native event. // This may happen when pointers have already been removed from tracker (i.e. pointerup event). // In situation when NaN would be sent as a response, we return cached value. // That prevents handlers from crashing public getAbsoluteCoordsAverage() { - const { totalX, totalY } = this.getAbsoluteCoordsSum(); + const coordsSum = this.getAbsoluteCoordsSum(); - const avgX = totalX / this.trackedPointers.size; - const avgY = totalY / this.trackedPointers.size; + const avgX = coordsSum.x / this.trackedPointers.size; + const avgY = coordsSum.y / this.trackedPointers.size; const averages = { x: isNaN(avgX) ? this.cachedAverages.x : avgX, @@ -165,23 +168,35 @@ export default class PointerTracker { } public getAbsoluteCoordsSum(ignoredPointer?: number) { - const sum = { - totalX: 0, - totalY: 0, - }; + const sum = { x: 0, y: 0 }; this.trackedPointers.forEach((value, key) => { if (key !== ignoredPointer) { - sum.totalX += value.abosoluteCoords.x; - sum.totalY += value.abosoluteCoords.y; + sum.x += value.abosoluteCoords.x; + sum.y += value.abosoluteCoords.y; } }); return sum; } + + public getViewRelativeCoordsSum(ignoredPointer?: number) { + const sum = { x: 0, y: 0 }; + + this.trackedPointers.forEach((value, key) => { + if (key !== ignoredPointer) { + sum.x += value.viewRelativeCoords.x; + sum.y += value.viewRelativeCoords.y; + } + }); + + return sum; + } + public getTrackedPointersCount(): number { return this.trackedPointers.size; } + public getTrackedPointersID(): number[] { const keys: number[] = []; From f9cabd8d5cd2592a1bba4adb6f62fab112803f1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= Date: Mon, 3 Jun 2024 15:03:37 +0200 Subject: [PATCH 03/10] Fix rotation --- src/web/detectors/RotationGestureDetector.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/web/detectors/RotationGestureDetector.ts b/src/web/detectors/RotationGestureDetector.ts index fdf3ddf5b2..9fcea99b98 100644 --- a/src/web/detectors/RotationGestureDetector.ts +++ b/src/web/detectors/RotationGestureDetector.ts @@ -39,8 +39,10 @@ export default class RotationGestureDetector const [firstPointerID, secondPointerID] = this.keyPointers; - const firstPointerCoords = tracker.getLastAbsoluteCoords(firstPointerID); - const secondPointerCoords = tracker.getLastAbsoluteCoords(secondPointerID); + const firstPointerCoords = + tracker.getLastViewRelativeCoords(firstPointerID); + const secondPointerCoords = + tracker.getLastViewRelativeCoords(secondPointerID); const vectorX: number = secondPointerCoords.x - firstPointerCoords.x; const vectorY: number = secondPointerCoords.y - firstPointerCoords.y; From 43ed5a939682dc1abfd7f060a766ddbcc52e03a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= Date: Mon, 3 Jun 2024 15:04:55 +0200 Subject: [PATCH 04/10] Fix comment --- src/web/detectors/RotationGestureDetector.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/detectors/RotationGestureDetector.ts b/src/web/detectors/RotationGestureDetector.ts index 9fcea99b98..1d082ab1af 100644 --- a/src/web/detectors/RotationGestureDetector.ts +++ b/src/web/detectors/RotationGestureDetector.ts @@ -50,7 +50,7 @@ export default class RotationGestureDetector this.anchorX = (firstPointerCoords.x + secondPointerCoords.x) / 2; this.anchorY = (firstPointerCoords.y + secondPointerCoords.y) / 2; - //Angle diff should be positive when rotating in clockwise direction + // Angle diff should be positive when rotating in clockwise direction const angle: number = -Math.atan2(vectorY, vectorX); this.rotation = Number.isNaN(this.previousAngle) From 7bf99f093c32481a2d32d983c42ca65fdbf79939 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= Date: Mon, 3 Jun 2024 15:06:28 +0200 Subject: [PATCH 05/10] Fix scale --- src/web/detectors/ScaleGestureDetector.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/detectors/ScaleGestureDetector.ts b/src/web/detectors/ScaleGestureDetector.ts index 47efb6a026..713c298994 100644 --- a/src/web/detectors/ScaleGestureDetector.ts +++ b/src/web/detectors/ScaleGestureDetector.ts @@ -76,7 +76,7 @@ export default class ScaleGestureDetector implements ScaleGestureListener { const div: number = pointerUp ? numOfPointers - 1 : numOfPointers; - const coordsSum = tracker.getAbsoluteCoordsSum(); + const coordsSum = tracker.getViewRelativeCoordsSum(); const focusX = coordsSum.x / div; const focusY = coordsSum.y / div; From 49eec00e8675653b3c90c3ecc7d84364791a5edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= Date: Mon, 3 Jun 2024 15:07:50 +0200 Subject: [PATCH 06/10] Fix comments --- src/web/detectors/ScaleGestureDetector.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/web/detectors/ScaleGestureDetector.ts b/src/web/detectors/ScaleGestureDetector.ts index 713c298994..43ccfb876f 100644 --- a/src/web/detectors/ScaleGestureDetector.ts +++ b/src/web/detectors/ScaleGestureDetector.ts @@ -72,8 +72,7 @@ export default class ScaleGestureDetector implements ScaleGestureListener { ? event.pointerId : undefined; - //Determine focal point - + // Determine focal point const div: number = pointerUp ? numOfPointers - 1 : numOfPointers; const coordsSum = tracker.getViewRelativeCoordsSum(); @@ -81,8 +80,7 @@ export default class ScaleGestureDetector implements ScaleGestureListener { const focusX = coordsSum.x / div; const focusY = coordsSum.y / div; - //Determine average deviation from focal point - + // Determine average deviation from focal point let devSumX = 0; let devSumY = 0; @@ -103,7 +101,7 @@ export default class ScaleGestureDetector implements ScaleGestureListener { const span = Math.hypot(spanX, spanY); - //Begin/end events + // Begin/end events const wasInProgress: boolean = this.inProgress; this.focusX = focusX; this.focusY = focusY; @@ -128,7 +126,7 @@ export default class ScaleGestureDetector implements ScaleGestureListener { this.inProgress = this.onScaleBegin(this); } - //Handle motion + // Handle motion if (action !== EventTypes.MOVE) { return true; } From 16931316223dfef48f0fbd6735dba129da3305f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= Date: Thu, 13 Jun 2024 09:47:40 +0200 Subject: [PATCH 07/10] Use right methods --- src/web/detectors/RotationGestureDetector.ts | 6 ++---- src/web/detectors/ScaleGestureDetector.ts | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/web/detectors/RotationGestureDetector.ts b/src/web/detectors/RotationGestureDetector.ts index 1d082ab1af..064ea348bb 100644 --- a/src/web/detectors/RotationGestureDetector.ts +++ b/src/web/detectors/RotationGestureDetector.ts @@ -39,10 +39,8 @@ export default class RotationGestureDetector const [firstPointerID, secondPointerID] = this.keyPointers; - const firstPointerCoords = - tracker.getLastViewRelativeCoords(firstPointerID); - const secondPointerCoords = - tracker.getLastViewRelativeCoords(secondPointerID); + const firstPointerCoords = tracker.getLastRelativeCoords(firstPointerID); + const secondPointerCoords = tracker.getLastRelativeCoords(secondPointerID); const vectorX: number = secondPointerCoords.x - firstPointerCoords.x; const vectorY: number = secondPointerCoords.y - firstPointerCoords.y; diff --git a/src/web/detectors/ScaleGestureDetector.ts b/src/web/detectors/ScaleGestureDetector.ts index 43ccfb876f..df075c23aa 100644 --- a/src/web/detectors/ScaleGestureDetector.ts +++ b/src/web/detectors/ScaleGestureDetector.ts @@ -75,7 +75,7 @@ export default class ScaleGestureDetector implements ScaleGestureListener { // Determine focal point const div: number = pointerUp ? numOfPointers - 1 : numOfPointers; - const coordsSum = tracker.getViewRelativeCoordsSum(); + const coordsSum = tracker.getRelativeCoordsSum(); const focusX = coordsSum.x / div; const focusY = coordsSum.y / div; From c259aa6598d957cdc151502659d8230520490825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= Date: Fri, 28 Jun 2024 16:21:23 +0200 Subject: [PATCH 08/10] Correctly calculate deviation --- src/web/detectors/ScaleGestureDetector.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/web/detectors/ScaleGestureDetector.ts b/src/web/detectors/ScaleGestureDetector.ts index df075c23aa..4c35deae40 100644 --- a/src/web/detectors/ScaleGestureDetector.ts +++ b/src/web/detectors/ScaleGestureDetector.ts @@ -89,8 +89,8 @@ export default class ScaleGestureDetector implements ScaleGestureListener { return; } - devSumX += Math.abs(value.abosoluteCoords.x - focusX); - devSumY += Math.abs(value.abosoluteCoords.y - focusY); + devSumX += Math.abs(value.relativeCoords.x - focusX); + devSumY += Math.abs(value.relativeCoords.y - focusY); }); const devX: number = devSumX / div; From 120f093befc5314101e7a6a0123d3f9a8a09383f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= Date: Fri, 27 Sep 2024 12:14:18 +0200 Subject: [PATCH 09/10] Switch back to offset --- src/web/tools/PointerEventManager.ts | 8 ++----- src/web/utils.ts | 36 ---------------------------- 2 files changed, 2 insertions(+), 42 deletions(-) diff --git a/src/web/tools/PointerEventManager.ts b/src/web/tools/PointerEventManager.ts index facc8be1e5..2680896f47 100644 --- a/src/web/tools/PointerEventManager.ts +++ b/src/web/tools/PointerEventManager.ts @@ -3,7 +3,6 @@ import { MouseButton } from '../../handlers/gestureHandlerCommon'; import { AdaptedEvent, EventTypes, Point } from '../interfaces'; import { PointerTypeMapping, - calculateViewScale, tryExtractStylusData, isPointerInBounds, } from '../utils'; @@ -201,14 +200,11 @@ export default class PointerEventManager extends EventManager { } protected mapEvent(event: PointerEvent, eventType: EventTypes): AdaptedEvent { - const rect = this.view.getBoundingClientRect(); - const { scaleX, scaleY } = calculateViewScale(this.view); - return { x: event.clientX, y: event.clientY, - offsetX: (event.clientX - rect.left) / scaleX, - offsetY: (event.clientY - rect.top) / scaleY, + offsetX: event.offsetX, + offsetY: event.offsetY, pointerId: event.pointerId, eventType: eventType, pointerType: diff --git a/src/web/utils.ts b/src/web/utils.ts index 2ce5354c45..08b07c1377 100644 --- a/src/web/utils.ts +++ b/src/web/utils.ts @@ -19,42 +19,6 @@ export const degToRad = (degrees: number) => (degrees * Math.PI) / 180; export const coneToDeviation = (degrees: number) => Math.cos(degToRad(degrees / 2)); -export function calculateViewScale(view: HTMLElement) { - const styles = getComputedStyle(view); - - const resultScales = { - scaleX: 1, - scaleY: 1, - }; - - // Get scales from scale property - if (styles.scale !== undefined && styles.scale !== 'none') { - const scales = styles.scale.split(' '); - - if (scales[0]) { - resultScales.scaleX = parseFloat(scales[0]); - } - - resultScales.scaleY = scales[1] - ? parseFloat(scales[1]) - : parseFloat(scales[0]); - } - - // Get scales from transform property - const matrixElements = new RegExp(/matrix\((.+)\)/).exec( - styles.transform - )?.[1]; - - if (matrixElements) { - const matrixElementsArray = matrixElements.split(', '); - - resultScales.scaleX *= parseFloat(matrixElementsArray[0]); - resultScales.scaleY *= parseFloat(matrixElementsArray[3]); - } - - return resultScales; -} - export function tryExtractStylusData( event: PointerEvent ): StylusData | undefined { From 21fcbf9602eec4fce66cedc623656b2d459a7067 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Bert?= Date: Mon, 7 Oct 2024 14:09:39 +0200 Subject: [PATCH 10/10] Almost almost --- src/web/detectors/RotationGestureDetector.ts | 27 ++++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/web/detectors/RotationGestureDetector.ts b/src/web/detectors/RotationGestureDetector.ts index 064ea348bb..155d801dae 100644 --- a/src/web/detectors/RotationGestureDetector.ts +++ b/src/web/detectors/RotationGestureDetector.ts @@ -39,14 +39,25 @@ export default class RotationGestureDetector const [firstPointerID, secondPointerID] = this.keyPointers; - const firstPointerCoords = tracker.getLastRelativeCoords(firstPointerID); - const secondPointerCoords = tracker.getLastRelativeCoords(secondPointerID); - - const vectorX: number = secondPointerCoords.x - firstPointerCoords.x; - const vectorY: number = secondPointerCoords.y - firstPointerCoords.y; - - this.anchorX = (firstPointerCoords.x + secondPointerCoords.x) / 2; - this.anchorY = (firstPointerCoords.y + secondPointerCoords.y) / 2; + const firstPointerRelativeCoords = + tracker.getLastRelativeCoords(firstPointerID); + const secondPointerRelativeCoords = + tracker.getLastRelativeCoords(secondPointerID); + + this.anchorX = + (firstPointerRelativeCoords.x + secondPointerRelativeCoords.x) / 2; + this.anchorY = + (firstPointerRelativeCoords.y + secondPointerRelativeCoords.y) / 2; + + const firstPointerAbsoluteCoords = + tracker.getLastAbsoluteCoords(firstPointerID); + const secondPointerAbsoluteCoords = + tracker.getLastAbsoluteCoords(secondPointerID); + + const vectorX: number = + secondPointerAbsoluteCoords.x - firstPointerAbsoluteCoords.x; + const vectorY: number = + secondPointerAbsoluteCoords.y - firstPointerAbsoluteCoords.y; // Angle diff should be positive when rotating in clockwise direction const angle: number = -Math.atan2(vectorY, vectorX);