mobile support for client review player
Deploy / deploy (push) Failing after 5m17s

This commit is contained in:
twotalesanimation
2026-06-12 09:01:28 +02:00
parent 3248b8596a
commit 289e0c367a
5 changed files with 176 additions and 70 deletions
+41 -2
View File
@@ -170,21 +170,60 @@ export function FrameTimeline({ fps, comments, annotations = [], videoRef, onSee
isDragging.current = false;
}, []);
// ── Touch scrubbing ──────────────────────────────────────────────────────
const getFrameFromTouch = useCallback(
(touch: Touch): number => {
const canvas = canvasRef.current;
if (!canvas || totalFrames === 0) return 0;
const rect = canvas.getBoundingClientRect();
const x = Math.max(0, Math.min(touch.clientX - rect.left, rect.width));
return Math.round((x / rect.width) * totalFrames);
},
[totalFrames]
);
const handleTouchStart = useCallback(
(e: React.TouchEvent<HTMLCanvasElement>) => {
e.preventDefault();
const touch = e.touches[0];
if (!touch) return;
isDragging.current = true;
onSeek(getFrameFromTouch(touch));
},
[getFrameFromTouch, onSeek]
);
const handleTouchMove = useCallback(
(e: TouchEvent) => {
if (!isDragging.current) return;
e.preventDefault();
const touch = e.touches[0];
if (!touch) return;
onSeek(getFrameFromTouch(touch));
},
[getFrameFromTouch, onSeek]
);
useEffect(() => {
window.addEventListener("mousemove", handleMouseMove);
window.addEventListener("mouseup", handleMouseUp);
window.addEventListener("touchmove", handleTouchMove, { passive: false });
window.addEventListener("touchend", handleMouseUp);
return () => {
window.removeEventListener("mousemove", handleMouseMove);
window.removeEventListener("mouseup", handleMouseUp);
window.removeEventListener("touchmove", handleTouchMove);
window.removeEventListener("touchend", handleMouseUp);
};
}, [handleMouseMove, handleMouseUp]);
}, [handleMouseMove, handleMouseUp, handleTouchMove]);
return (
<canvas
ref={canvasRef}
className="frame-timeline w-full cursor-ew-resize"
style={{ height: 48 }}
style={{ height: 48, touchAction: "none" }}
onMouseDown={handleMouseDown}
onTouchStart={handleTouchStart}
/>
);
}