fix(annotations): lock annotations to the picture at any player size
Deploy / deploy (push) Successful in 3m7s

Points were normalised to the whole player box, but the video is drawn
object-contain inside it, so any change in the player's shape (window or
panel resize, fullscreen, phone rotation, the annotation toolbar opening)
moved the picture under the marks.

The canvas now sits exactly over the displayed picture (same letterbox
measurement as AspectOverlay), so points are fractions of the image and
new saves are tagged version "2.0". Legacy "1.0" annotations are mapped
onto the picture at load time from their stored canvasWidth/canvasHeight
and the video's intrinsic size; no data migration. The save action now
accepts both versions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
twotalesanimation
2026-09-22 14:34:57 +02:00
parent 428814b8b9
commit 2817c7e815
4 changed files with 103 additions and 13 deletions
+8 -3
View File
@@ -8,8 +8,8 @@ export { Role, ApprovalStatus, ReviewStatus, ShotStatus, ShotApprovalStatus, Sho
export type AnnotationTool = "freehand" | "arrow" | "rectangle" | "circle";
export interface AnnotationPoint {
x: number; // normalized 0-1 relative to canvas width
y: number; // normalized 0-1 relative to canvas height
x: number; // normalized 0-1 — v2.0: of the picture; v1.0: of the player box
y: number; // normalized 0-1 — v2.0: of the picture; v1.0: of the player box
}
export interface AnnotationShape {
@@ -26,7 +26,12 @@ export interface AnnotationDrawingData {
shapes: AnnotationShape[];
canvasWidth: number;
canvasHeight: number;
version: "1.0";
/**
* "2.0": points are relative to the displayed picture, so they stay locked to
* the image at any player size. "1.0" (legacy): relative to the whole player
* box (picture + letterbox bars) that was canvasWidth x canvasHeight.
*/
version: "1.0" | "2.0";
}
// ── Review Player State ──────────────────────────────────────────────────────