diff --git a/src/components/video-editor/KeyboardShortcutsHelp.tsx b/src/components/video-editor/KeyboardShortcutsHelp.tsx new file mode 100644 index 0000000..221d9eb --- /dev/null +++ b/src/components/video-editor/KeyboardShortcutsHelp.tsx @@ -0,0 +1,34 @@ +import { HelpCircle } from "lucide-react"; + +export function KeyboardShortcutsHelp() { + return ( +
+ +
+
Keyboard Shortcuts
+
+
+ Add Zoom + Z +
+
+ Add Keyframe + F +
+
+ Delete Selected + ⌘ + D +
+
+ Pan Timeline + ⇧ + ⌘ + Scroll +
+
+ Zoom Timeline + ⌘ + Scroll +
+
+
+
+ ); +} diff --git a/src/components/video-editor/SettingsPanel.tsx b/src/components/video-editor/SettingsPanel.tsx index 02759cd..8fa94d8 100644 --- a/src/components/video-editor/SettingsPanel.tsx +++ b/src/components/video-editor/SettingsPanel.tsx @@ -13,6 +13,7 @@ import { GiHearts } from "react-icons/gi"; import { toast } from "sonner"; import type { ZoomDepth, CropRegion } from "./types"; import { CropControl } from "./CropControl"; +import { KeyboardShortcutsHelp } from "./KeyboardShortcutsHelp"; const WALLPAPER_COUNT = 23; const WALLPAPER_RELATIVE = Array.from({ length: WALLPAPER_COUNT }, (_, i) => `wallpapers/wallpaper${i + 1}.jpg`); @@ -68,6 +69,7 @@ const ZOOM_DEPTH_OPTIONS: Array<{ depth: ZoomDepth; label: string }> = [ { depth: 3, label: "1.8×" }, { depth: 4, label: "2.2×" }, { depth: 5, label: "3.5×" }, + { depth: 6, label: "5×" }, ]; export function SettingsPanel({ selected, onWallpaperChange, selectedZoomDepth, onZoomDepthChange, selectedZoomId, onZoomDelete, shadowIntensity = 0, onShadowChange, showBlur, onBlurChange, cropRegion, onCropChange, videoElement, onExport }: SettingsPanelProps) { @@ -151,13 +153,16 @@ export function SettingsPanel({ selected, onWallpaperChange, selectedZoomDepth,
Zoom Level - {zoomEnabled && selectedZoomDepth && ( - - {ZOOM_DEPTH_OPTIONS.find(o => o.depth === selectedZoomDepth)?.label} Active - - )} +
+ {zoomEnabled && selectedZoomDepth && ( + + {ZOOM_DEPTH_OPTIONS.find(o => o.depth === selectedZoomDepth)?.label} Active + + )} + +
-
+
{ZOOM_DEPTH_OPTIONS.map((option) => { const isActive = selectedZoomDepth === option.depth; return ( diff --git a/src/components/video-editor/timeline/TimelineEditor.tsx b/src/components/video-editor/timeline/TimelineEditor.tsx index 6599889..6049799 100644 --- a/src/components/video-editor/timeline/TimelineEditor.tsx +++ b/src/components/video-editor/timeline/TimelineEditor.tsx @@ -401,24 +401,6 @@ export default function TimelineEditor({ onSelectZoom(null); }, [selectedZoomId, onZoomDelete, onSelectZoom]); - // Listen for F key to add keyframe, Ctrl+D to remove selected keyframe or zoom item - useEffect(() => { - const handleKeyDown = (e: KeyboardEvent) => { - if (e.key === 'f' || e.key === 'F') { - addKeyframe(); - } - if ((e.key === 'd' || e.key === 'D') && (e.ctrlKey || e.metaKey)) { - if (selectedKeyframeId) { - deleteSelectedKeyframe(); - } else if (selectedZoomId) { - deleteSelectedZoom(); - } - } - }; - window.addEventListener('keydown', handleKeyDown); - return () => window.removeEventListener('keydown', handleKeyDown); - }, [addKeyframe, deleteSelectedKeyframe, deleteSelectedZoom, selectedKeyframeId, selectedZoomId]); - useEffect(() => { setRange(createInitialRange(totalMs)); }, [totalMs]); @@ -484,6 +466,27 @@ export default function TimelineEditor({ onZoomAdded({ start: startPos, end: startPos + actualDuration }); }, [videoDuration, totalMs, currentTimeMs, zoomRegions, onZoomAdded]); + // Listen for F key to add keyframe, Z key to add zoom, Ctrl+D to remove selected keyframe or zoom item + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === 'f' || e.key === 'F') { + addKeyframe(); + } + if (e.key === 'z' || e.key === 'Z') { + handleAddZoom(); + } + if ((e.key === 'd' || e.key === 'D') && (e.ctrlKey || e.metaKey)) { + if (selectedKeyframeId) { + deleteSelectedKeyframe(); + } else if (selectedZoomId) { + deleteSelectedZoom(); + } + } + }; + window.addEventListener('keydown', handleKeyDown); + return () => window.removeEventListener('keydown', handleKeyDown); + }, [addKeyframe, handleAddZoom, deleteSelectedKeyframe, deleteSelectedZoom, selectedKeyframeId, selectedZoomId]); + const clampedRange = useMemo(() => { if (totalMs === 0) { return range; @@ -543,10 +546,6 @@ export default function TimelineEditor({ ⌘ + Scroll Zoom - - F - Add Keyframe -
= { 3: 1.8, 4: 2.2, 5: 3.5, + 6: 5.0, }; export const DEFAULT_ZOOM_DEPTH: ZoomDepth = 3;