diff --git a/apps/web/src/components/editor/panels/timeline/graph-editor/bezier-graph.tsx b/apps/web/src/components/editor/panels/timeline/graph-editor/bezier-graph.tsx index f607dc7a..3f78350b 100644 --- a/apps/web/src/components/editor/panels/timeline/graph-editor/bezier-graph.tsx +++ b/apps/web/src/components/editor/panels/timeline/graph-editor/bezier-graph.tsx @@ -62,9 +62,9 @@ function curvePath({ curve }: { curve: NormalizedCubicBezier }) { const points: string[] = []; for (let i = 0; i <= CURVE_SEGMENTS; i++) { const progress = i / CURVE_SEGMENTS; - points.push( - `${toSvgX({ value: getBezierPoint({ progress, p0: 0, p1: curve[0], p2: curve[2], p3: 1 }) })},${toSvgY({ value: getBezierPoint({ progress, p0: 0, p1: curve[1], p2: curve[3], p3: 1 }) })}`, - ); + const x = toSvgX({ value: getBezierPoint({ progress, p0: 0, p1: curve[0], p2: curve[2], p3: 1 }) }); + const y = toSvgY({ value: getBezierPoint({ progress, p0: 0, p1: curve[1], p2: curve[3], p3: 1 }) }); + points.push(`${x},${y}`); } return `M${points.join("L")}`; } diff --git a/apps/web/src/components/editor/panels/timeline/graph-editor/popover.tsx b/apps/web/src/components/editor/panels/timeline/graph-editor/popover.tsx index 00348a60..733195ed 100644 --- a/apps/web/src/components/editor/panels/timeline/graph-editor/popover.tsx +++ b/apps/web/src/components/editor/panels/timeline/graph-editor/popover.tsx @@ -299,13 +299,21 @@ function PresetItem({ ); } +function toThumbX({ value }: { value: number }) { + return THUMB_PADDING_X + value * (THUMB_WIDTH - THUMB_PADDING_X * 2); +} + +function toThumbY({ value }: { value: number }) { + return THUMB_PADDING_Y + (1 - value) * (THUMB_HEIGHT - THUMB_PADDING_Y * 2); +} + function CurveThumb({ value }: { value: NormalizedCubicBezier }) { const points: string[] = []; for (let i = 0; i <= THUMB_SEGMENTS; i++) { const progress = i / THUMB_SEGMENTS; - points.push( - `${THUMB_PADDING_X + getBezierPoint({ progress, p0: 0, p1: value[0], p2: value[2], p3: 1 }) * (THUMB_WIDTH - THUMB_PADDING_X * 2)},${THUMB_PADDING_Y + (1 - getBezierPoint({ progress, p0: 0, p1: value[1], p2: value[3], p3: 1 })) * (THUMB_HEIGHT - THUMB_PADDING_Y * 2)}`, - ); + const x = toThumbX({ value: getBezierPoint({ progress, p0: 0, p1: value[0], p2: value[2], p3: 1 }) }); + const y = toThumbY({ value: getBezierPoint({ progress, p0: 0, p1: value[1], p2: value[3], p3: 1 }) }); + points.push(`${x},${y}`); } return ( { + if (state.status !== "ready") { + return; + } - const nextAnimations = applyGraphEditorCurvePreview({ - animations: state.element.animations, - context: state.context, - cubicBezier: nextValue, - }); - editor.timeline.previewElements({ - updates: [ - { + const nextAnimations = applyGraphEditorCurvePreview({ + animations: state.element.animations, + context: state.context, + cubicBezier: nextValue, + }); + editor.timeline.previewElements({ + updates: [ + { + trackId: state.trackId, + elementId: state.elementId, + updates: { + animations: nextAnimations, + }, + }, + ], + }); + hasPreviewRef.current = true; + }, + [editor, state], + ); + + const handleCommitValue = useCallback( + (nextValue: NormalizedCubicBezier) => { + if (state.status !== "ready") { + return; + } + + const patches = buildGraphEditorCurvePatches({ + context: state.context, + cubicBezier: nextValue, + }); + if (!patches) { + return; + } + + editor.timeline.updateKeyframeCurves({ + keyframes: patches.map(({ keyframeId, patch }) => ({ trackId: state.trackId, elementId: state.elementId, - updates: { - animations: nextAnimations, - }, - }, - ], - }); - hasPreviewRef.current = true; - } - - function handleCommitValue(nextValue: NormalizedCubicBezier) { - if (state.status !== "ready") { - return; - } - - const patches = buildGraphEditorCurvePatches({ - context: state.context, - cubicBezier: nextValue, - }); - if (!patches) { - return; - } - - editor.timeline.updateKeyframeCurves({ - keyframes: patches.map(({ keyframeId, patch }) => ({ - trackId: state.trackId, - elementId: state.elementId, - propertyPath: state.propertyPath, - componentKey: state.context.componentKey, - keyframeId, - patch, - })), - }); - hasPreviewRef.current = false; - } + propertyPath: state.propertyPath, + componentKey: state.context.componentKey, + keyframeId, + patch, + })), + }); + hasPreviewRef.current = false; + }, + [editor, state], + ); return { open,