From ada1f434f708f2b718bfa52e3df7d93e16901132 Mon Sep 17 00:00:00 2001 From: Ayusman Singhal Date: Thu, 7 May 2026 12:19:48 +0530 Subject: [PATCH] feat: add 'No Webcam' layout preset to hide webcam in final recording Adds a new 'No Webcam' option to the webcam layout preset dropdown in the editor. When selected, the webcam feed is completely hidden from both the preview and the exported video, allowing users who recorded with a webcam to exclude it from the final output. - Add 'no-webcam' to WebcamLayoutPreset type union and preset map - Handle 'no-webcam' in computeCompositeLayout (returns webcamRect: null) - Add 'no-webcam' case in project persistence normalization - Add 'No Webcam' option to the layout preset dropdown in SettingsPanel - Add 'noWebcam' i18n translation key (en) --- src/components/video-editor/SettingsPanel.tsx | 5 ++- .../video-editor/projectPersistence.ts | 1 + src/i18n/locales/en/settings.json | 1 + src/lib/compositeLayout.ts | 32 ++++++++++++++++++- 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/components/video-editor/SettingsPanel.tsx b/src/components/video-editor/SettingsPanel.tsx index 76ff762d..6cadead0 100644 --- a/src/components/video-editor/SettingsPanel.tsx +++ b/src/components/video-editor/SettingsPanel.tsx @@ -821,6 +821,7 @@ export function SettingsPanel({ {WEBCAM_LAYOUT_PRESETS.filter((preset) => { if (preset.value === "picture-in-picture") return true; + if (preset.value === "no-webcam") return true; if (preset.value === "vertical-stack") return isPortraitCanvas; return !isPortraitCanvas; }).map((preset) => ( @@ -829,7 +830,9 @@ export function SettingsPanel({ ? t("layout.pictureInPicture") : preset.value === "vertical-stack" ? t("layout.verticalStack") - : t("layout.dualFrame")} + : preset.value === "no-webcam" + ? t("layout.noWebcam") + : t("layout.dualFrame")} ))} diff --git a/src/components/video-editor/projectPersistence.ts b/src/components/video-editor/projectPersistence.ts index 8d134282..aec570f9 100644 --- a/src/components/video-editor/projectPersistence.ts +++ b/src/components/video-editor/projectPersistence.ts @@ -100,6 +100,7 @@ function computeNormalizedWebcamLayoutPreset( ): WebcamLayoutPreset { switch (webcamLayoutPreset) { case "picture-in-picture": + case "no-webcam": return webcamLayoutPreset; case "vertical-stack": return isPortraitAspectRatio(normalizedAspectRatio) diff --git a/src/i18n/locales/en/settings.json b/src/i18n/locales/en/settings.json index 557fb14e..aeac04f8 100644 --- a/src/i18n/locales/en/settings.json +++ b/src/i18n/locales/en/settings.json @@ -35,6 +35,7 @@ "pictureInPicture": "Picture in Picture", "verticalStack": "Vertical Stack", "dualFrame": "Dual Frame", + "noWebcam": "No Webcam", "webcamShape": "Camera Shape", "webcamSize": "Webcam Size" }, diff --git a/src/lib/compositeLayout.ts b/src/lib/compositeLayout.ts index e6db7337..93161c06 100644 --- a/src/lib/compositeLayout.ts +++ b/src/lib/compositeLayout.ts @@ -15,7 +15,11 @@ export interface Size { height: number; } -export type WebcamLayoutPreset = "picture-in-picture" | "vertical-stack" | "dual-frame"; +export type WebcamLayoutPreset = + | "picture-in-picture" + | "vertical-stack" + | "dual-frame" + | "no-webcam"; /** Webcam size as a percentage of the canvas reference dimension (10–50). */ export type WebcamSizePreset = number; @@ -126,6 +130,21 @@ const WEBCAM_LAYOUT_PRESET_MAP: Record