Skip to content
This repository was archived by the owner on Jun 17, 2026. It is now read-only.

Commit 0cb298d

Browse files
committed
Fix Pr reviews
1 parent 7409631 commit 0cb298d

4 files changed

Lines changed: 49 additions & 26 deletions

File tree

src/components/video-editor/SettingsPanel.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ const ZOOM_DEPTH_OPTIONS: Array<{ depth: ZoomDepth; label: string }> = [
166166
{ depth: 6, label: "5×" },
167167
];
168168

169-
// TODO: make this configurable
170169
const ZOOM_SPEED_OPTIONS = [
171170
{ label: "Instant", zoomIn: 0, zoomOut: 0 },
172171
{ label: "Fast", zoomIn: 500, zoomOut: 350 },
@@ -570,8 +569,10 @@ export function SettingsPanel({
570569
<div className="grid grid-cols-4 gap-1.5">
571570
{ZOOM_SPEED_OPTIONS.map((opt) => {
572571
const isActive =
573-
selectedZoomInDuration === opt.zoomIn &&
574-
selectedZoomOutDuration === opt.zoomOut;
572+
selectedZoomInDuration !== undefined &&
573+
selectedZoomOutDuration !== undefined &&
574+
Math.round(selectedZoomInDuration) === Math.round(opt.zoomIn) &&
575+
Math.round(selectedZoomOutDuration) === Math.round(opt.zoomOut);
575576
return (
576577
<Button
577578
key={opt.label}
@@ -924,7 +925,7 @@ export function SettingsPanel({
924925
</AccordionTrigger>
925926
<AccordionContent className="pb-3">
926927
<Tabs defaultValue="image" className="w-full">
927-
<TabsList className="mb-2 bg-white/5 border border-white/5 p-0.5 w-full grid grid-cols-3 rounded-lg">
928+
<TabsList className="mb-2 bg-white/5 border border-white/5 p-0.5 w-full grid grid-cols-3 rounded-lg">
928929
<TabsTrigger
929930
value="image"
930931
className="data-[state=active]:bg-[#34B27B] data-[state=active]:text-white text-slate-400 text-[10px] py-1 rounded-md transition-all"

src/components/video-editor/VideoEditor.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,13 +1773,13 @@ export default function VideoEditor() {
17731773
selectedZoomInDuration={
17741774
selectedZoomId
17751775
? (zoomRegions.find((z) => z.id === selectedZoomId)?.zoomInDurationMs ??
1776-
ZOOM_IN_TRANSITION_WINDOW_MS)
1776+
Math.round(ZOOM_IN_TRANSITION_WINDOW_MS))
17771777
: undefined
17781778
}
17791779
selectedZoomOutDuration={
17801780
selectedZoomId
17811781
? (zoomRegions.find((z) => z.id === selectedZoomId)?.zoomOutDurationMs ??
1782-
TRANSITION_WINDOW_MS)
1782+
Math.round(TRANSITION_WINDOW_MS))
17831783
: undefined
17841784
}
17851785
onZoomDurationChange={(zoomIn, zoomOut) =>

src/components/video-editor/timeline/Item.tsx

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ import { useItem, useTimelineContext } from "dnd-timeline";
33
import { Gauge, MessageSquare, Scissors, ZoomIn } from "lucide-react";
44
import { useMemo } from "react";
55
import { cn } from "@/lib/utils";
6+
import {
7+
DEFAULT_ZOOM_IN_MS,
8+
DEFAULT_ZOOM_OUT_MS,
9+
getDurations,
10+
} from "../videoPlayback/zoomRegionUtils";
611
import glassStyles from "./ItemGlass.module.css";
712

813
interface ItemProps {
@@ -86,6 +91,16 @@ export default function Item({
8691
const MIN_ITEM_PX = 6;
8792
const safeItemStyle = { ...itemStyle, minWidth: MIN_ITEM_PX };
8893

94+
const { zoomIn, zoomOut } = useMemo(() => {
95+
if (!isZoom) return { zoomIn: 0, zoomOut: 0 };
96+
return getDurations({
97+
startMs: span.start,
98+
endMs: span.end,
99+
zoomInDurationMs,
100+
zoomOutDurationMs,
101+
});
102+
}, [isZoom, span.start, span.end, zoomInDurationMs, zoomOutDurationMs]);
103+
89104
return (
90105
<div
91106
ref={setNodeRef}
@@ -114,14 +129,14 @@ export default function Item({
114129
<div
115130
className="absolute top-0 bottom-0 left-0 bg-white/10 border-r border-white/20 pointer-events-none"
116131
style={{
117-
width: `${((zoomInDurationMs ?? 1522.575) / (span.end - span.start)) * 100}%`,
132+
width: `${(zoomIn / (span.end - span.start)) * 100}%`,
118133
}}
119134
/>
120135
{/* Draggable handle for Transition In */}
121136
<div
122137
className="absolute top-0 bottom-0 w-2 cursor-col-resize z-20 group-hover:bg-white/5 transition-colors"
123138
style={{
124-
left: `${((zoomInDurationMs ?? 1522.575) / (span.end - span.start)) * 100}%`,
139+
left: `${(zoomIn / (span.end - span.start)) * 100}%`,
125140
transform: "translateX(-50%)",
126141
}}
127142
onPointerDown={(e) => {
@@ -130,17 +145,18 @@ export default function Item({
130145
const target = e.currentTarget;
131146
target.setPointerCapture(e.pointerId);
132147

148+
const startX = e.clientX;
149+
const initialZoomIn = zoomInDurationMs ?? DEFAULT_ZOOM_IN_MS;
150+
const initialZoomOut = zoomOutDurationMs ?? DEFAULT_ZOOM_OUT_MS;
151+
133152
const onPointerMove = (moveEvent: PointerEvent) => {
134-
const deltaPx = moveEvent.clientX - e.clientX;
153+
const deltaPx = moveEvent.clientX - startX;
135154
const deltaMs = pixelsToValue(deltaPx);
136155
const newDuration = Math.max(
137156
0,
138-
Math.min(
139-
(zoomInDurationMs ?? 1522.575) + deltaMs,
140-
span.end - span.start - (zoomOutDurationMs ?? 1015.05),
141-
),
157+
Math.min(initialZoomIn + deltaMs, span.end - span.start - initialZoomOut),
142158
);
143-
onZoomDurationChange?.(id, newDuration, zoomOutDurationMs ?? 1015.05);
159+
onZoomDurationChange?.(id, newDuration, initialZoomOut);
144160
};
145161

146162
const onPointerUp = () => {
@@ -157,14 +173,14 @@ export default function Item({
157173
<div
158174
className="absolute top-0 bottom-0 right-0 bg-white/10 border-l border-white/20 pointer-events-none"
159175
style={{
160-
width: `${((zoomOutDurationMs ?? 1015.05) / (span.end - span.start)) * 100}%`,
176+
width: `${(zoomOut / (span.end - span.start)) * 100}%`,
161177
}}
162178
/>
163179
{/* Draggable handle for Transition Out */}
164180
<div
165181
className="absolute top-0 bottom-0 w-2 cursor-col-resize z-20 group-hover:bg-white/5 transition-colors"
166182
style={{
167-
right: `${((zoomOutDurationMs ?? 1015.05) / (span.end - span.start)) * 100}%`,
183+
right: `${(zoomOut / (span.end - span.start)) * 100}%`,
168184
transform: "translateX(50%)",
169185
}}
170186
onPointerDown={(e) => {
@@ -173,17 +189,18 @@ export default function Item({
173189
const target = e.currentTarget;
174190
target.setPointerCapture(e.pointerId);
175191

192+
const startX = e.clientX;
193+
const initialZoomIn = zoomInDurationMs ?? DEFAULT_ZOOM_IN_MS;
194+
const initialZoomOut = zoomOutDurationMs ?? DEFAULT_ZOOM_OUT_MS;
195+
176196
const onPointerMove = (moveEvent: PointerEvent) => {
177-
const deltaPx = e.clientX - moveEvent.clientX; // Inverted because right-anchored
197+
const deltaPx = startX - moveEvent.clientX; // Inverted because right-anchored
178198
const deltaMs = pixelsToValue(deltaPx);
179199
const newDuration = Math.max(
180200
0,
181-
Math.min(
182-
(zoomOutDurationMs ?? 1015.05) + deltaMs,
183-
span.end - span.start - (zoomInDurationMs ?? 1522.575),
184-
),
201+
Math.min(initialZoomOut + deltaMs, span.end - span.start - initialZoomIn),
185202
);
186-
onZoomDurationChange?.(id, zoomInDurationMs ?? 1522.575, newDuration);
203+
onZoomDurationChange?.(id, initialZoomIn, newDuration);
187204
};
188205

189206
const onPointerUp = () => {

src/components/video-editor/videoPlayback/zoomRegionUtils.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,15 @@ function easeConnectedPan(value: number) {
3737
return cubicBezier(0.1, 0.0, 0.2, 1.0, value);
3838
}
3939

40-
const DEFAULT_ZOOM_OUT_MS = TRANSITION_WINDOW_MS;
41-
const DEFAULT_ZOOM_IN_MS = ZOOM_IN_TRANSITION_WINDOW_MS;
42-
43-
function getDurations(region: ZoomRegion) {
40+
export const DEFAULT_ZOOM_OUT_MS = TRANSITION_WINDOW_MS;
41+
export const DEFAULT_ZOOM_IN_MS = ZOOM_IN_TRANSITION_WINDOW_MS;
42+
43+
export function getDurations(region: {
44+
startMs: number;
45+
endMs: number;
46+
zoomInDurationMs?: number;
47+
zoomOutDurationMs?: number;
48+
}) {
4449
let zoomIn = region.zoomInDurationMs ?? DEFAULT_ZOOM_IN_MS;
4550
let zoomOut = region.zoomOutDurationMs ?? DEFAULT_ZOOM_OUT_MS;
4651

0 commit comments

Comments
 (0)