diff --git a/src/components/video-editor/SettingsPanel.tsx b/src/components/video-editor/SettingsPanel.tsx index 571b587d..6de6a7fb 100644 --- a/src/components/video-editor/SettingsPanel.tsx +++ b/src/components/video-editor/SettingsPanel.tsx @@ -238,6 +238,8 @@ interface SettingsPanelProps { selectedZoomCustomScale?: number | null; onZoomCustomScaleChange?: (scale: number) => void; onZoomCustomScaleCommit?: () => void; + onZoomPreviewStart?: () => void; + onZoomPreviewEnd?: () => void; selectedZoomFocusMode?: ZoomFocusMode | null; onZoomFocusModeChange?: (mode: ZoomFocusMode) => void; selectedZoomFocus?: ZoomFocus | null; @@ -367,6 +369,8 @@ export function SettingsPanel({ selectedZoomCustomScale, onZoomCustomScaleChange, onZoomCustomScaleCommit, + onZoomPreviewStart, + onZoomPreviewEnd, selectedZoomFocusMode, onZoomFocusModeChange, selectedZoomFocus, @@ -949,6 +953,31 @@ export function SettingsPanel({ )} + {zoomEnabled && onZoomPreviewStart && onZoomPreviewEnd && ( + + )} {zoomEnabled && selectedZoomFocusMode !== "auto" && selectedZoomFocus && diff --git a/src/components/video-editor/VideoEditor.tsx b/src/components/video-editor/VideoEditor.tsx index b44d9b63..b32621c9 100644 --- a/src/components/video-editor/VideoEditor.tsx +++ b/src/components/video-editor/VideoEditor.tsx @@ -195,6 +195,7 @@ export default function VideoEditor() { const durationRef = useRef(duration); durationRef.current = duration; const [selectedZoomId, setSelectedZoomId] = useState(null); + const [isPreviewingZoom, setIsPreviewingZoom] = useState(false); const [selectedTrimId, setSelectedTrimId] = useState(null); const [selectedSpeedId, setSelectedSpeedId] = useState(null); const [selectedAnnotationId, setSelectedAnnotationId] = useState(null); @@ -2120,6 +2121,7 @@ export default function VideoEditor() { cursorMotionBlur={cursorMotionBlur} cursorClickBounce={cursorClickBounce} cursorClipToBounds={cursorClipToBounds} + isPreviewingZoom={isPreviewingZoom} /> @@ -2155,6 +2157,8 @@ export default function VideoEditor() { } onZoomCustomScaleChange={handleZoomCustomScaleChange} onZoomCustomScaleCommit={handleZoomCustomScaleCommit} + onZoomPreviewStart={() => setIsPreviewingZoom(true)} + onZoomPreviewEnd={() => setIsPreviewingZoom(false)} selectedZoomFocusMode={ selectedZoomId ? (zoomRegions.find((z) => z.id === selectedZoomId)?.focusMode ?? "manual") diff --git a/src/components/video-editor/VideoPlayback.tsx b/src/components/video-editor/VideoPlayback.tsx index 5b25ced3..28c7b50a 100644 --- a/src/components/video-editor/VideoPlayback.tsx +++ b/src/components/video-editor/VideoPlayback.tsx @@ -150,6 +150,9 @@ interface VideoPlaybackProps { cursorMotionBlur?: number; cursorClickBounce?: number; cursorClipToBounds?: boolean; + // When true, render the selected zoom at the playhead even while paused — + // lets the editor preview the zoom effect without leaving the focus-edit view. + isPreviewingZoom?: boolean; } export interface VideoPlaybackRef { @@ -271,6 +274,7 @@ const VideoPlayback = forwardRef( cursorMotionBlur = DEFAULT_CURSOR_SETTINGS.motionBlur, cursorClickBounce = DEFAULT_CURSOR_SETTINGS.clickBounce, cursorClipToBounds = DEFAULT_CURSOR_SETTINGS.clipToBounds, + isPreviewingZoom = false, }, ref, ) => { @@ -342,6 +346,7 @@ const VideoPlayback = forwardRef( const cursorMotionBlurRef = useRef(cursorMotionBlur); const cursorClickBounceRef = useRef(cursorClickBounce); const cursorClipToBoundsRef = useRef(cursorClipToBounds); + const isPreviewingZoomRef = useRef(isPreviewingZoom); const motionBlurStateRef = useRef(createMotionBlurState()); const onTimeUpdateRef = useRef(onTimeUpdate); const onPlayStateChangeRef = useRef(onPlayStateChange); @@ -833,6 +838,10 @@ const VideoPlayback = forwardRef( cursorClipToBoundsRef.current = cursorClipToBounds; }, [cursorClipToBounds]); + useEffect(() => { + isPreviewingZoomRef.current = isPreviewingZoom; + }, [isPreviewingZoom]); + // Sync cursor overlay config when settings change useEffect(() => { const overlay = cursorOverlayRef.current; @@ -1310,7 +1319,8 @@ const VideoPlayback = forwardRef( // If a zoom is selected but video is not playing, show default unzoomed view const selectedId = selectedZoomIdRef.current; const hasSelectedZoom = selectedId !== null; - const shouldShowUnzoomedView = hasSelectedZoom && !isPlayingRef.current; + const shouldShowUnzoomedView = + hasSelectedZoom && !isPlayingRef.current && !isPreviewingZoomRef.current; if (region && strength > 0 && !shouldShowUnzoomedView) { const zoomScale = blendedScale ?? ZOOM_DEPTH_SCALES[region.depth]; diff --git a/src/i18n/locales/ar/settings.json b/src/i18n/locales/ar/settings.json index 0b7bf8b1..6cd90b6a 100644 --- a/src/i18n/locales/ar/settings.json +++ b/src/i18n/locales/ar/settings.json @@ -1,5 +1,6 @@ { "zoom": { + "previewHold": "اضغط مع الاستمرار لمعاينة تأثير التكبير", "level": "مستوى التكبير", "selectRegion": "حدد منطقة التكبير للتعديل", "deleteZoom": "حذف التكبير", diff --git a/src/i18n/locales/en/settings.json b/src/i18n/locales/en/settings.json index fae2f2ca..f6d89e82 100644 --- a/src/i18n/locales/en/settings.json +++ b/src/i18n/locales/en/settings.json @@ -1,5 +1,6 @@ { "zoom": { + "previewHold": "Hold to preview zoom effect", "level": "Zoom Level", "customScale": "Custom Zoom", "selectRegion": "Select a zoom region to adjust", diff --git a/src/i18n/locales/es/settings.json b/src/i18n/locales/es/settings.json index 60a4def5..130754fd 100644 --- a/src/i18n/locales/es/settings.json +++ b/src/i18n/locales/es/settings.json @@ -1,5 +1,6 @@ { "zoom": { + "previewHold": "Mantener para previsualizar el efecto de zoom", "level": "Nivel de zoom", "selectRegion": "Selecciona una región de zoom para ajustar", "deleteZoom": "Eliminar zoom", diff --git a/src/i18n/locales/fr/settings.json b/src/i18n/locales/fr/settings.json index df98a2df..bf39c64c 100644 --- a/src/i18n/locales/fr/settings.json +++ b/src/i18n/locales/fr/settings.json @@ -1,5 +1,6 @@ { "zoom": { + "previewHold": "Maintenir pour prévisualiser l’effet de zoom", "level": "Niveau de zoom", "selectRegion": "Sélectionnez une région de zoom à ajuster", "deleteZoom": "Supprimer le zoom", diff --git a/src/i18n/locales/ja-JP/settings.json b/src/i18n/locales/ja-JP/settings.json index 7b729c3e..cec09bef 100644 --- a/src/i18n/locales/ja-JP/settings.json +++ b/src/i18n/locales/ja-JP/settings.json @@ -1,5 +1,6 @@ { "zoom": { + "previewHold": "押している間ズーム効果をプレビュー", "level": "ズーム倍率", "selectRegion": "ズーム範囲を選択して調整", "deleteZoom": "ズームを削除", diff --git a/src/i18n/locales/ko-KR/settings.json b/src/i18n/locales/ko-KR/settings.json index cdc57f3c..5ff469c4 100644 --- a/src/i18n/locales/ko-KR/settings.json +++ b/src/i18n/locales/ko-KR/settings.json @@ -1,5 +1,6 @@ { "zoom": { + "previewHold": "누르고 있으면 줌 효과 미리보기", "level": "줌 레벨", "customScale": "커스텀 줌", "selectRegion": "조정할 줌 구간을 선택하세요", diff --git a/src/i18n/locales/ru/settings.json b/src/i18n/locales/ru/settings.json index 02e4fbae..c0dbba8f 100644 --- a/src/i18n/locales/ru/settings.json +++ b/src/i18n/locales/ru/settings.json @@ -1,5 +1,6 @@ { "zoom": { + "previewHold": "Удерживайте для предпросмотра эффекта зума", "level": "Уровень масштабирования", "selectRegion": "Выберите область масштабирования для настройки", "deleteZoom": "Удалить масштабирование", diff --git a/src/i18n/locales/tr/settings.json b/src/i18n/locales/tr/settings.json index 6bebd4e7..7f426c20 100644 --- a/src/i18n/locales/tr/settings.json +++ b/src/i18n/locales/tr/settings.json @@ -1,5 +1,6 @@ { "zoom": { + "previewHold": "Yakınlaştırma efektini önizlemek için basılı tutun", "level": "Yakınlaştırma Seviyesi", "selectRegion": "Ayarlamak için bir yakınlaştırma bölgesi seçin", "deleteZoom": "Yakınlaştırmayı Sil", diff --git a/src/i18n/locales/vi/settings.json b/src/i18n/locales/vi/settings.json index c0bf09f8..e83c799d 100644 --- a/src/i18n/locales/vi/settings.json +++ b/src/i18n/locales/vi/settings.json @@ -1,5 +1,6 @@ { "zoom": { + "previewHold": "Giữ để xem trước hiệu ứng phóng to", "level": "Mức độ thu phóng", "selectRegion": "Chọn vùng thu phóng để điều chỉnh", "deleteZoom": "Xóa thu phóng", diff --git a/src/i18n/locales/zh-CN/settings.json b/src/i18n/locales/zh-CN/settings.json index 77f41b71..b4fafdd6 100644 --- a/src/i18n/locales/zh-CN/settings.json +++ b/src/i18n/locales/zh-CN/settings.json @@ -1,5 +1,6 @@ { "zoom": { + "previewHold": "按住预览放大效果", "level": "缩放级别", "selectRegion": "选择要调整的缩放区域", "deleteZoom": "删除缩放", diff --git a/src/i18n/locales/zh-TW/settings.json b/src/i18n/locales/zh-TW/settings.json index 72d7a205..9d970ea7 100644 --- a/src/i18n/locales/zh-TW/settings.json +++ b/src/i18n/locales/zh-TW/settings.json @@ -1,5 +1,6 @@ { "zoom": { + "previewHold": "按住預覽放大效果", "level": "縮放級別", "selectRegion": "選擇要調整的縮放區域", "deleteZoom": "刪除縮放",