From d2ee51146610e61107d4437dee4279a93c134118 Mon Sep 17 00:00:00 2001 From: Siddharth Date: Fri, 28 Nov 2025 23:54:58 -0700 Subject: [PATCH] preview aspect ratio --- src/components/video-editor/CropControl.tsx | 7 ++- src/components/video-editor/SettingsPanel.tsx | 34 +++++++++++++- src/components/video-editor/VideoEditor.tsx | 7 ++- src/components/video-editor/VideoPlayback.tsx | 5 ++- src/utils/aspectRatioUtils.ts | 45 +++++++++++++++++++ 5 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 src/utils/aspectRatioUtils.ts diff --git a/src/components/video-editor/CropControl.tsx b/src/components/video-editor/CropControl.tsx index 036116c..129b536 100644 --- a/src/components/video-editor/CropControl.tsx +++ b/src/components/video-editor/CropControl.tsx @@ -1,5 +1,6 @@ import { useEffect, useRef, useState } from "react"; import { cn } from "@/lib/utils"; +import { type AspectRatio, formatAspectRatioForCSS } from "@/utils/aspectRatioUtils"; interface CropRegion { x: number; // 0-1 normalized @@ -12,11 +13,12 @@ interface CropControlProps { videoElement: HTMLVideoElement | null; cropRegion: CropRegion; onCropChange: (region: CropRegion) => void; + aspectRatio: AspectRatio; } type DragHandle = 'top' | 'right' | 'bottom' | 'left' | null; -export function CropControl({ videoElement, cropRegion, onCropChange }: CropControlProps) { +export function CropControl({ videoElement, cropRegion, onCropChange, aspectRatio }: CropControlProps) { const canvasRef = useRef(null); const containerRef = useRef(null); const [isDragging, setIsDragging] = useState(null); @@ -119,7 +121,8 @@ export function CropControl({ videoElement, cropRegion, onCropChange }: CropCont
`wallpapers/wallpaper${i + 1}.jpg`); @@ -63,6 +64,8 @@ interface SettingsPanelProps { onPaddingChange?: (padding: number) => void; cropRegion?: CropRegion; onCropChange?: (region: CropRegion) => void; + aspectRatio: AspectRatio; + onAspectRatioChange: (aspectRatio: AspectRatio) => void; videoElement?: HTMLVideoElement | null; onExport?: () => void; } @@ -78,7 +81,7 @@ const ZOOM_DEPTH_OPTIONS: Array<{ depth: ZoomDepth; label: string }> = [ { depth: 6, label: "5×" }, ]; -export function SettingsPanel({ selected, onWallpaperChange, selectedZoomDepth, onZoomDepthChange, selectedZoomId, onZoomDelete, shadowIntensity = 0, onShadowChange, showBlur, onBlurChange, motionBlurEnabled = true, onMotionBlurChange, borderRadius = 0, onBorderRadiusChange, padding = 50, onPaddingChange, cropRegion, onCropChange, videoElement, onExport }: SettingsPanelProps) { +export function SettingsPanel({ selected, onWallpaperChange, selectedZoomDepth, onZoomDepthChange, selectedZoomId, onZoomDelete, shadowIntensity = 0, onShadowChange, showBlur, onBlurChange, motionBlurEnabled = true, onMotionBlurChange, borderRadius = 0, onBorderRadiusChange, padding = 50, onPaddingChange, cropRegion, onCropChange, aspectRatio, onAspectRatioChange, videoElement, onExport }: SettingsPanelProps) { const [wallpaperPaths, setWallpaperPaths] = useState([]); const [customImages, setCustomImages] = useState([]); const fileInputRef = useRef(null); @@ -230,11 +233,37 @@ export function SettingsPanel({ selected, onWallpaperChange, selectedZoomDepth,
+
+ Aspect Ratio +
+ {(['16:9', '9:16', '1:1', '4:3'] as AspectRatio[]).map((ratio) => { + const isActive = aspectRatio === ratio; + return ( + + ); + })} +
+
+ +
{/* Drop Shadow Slider */}
-
+
\n
Shadow
{Math.round(shadowIntensity * 100)}%
@@ -319,6 +348,7 @@ export function SettingsPanel({ selected, onWallpaperChange, selectedZoomDepth, videoElement={videoElement || null} cropRegion={cropRegion} onCropChange={onCropChange} + aspectRatio={aspectRatio} />