fixup! ♻️(frontend) refactor screen share zoom pan with useMove and imperative DOM updates

This commit is contained in:
Ovgodd
2026-09-09 10:50:39 +02:00
parent 9b8d7cb66d
commit 1f66a136ec
@@ -29,8 +29,8 @@ import {
* when the toolbar UI needs to update (zoom level change, drag end).
*
* Drag/touch panning is handled by react-aria's useMove (moveProps).
* Ctrl/Cmd + wheel zoom is a native listener (must be non-passive to
* preventDefault and block browser page zoom).
* The wheel listener (non-passive) zooms on Ctrl/Cmd+scroll and pans on a
* two-finger trackpad scroll once zoomed.
* Arrow key panning and +/-/0 zoom are on a keydown listener attached to the
* tile container (which has tabIndex=0 and focus).
*/
@@ -127,39 +127,66 @@ export const useScreenShareZoom = () => {
const resetZoom = useCallback(() => setZoom(MIN_ZOOM), [setZoom])
// Must be attached with { passive: false } so preventDefault() blocks
// the browser's native Ctrl+scroll page zoom.
// the browser's native Ctrl+scroll page zoom. Trackpad pinch arrives
// here as a wheel event with ctrl/cmd already set.
const handleWheel = useCallback(
(e: WheelEvent) => {
if (!e.ctrlKey && !e.metaKey) return
if (e.ctrlKey || e.metaKey) {
e.preventDefault()
e.stopPropagation()
const target = e.currentTarget as HTMLElement
const prev = zoomRef.current
const delta = -e.deltaY * WHEEL_ZOOM_SPEED
const next = clampZoom(prev + delta)
if (next <= MIN_ZOOM) {
zoomRef.current = MIN_ZOOM
panRef.current = { x: 0, y: 0 }
} else {
const { cursorXPercent, cursorYPercent } =
getCursorPercentsFromWheelEvent(e, target)
zoomRef.current = next
panRef.current = getWheelPanOffset({
pan: panRef.current,
prevZoom: prev,
nextZoom: next,
cursorXPercent,
cursorYPercent,
ratio: readPictureRatio(),
})
}
applyTransform()
applyCursor()
flush()
return
}
// Two-finger trackpad scroll: pan only once zoomed, otherwise leave
// the event alone so the page can still scroll.
if (zoomRef.current <= MIN_ZOOM) return
const el = surfaceElRef.current
if (!el) return
e.preventDefault()
e.stopPropagation()
const target = e.currentTarget as HTMLElement
const prev = zoomRef.current
const delta = -e.deltaY * WHEEL_ZOOM_SPEED
const next = clampZoom(prev + delta)
if (next <= MIN_ZOOM) {
zoomRef.current = MIN_ZOOM
panRef.current = { x: 0, y: 0 }
} else {
const { cursorXPercent, cursorYPercent } =
getCursorPercentsFromWheelEvent(e, target)
zoomRef.current = next
panRef.current = getWheelPanOffset({
pan: panRef.current,
prevZoom: prev,
nextZoom: next,
cursorXPercent,
cursorYPercent,
ratio: readPictureRatio(),
})
}
const { deltaXPercent, deltaYPercent } = getPanDeltaPercentsFromMove(
-e.deltaX,
-e.deltaY,
el
)
panRef.current = clampPan(
{
x: panRef.current.x + deltaXPercent,
y: panRef.current.y + deltaYPercent,
},
zoomRef.current,
readPictureRatio()
)
applyTransform()
applyCursor()
flush()
},
[applyTransform, applyCursor, flush, readPictureRatio]
)