@@ -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