diff --git a/src/components/video-editor/projectPersistence.test.ts b/src/components/video-editor/projectPersistence.test.ts index fd2cb43..9a99ef7 100644 --- a/src/components/video-editor/projectPersistence.test.ts +++ b/src/components/video-editor/projectPersistence.test.ts @@ -82,6 +82,15 @@ describe("projectPersistence media compatibility", () => { }).webcamLayoutPreset, ).toBe("picture-in-picture"); }); + + it("clears webcamPosition when the normalized preset is not picture in picture", () => { + expect( + normalizeProjectEditor({ + webcamLayoutPreset: "dual-frame", + webcamPosition: { cx: 0.2, cy: 0.8 }, + }).webcamPosition, + ).toBeNull(); + }); }); it("creates stable snapshots for identical project state", () => { diff --git a/src/components/video-editor/projectPersistence.ts b/src/components/video-editor/projectPersistence.ts index 1d78f29..7a4881a 100644 --- a/src/components/video-editor/projectPersistence.ts +++ b/src/components/video-editor/projectPersistence.ts @@ -202,6 +202,17 @@ export function normalizeProjectEditor(editor: Partial): Pro ? DEFAULT_WEBCAM_LAYOUT_PRESET : editor.webcamLayoutPreset : DEFAULT_WEBCAM_LAYOUT_PRESET; + const normalizedWebcamPosition: WebcamPosition | null = + normalizedWebcamLayoutPreset === "picture-in-picture" && + editor.webcamPosition && + typeof editor.webcamPosition === "object" && + isFiniteNumber((editor.webcamPosition as WebcamPosition).cx) && + isFiniteNumber((editor.webcamPosition as WebcamPosition).cy) + ? { + cx: clamp((editor.webcamPosition as WebcamPosition).cx, 0, 1), + cy: clamp((editor.webcamPosition as WebcamPosition).cy, 0, 1), + } + : DEFAULT_WEBCAM_POSITION; const normalizedZoomRegions: ZoomRegion[] = Array.isArray(editor.zoomRegions) ? editor.zoomRegions @@ -426,16 +437,7 @@ export function normalizeProjectEditor(editor: Partial): Pro typeof editor.webcamSizePreset === "number" && isFiniteNumber(editor.webcamSizePreset) ? Math.max(10, Math.min(50, editor.webcamSizePreset)) : DEFAULT_WEBCAM_SIZE_PRESET, - webcamPosition: - editor.webcamPosition && - typeof editor.webcamPosition === "object" && - isFiniteNumber((editor.webcamPosition as WebcamPosition).cx) && - isFiniteNumber((editor.webcamPosition as WebcamPosition).cy) - ? { - cx: clamp((editor.webcamPosition as WebcamPosition).cx, 0, 1), - cy: clamp((editor.webcamPosition as WebcamPosition).cy, 0, 1), - } - : DEFAULT_WEBCAM_POSITION, + webcamPosition: normalizedWebcamPosition, exportQuality: editor.exportQuality === "medium" || editor.exportQuality === "source" ? editor.exportQuality