Skip to content

Commit be0e833

Browse files
committed
cursors: spell out transform-origin: 0 0 assumption
1 parent 1849b65 commit be0e833

1 file changed

Lines changed: 21 additions & 8 deletions

File tree

packages/playhtml/src/cursors/cursor-client.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -406,12 +406,23 @@ export class CursorClientAwareness {
406406
private clientToStorage(clientX: number, clientY: number): { x: number; y: number } {
407407
const m = this.getContainerMatrix();
408408
if (m) {
409-
// The container has `transform-origin: 0 0` (the only origin we
410-
// support; `getBoundingClientRect()` already reflects the post-
411-
// transform top-left). To recover container-local pre-transform
412-
// coords, subtract the rect origin and undo the matrix's scale/rotate.
413-
// The matrix's translate component is already absorbed into rect.left
414-
// / rect.top, so we apply only the linear (a, b, c, d) part.
409+
// ASSUMPTION: the container uses `transform-origin: 0 0`. Hosts
410+
// applying their own pan/zoom transform almost always do so — it's
411+
// the natural choice for a canvas where (0, 0) in content space
412+
// maps to the container's top-left. With this origin, the post-
413+
// transform top-left equals `rect.left / rect.top` directly, AND
414+
// an absolutely-positioned child rendered at (left, top) inside the
415+
// container ends up at viewport position
416+
// (rect.left + a*left + c*top, rect.top + b*left + d*top)
417+
// i.e. only the linear (a, b, c, d) part of the matrix is applied
418+
// to the child's local coordinates — the matrix's translate (e, f)
419+
// is already absorbed into rect.left / rect.top by the browser's
420+
// layout. So to invert, subtract the rect origin and undo only
421+
// the linear part. Other origins (e.g. `center`) would shift the
422+
// anchor and produce off-by-half-the-container errors; we don't
423+
// support them here. If a host needs that, they can pre-multiply
424+
// their transform with the equivalent translate to bake the origin
425+
// into (e, f) and keep `transform-origin: 0 0`.
415426
const a = m.matrix.a;
416427
const b = m.matrix.b;
417428
const c = m.matrix.c;
@@ -431,8 +442,10 @@ export class CursorClientAwareness {
431442
private storageToClient(x: number, y: number): { x: number; y: number } {
432443
const m = this.getContainerMatrix();
433444
if (m) {
434-
// Mirror clientToStorage: apply only the linear part of the matrix
435-
// and add the rect origin. Translate is already in rect.left/top.
445+
// Mirror clientToStorage; same `transform-origin: 0 0` assumption.
446+
// Apply only the linear part of the matrix to the local coord and
447+
// add the rect origin — the translate (e, f) is already in
448+
// rect.left / rect.top.
436449
const a = m.matrix.a;
437450
const b = m.matrix.b;
438451
const c = m.matrix.c;

0 commit comments

Comments
 (0)