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 76ff762..6cadead 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 8d13428..aec570f 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 557fb14..aeac04f 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 e6db733..93161c0 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