Skip to content

Commit

Permalink
Unify scaled coordinates between web and native side. (#2943)
Browse files Browse the repository at this point in the history
## Description

On `android` and `iOS` if you scale view and get relative coords, they will act like they were not scaled at all. Let's say that we have a square with size `100x100`. If you click in the middle, `x` and `y` fields in event will both be `50`. Now, if you scale this view by 2 (i.e. new size is `200x200`) and click in the middle, you'll still get values of 50.

Web takes scale into account and on the above situation, second output would be `100`. To unify this behavior we now divide coords by scale factors.

## Test plan

Add `console.log(e.x, e.y)` in any example with scale, for example in `transformations`
  • Loading branch information
m-bert committed Jun 14, 2024
1 parent 8e20b37 commit f393b8e
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 6 deletions.
12 changes: 9 additions & 3 deletions src/web/tools/PointerEventManager.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import EventManager from './EventManager';
import { MouseButton } from '../../handlers/gestureHandlerCommon';
import { AdaptedEvent, EventTypes, Point } from '../interfaces';
import { PointerTypeMapping, isPointerInBounds } from '../utils';
import {
PointerTypeMapping,
calculateViewScale,
isPointerInBounds,
} from '../utils';
import { PointerType } from '../../PointerType';

const POINTER_CAPTURE_EXCLUDE_LIST = new Set<string>(['SELECT', 'INPUT']);
Expand Down Expand Up @@ -234,11 +238,13 @@ export default class PointerEventManager extends EventManager<HTMLElement> {
}

protected mapEvent(event: PointerEvent, eventType: EventTypes): AdaptedEvent {
const { scaleX, scaleY } = calculateViewScale(this.view);

return {
x: event.clientX,
y: event.clientY,
offsetX: event.offsetX,
offsetY: event.offsetY,
offsetX: event.offsetX / scaleX,
offsetY: event.offsetY / scaleY,
pointerId: event.pointerId,
eventType: eventType,
pointerType:
Expand Down
8 changes: 5 additions & 3 deletions src/web/tools/TouchEventManager.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AdaptedEvent, EventTypes, TouchEventType } from '../interfaces';
import EventManager from './EventManager';
import { isPointerInBounds } from '../utils';
import { calculateViewScale, isPointerInBounds } from '../utils';
import { PointerType } from '../../PointerType';

export default class TouchEventManager extends EventManager<HTMLElement> {
Expand Down Expand Up @@ -156,11 +156,13 @@ export default class TouchEventManager extends EventManager<HTMLElement> {
const clientX = event.changedTouches[index].clientX;
const clientY = event.changedTouches[index].clientY;

const { scaleX, scaleY } = calculateViewScale(this.view);

return {
x: clientX,
y: clientY,
offsetX: clientX - rect.left,
offsetY: clientY - rect.top,
offsetX: (clientX - rect.left) / scaleX,
offsetY: (clientY - rect.top) / scaleY,
pointerId: event.changedTouches[index].identifier,
eventType: eventType,
pointerType: PointerType.TOUCH,
Expand Down
34 changes: 34 additions & 0 deletions src/web/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,37 @@ 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,
};

const scales = styles.scale.split(' ');

if (scales[0] !== 'none') {
resultScales.scaleX = parseFloat(scales[0]);
}

if (scales[1]) {
resultScales.scaleY = parseFloat(scales[1]);
}

const matrixElements = new RegExp(/matrix\((.+)\)/).exec(
styles.transform
)?.[1];

if (!matrixElements) {
return resultScales;
}

const matrixElementsArray = matrixElements.split(', ');

resultScales.scaleX *= parseFloat(matrixElementsArray[0]);
resultScales.scaleY *= parseFloat(matrixElementsArray[3]);

return resultScales;
}

0 comments on commit f393b8e

Please sign in to comment.