From 01266dcdffa3da109ef7745795f018a79320b286 Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Wed, 28 Feb 2024 11:46:43 +0100 Subject: [PATCH 01/18] initial changes --- src/App.tsx | 224 ++++++++++++++++++++++++----------------- src/CanvasWrapper.tsx | 10 +- src/Sidebar.tsx | 135 +++++++------------------ src/SpringControls.tsx | 117 +++++++++++++++++++++ 4 files changed, 297 insertions(+), 189 deletions(-) create mode 100644 src/SpringControls.tsx diff --git a/src/App.tsx b/src/App.tsx index 8743bf7..951eb96 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -16,116 +16,167 @@ export type DraggedConfig = SpringConfig & { }; function App() { - const [config, setConfig] = useState< - SpringConfig & { - reverse: boolean; - durationInFrames: number | null; - delay: number; - } - >({ - damping: DEFAULT_DAMPING, - mass: DEFAULT_MASS, - stiffness: DEFAULT_STIFFNESS, - overshootClamping: false, - reverse: false, - durationInFrames: null, - delay: 0, - }); - - const [draggedConfig, setDraggedConfig] = useState( - null - ); + const [springConfigs, setSpringConfigs] = useState([ + { + damping: DEFAULT_DAMPING, + mass: DEFAULT_MASS, + stiffness: DEFAULT_STIFFNESS, + overshootClamping: false, + reverse: false, + durationInFrames: null, + delay: 0, + }, + ]); + + const [draggedConfigs, setDraggedConfigs] = useState< + (DraggedConfig | null)[] + >([ + { + damping: DEFAULT_DAMPING, + mass: DEFAULT_MASS, + stiffness: DEFAULT_STIFFNESS, + overshootClamping: false, + reverse: false, + durationInFrames: null, + delay: 0, + }, + ]); const onMassChange = useCallback( - (e: [number]) => { - setDraggedConfig({ ...config, mass: e[0] }); + (e: [number], index: number) => { + setDraggedConfigs([ + ...springConfigs.slice(0, index), + { ...springConfigs[index], mass: e[0] }, + ...springConfigs.slice(index + 1), + ]); }, - [config] + [springConfigs] ); const onDampingChange = useCallback( - (e: number[]) => { - setDraggedConfig({ ...config, damping: e[0] }); + (e: number[], index: number) => { + setDraggedConfigs([ + ...springConfigs.slice(0, index), + { ...springConfigs[index], damping: e[0] }, + ...springConfigs.slice(index + 1), + ]); }, - [config] + [springConfigs] ); const onStiffnessChange = useCallback( - (e: number[]) => { - setDraggedConfig({ ...config, stiffness: e[0] }); + (e: number[], index: number) => { + setDraggedConfigs([ + ...springConfigs.slice(0, index), + { ...springConfigs[index], stiffness: e[0] }, + ...springConfigs.slice(index + 1), + ]); }, - [config] + [springConfigs] ); const onDurationInFramesChange = useCallback( - (e: number | null) => { - setDraggedConfig({ ...config, durationInFrames: e }); - setConfig({ ...config, durationInFrames: e }); + (e: number | null, index: number) => { + setDraggedConfigs([ + ...springConfigs.slice(0, index), + { ...springConfigs[index], durationInFrames: e }, + ...springConfigs.slice(index + 1), + ]); + setSpringConfigs([ + ...springConfigs.slice(0, index), + { ...springConfigs[index], durationInFrames: e }, + ...springConfigs.slice(index + 1), + ]); }, - [config] + [springConfigs] ); const onDelayChange = useCallback( - (e: number) => { - setDraggedConfig({ ...config, delay: e }); - setConfig({ ...config, delay: e }); + (e: number, index: number) => { + setDraggedConfigs([ + ...springConfigs.slice(0, index), + { ...springConfigs[index], delay: e }, + ...springConfigs.slice(index + 1), + ]); + setSpringConfigs([ + ...springConfigs.slice(0, index), + { ...springConfigs[index], delay: e }, + ...springConfigs.slice(index + 1), + ]); }, - [config] + [springConfigs] ); const onOvershootClampingChange = useCallback( - (checked: boolean) => { - setDraggedConfig({ - ...config, - overshootClamping: checked, - }); - setConfig({ - ...config, - overshootClamping: checked, - }); + (checked: boolean, index: number) => { + setDraggedConfigs([ + ...springConfigs.slice(0, index), + { ...springConfigs[index], overshootClamping: checked }, + ...springConfigs.slice(index + 1), + ]); + setSpringConfigs([ + ...springConfigs.slice(0, index), + { ...springConfigs[index], overshootClamping: checked }, + ...springConfigs.slice(index + 1), + ]); }, - [config] + [springConfigs] ); const onReverseChange = useCallback( - (checked: boolean) => { - setDraggedConfig({ - ...config, - reverse: checked, - }); - setConfig({ - ...config, - reverse: checked, - }); + (checked: boolean, index: number) => { + setDraggedConfigs([ + ...springConfigs.slice(0, index), + { ...springConfigs[index], reverse: checked }, + ...springConfigs.slice(index + 1), + ]); + setSpringConfigs([ + ...springConfigs.slice(0, index), + { ...springConfigs[index], reverse: checked }, + ...springConfigs.slice(index + 1), + ]); + }, + [springConfigs] + ); + + const onRelease = useCallback( + (index: number) => { + if (draggedConfigs[index]) { + setSpringConfigs([ + ...springConfigs.slice(0, index), + draggedConfigs[index] as DraggedConfig, + ...springConfigs.slice(index + 1), + ]); + } + setDraggedConfigs([ + ...draggedConfigs.slice(0, index), + null, + ...draggedConfigs.slice(index + 1), + ]); }, - [config] + [draggedConfigs, springConfigs] ); - const onRelease = useCallback(() => { - if (draggedConfig) { - setConfig(draggedConfig as DraggedConfig); + const duration = springConfigs.reduce((max, config) => { + const calculatedDuration = + config.delay + + (config.durationInFrames + ? config.durationInFrames + : measureSpring({ fps, threshold: 0.001, config })); + return calculatedDuration > max ? calculatedDuration : max; + }, 0); + + const draggedDuration = draggedConfigs.reduce((max, draggedConfig) => { + if (!draggedConfig) { + return max; } - setDraggedConfig(null); - }, [draggedConfig]); - - const duration = - config.delay + - (config.durationInFrames - ? config.durationInFrames - : measureSpring({ - fps, - threshold: 0.001, - config, - })); - const draggedDuration = draggedConfig - ? draggedConfig.durationInFrames - ? draggedConfig.durationInFrames + draggedConfig.delay - : measureSpring({ - fps, - threshold: 0.001, - config: draggedConfig, - }) + draggedConfig.delay - : null; + const calculatedDuration = + draggedConfig.delay + + (draggedConfig.durationInFrames + ? draggedConfig.durationInFrames + : measureSpring({ fps, threshold: 0.001, config: draggedConfig })); + return calculatedDuration > max ? calculatedDuration : max; + }, 0); return (
0 ? draggedDuration : null} duration={duration} fps={fps} /> @@ -166,16 +217,9 @@ function App() {
= ({ config, draggedConfig, draggedDuration, duration, fps }) => { +}> = ({ springConfigs, draggedConfigs, draggedDuration, duration, fps }) => { const outer = useRef(null); const elementSize = PlayerInternals.useElementSize(outer, { @@ -17,6 +17,10 @@ export const CanvasWrapper: React.FC<{ triggerOnWindowResize: true, }); + const addedConfigs = springConfigs.reduce( + (accumulated, currentConfig) => accumulated + currentConfig + ); + return (
void; + onMassChange: (e: [number], index: number) => void; onDampingChange: (e: [number]) => void; onStiffnessChange: (e: [number]) => void; onDurationInFramesChange: (e: number | null) => void; onDelayChange: (e: number) => void; - overshootClamping: boolean; onRelease: () => void; onOvershootClampingChange: (checked: boolean) => void; - reverse: boolean; onReverseChange: (checked: boolean) => void; }> = ({ - mass, + springConfigs, + draggedConfigs, onDampingChange, onMassChange, onStiffnessChange, onDurationInFramesChange, - fixedDurationInFrames, - overshootClamping, onRelease, - damping, - stiffness, calculatedDurationInFrames, onOvershootClampingChange, onReverseChange, - reverse, - delay, onDelayChange, }) => { return ( @@ -59,86 +46,42 @@ export const Sidebar: React.FC<{ Code - - - - - - - - { - onDelayChange(val[0]); - }} - onPointerUp={onRelease} - /> - - <> - { - onDurationInFramesChange(val[0]); - }} - onPointerUp={onRelease} - /> - { - if (enabled) { - onDurationInFramesChange(calculatedDurationInFrames); - } else { - onDurationInFramesChange(null); + {springConfigs.map((config, idx) => { + return ( + - - - - + reverse={config.reverse} + delay={draggedConfigs[idx]?.delay ?? config.delay} + calculatedDurationInFrames={calculatedDurationInFrames} + onMassChange={onMassChange} + onDampingChange={onDampingChange} + onDelayChange={onDelayChange} + onDurationInFramesChange={onDurationInFramesChange} + onStiffnessChange={onStiffnessChange} + onRelease={onRelease} + onOvershootClampingChange={onOvershootClampingChange} + onReverseChange={onReverseChange} + /> + ); + })} diff --git a/src/SpringControls.tsx b/src/SpringControls.tsx new file mode 100644 index 0000000..0fead46 --- /dev/null +++ b/src/SpringControls.tsx @@ -0,0 +1,117 @@ +import { Slider } from "@radix-ui/react-slider"; +import { Spacing } from "./Spacing"; +import { SliderLabel } from "./SliderLabel"; +import { CheckboxWithLabel } from "./Checkbox"; + +export const SpringControls: React.FC<{ + mass: number; + stiffness: number; + delay: number; + damping: number; + overshootClamping: boolean; + reverse: boolean; + onMassChange: (e: [number], index: number) => void; + onDampingChange: (e: [number]) => void; + onStiffnessChange: (e: [number]) => void; + onDurationInFramesChange: (e: number | null) => void; + onDelayChange: (e: number) => void; + onRelease: () => void; + onOvershootClampingChange: (checked: boolean) => void; + onReverseChange: (checked: boolean) => void; + fixedDurationInFrames: number | null; + calculatedDurationInFrames: number; + index: number; +}> = ({ + mass, + damping, + stiffness, + delay, + overshootClamping, + reverse, + onDampingChange, + onMassChange, + onStiffnessChange, + onDurationInFramesChange, + onRelease, + onOvershootClampingChange, + onReverseChange, + onDelayChange, + calculatedDurationInFrames, + fixedDurationInFrames, + index, +}) => { + return ( + <> + + onMassChange([mass], index)} // CHANGE 0 TO IDX + onPointerUp={onRelease} + /> + + + + + + { + onDelayChange(val[0]); + }} + onPointerUp={onRelease} + /> + + <> + { + onDurationInFramesChange(val[0]); + }} + onPointerUp={onRelease} + /> + { + if (enabled) { + onDurationInFramesChange(calculatedDurationInFrames); + } else { + onDurationInFramesChange(null); + } + }} + value={fixedDurationInFrames ?? null} + /> + + + + + + ); +}; From fe5c0821f4fec35b85f0031f96266d92868f246c Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Wed, 28 Feb 2024 15:06:41 +0100 Subject: [PATCH 02/18] basic working --- src/App.tsx | 120 ++++++++++++++++++----------------------- src/Canvas.tsx | 8 +-- src/CanvasWrapper.tsx | 10 ++-- src/Sidebar.tsx | 30 +++++------ src/SpringControls.tsx | 46 ++++++++-------- src/draw.tsx | 9 ++-- src/get-trajectory.ts | 20 ++++--- 7 files changed, 112 insertions(+), 131 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 951eb96..d934c4d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -26,11 +26,6 @@ function App() { durationInFrames: null, delay: 0, }, - ]); - - const [draggedConfigs, setDraggedConfigs] = useState< - (DraggedConfig | null)[] - >([ { damping: DEFAULT_DAMPING, mass: DEFAULT_MASS, @@ -42,62 +37,55 @@ function App() { }, ]); + const [draggedConfig, setDraggedConfig] = useState( + null + ); + const onMassChange = useCallback( - (e: [number], index: number) => { - setDraggedConfigs([ - ...springConfigs.slice(0, index), - { ...springConfigs[index], mass: e[0] }, - ...springConfigs.slice(index + 1), - ]); + (e: number[], index: number) => { + setDraggedConfig({ + ...springConfigs[index], + mass: e[0], + }); }, [springConfigs] ); - const onDampingChange = useCallback( (e: number[], index: number) => { - setDraggedConfigs([ - ...springConfigs.slice(0, index), - { ...springConfigs[index], damping: e[0] }, - ...springConfigs.slice(index + 1), - ]); + setDraggedConfig({ + ...springConfigs[index], + damping: e[0], + }); }, [springConfigs] ); const onStiffnessChange = useCallback( (e: number[], index: number) => { - setDraggedConfigs([ - ...springConfigs.slice(0, index), - { ...springConfigs[index], stiffness: e[0] }, - ...springConfigs.slice(index + 1), - ]); + setDraggedConfig({ + ...springConfigs[index], + stiffness: e[0], + }); }, [springConfigs] ); const onDurationInFramesChange = useCallback( (e: number | null, index: number) => { - setDraggedConfigs([ - ...springConfigs.slice(0, index), - { ...springConfigs[index], durationInFrames: e }, - ...springConfigs.slice(index + 1), - ]); - setSpringConfigs([ - ...springConfigs.slice(0, index), - { ...springConfigs[index], durationInFrames: e }, - ...springConfigs.slice(index + 1), - ]); + setDraggedConfig({ + ...springConfigs[index], + durationInFrames: e, + }); }, [springConfigs] ); const onDelayChange = useCallback( (e: number, index: number) => { - setDraggedConfigs([ - ...springConfigs.slice(0, index), - { ...springConfigs[index], delay: e }, - ...springConfigs.slice(index + 1), - ]); + setDraggedConfig({ + ...springConfigs[index], + delay: e, + }); setSpringConfigs([ ...springConfigs.slice(0, index), { ...springConfigs[index], delay: e }, @@ -109,11 +97,10 @@ function App() { const onOvershootClampingChange = useCallback( (checked: boolean, index: number) => { - setDraggedConfigs([ - ...springConfigs.slice(0, index), - { ...springConfigs[index], overshootClamping: checked }, - ...springConfigs.slice(index + 1), - ]); + setDraggedConfig({ + ...springConfigs[index], + overshootClamping: checked, + }); setSpringConfigs([ ...springConfigs.slice(0, index), { ...springConfigs[index], overshootClamping: checked }, @@ -125,11 +112,10 @@ function App() { const onReverseChange = useCallback( (checked: boolean, index: number) => { - setDraggedConfigs([ - ...springConfigs.slice(0, index), - { ...springConfigs[index], reverse: checked }, - ...springConfigs.slice(index + 1), - ]); + setDraggedConfig({ + ...springConfigs[index], + reverse: checked, + }); setSpringConfigs([ ...springConfigs.slice(0, index), { ...springConfigs[index], reverse: checked }, @@ -141,20 +127,16 @@ function App() { const onRelease = useCallback( (index: number) => { - if (draggedConfigs[index]) { + if (draggedConfig) { setSpringConfigs([ ...springConfigs.slice(0, index), - draggedConfigs[index] as DraggedConfig, + draggedConfig as DraggedConfig, ...springConfigs.slice(index + 1), ]); } - setDraggedConfigs([ - ...draggedConfigs.slice(0, index), - null, - ...draggedConfigs.slice(index + 1), - ]); + setDraggedConfig(null); }, - [draggedConfigs, springConfigs] + [draggedConfig, springConfigs] ); const duration = springConfigs.reduce((max, config) => { @@ -166,17 +148,15 @@ function App() { return calculatedDuration > max ? calculatedDuration : max; }, 0); - const draggedDuration = draggedConfigs.reduce((max, draggedConfig) => { - if (!draggedConfig) { - return max; - } - const calculatedDuration = - draggedConfig.delay + - (draggedConfig.durationInFrames - ? draggedConfig.durationInFrames - : measureSpring({ fps, threshold: 0.001, config: draggedConfig })); - return calculatedDuration > max ? calculatedDuration : max; - }, 0); + const draggedDuration = draggedConfig + ? draggedConfig.durationInFrames + ? draggedConfig.durationInFrames + draggedConfig.delay + : measureSpring({ + fps, + threshold: 0.001, + config: draggedConfig, + }) + draggedConfig.delay + : null; return (
0 ? draggedDuration : null} + draggedDuration={ + draggedDuration && draggedDuration > 0 ? draggedDuration : null + } duration={duration} fps={fps} /> @@ -218,7 +200,7 @@ function App() {
= ({ height, width, draggedConfig, draggedDuration, - config, + springConfigs, duration, fps, }) => { @@ -48,7 +48,7 @@ export const Canvas: React.FC<{ draw({ ref: canvasRef.current, duration: draggedDuration ?? duration, - config, + springConfigs, draggedConfig, fps, draggedDuration, @@ -59,12 +59,12 @@ export const Canvas: React.FC<{ }, [ draggedDuration, duration, - config, draggedConfig, fps, width, height, durationLabel, + springConfigs, ]); return ( diff --git a/src/CanvasWrapper.tsx b/src/CanvasWrapper.tsx index 6a098f1..a284071 100644 --- a/src/CanvasWrapper.tsx +++ b/src/CanvasWrapper.tsx @@ -4,12 +4,12 @@ import { Canvas } from "./Canvas"; import { DraggedConfig } from "./App"; export const CanvasWrapper: React.FC<{ - draggedConfigs: (DraggedConfig | null)[]; + draggedConfig: DraggedConfig | null; draggedDuration: number | null; duration: number; springConfigs: DraggedConfig[]; fps: number; -}> = ({ springConfigs, draggedConfigs, draggedDuration, duration, fps }) => { +}> = ({ springConfigs, draggedConfig, draggedDuration, duration, fps }) => { const outer = useRef(null); const elementSize = PlayerInternals.useElementSize(outer, { @@ -17,10 +17,6 @@ export const CanvasWrapper: React.FC<{ triggerOnWindowResize: true, }); - const addedConfigs = springConfigs.reduce( - (accumulated, currentConfig) => accumulated + currentConfig - ); - return (
{elementSize ? ( void; - onDampingChange: (e: [number]) => void; - onStiffnessChange: (e: [number]) => void; - onDurationInFramesChange: (e: number | null) => void; - onDelayChange: (e: number) => void; - onRelease: () => void; - onOvershootClampingChange: (checked: boolean) => void; - onReverseChange: (checked: boolean) => void; + onDampingChange: (e: [number], index: number) => void; + onStiffnessChange: (e: [number], index: number) => void; + onDurationInFramesChange: (e: number | null, index: number) => void; + onDelayChange: (e: number, index: number) => void; + onRelease: (index: number) => void; + onOvershootClampingChange: (checked: boolean, index: number) => void; + onReverseChange: (checked: boolean, index: number) => void; }> = ({ springConfigs, - draggedConfigs, + draggedConfig, onDampingChange, onMassChange, onStiffnessChange, @@ -49,17 +49,17 @@ export const Sidebar: React.FC<{ {springConfigs.map((config, idx) => { return ( void; - onDampingChange: (e: [number]) => void; - onStiffnessChange: (e: [number]) => void; - onDurationInFramesChange: (e: number | null) => void; - onDelayChange: (e: number) => void; - onRelease: () => void; - onOvershootClampingChange: (checked: boolean) => void; - onReverseChange: (checked: boolean) => void; + onMassChange: (e: number[], index: number) => void; + onDampingChange: (e: number[], index: number) => void; + onStiffnessChange: (e: number[], index: number) => void; + onDurationInFramesChange: (e: number | null, index: number) => void; + onDelayChange: (e: number, index: number) => void; + onRelease: (index: number) => void; + onOvershootClampingChange: (checked: boolean, index: number) => void; + onReverseChange: (checked: boolean, index: number) => void; fixedDurationInFrames: number | null; calculatedDurationInFrames: number; index: number; @@ -48,24 +48,24 @@ export const SpringControls: React.FC<{ min={0.3} step={0.1} max={10} - onValueChange={() => onMassChange([mass], index)} // CHANGE 0 TO IDX - onPointerUp={onRelease} + onValueChange={(e) => onMassChange(e, index)} + onPointerUp={() => onRelease(index)} /> onDampingChange(e, index)} + onPointerUp={() => onRelease(index)} /> onStiffnessChange(e, index)} + onPointerUp={() => onRelease(index)} /> { - onDelayChange(val[0]); + onDelayChange(val[0], index); }} - onPointerUp={onRelease} + onPointerUp={() => onRelease(index)} /> <> @@ -85,17 +85,17 @@ export const SpringControls: React.FC<{ value={[fixedDurationInFrames ?? calculatedDurationInFrames]} style={{ opacity: fixedDurationInFrames === null ? 0.5 : 1 }} onValueChange={(val) => { - onDurationInFramesChange(val[0]); + onDurationInFramesChange(val[0], index); }} - onPointerUp={onRelease} + onPointerUp={() => onRelease(index)} /> { if (enabled) { - onDurationInFramesChange(calculatedDurationInFrames); + onDurationInFramesChange(calculatedDurationInFrames, index); } else { - onDurationInFramesChange(null); + onDurationInFramesChange(null, index); } }} value={fixedDurationInFrames ?? null} @@ -104,12 +104,12 @@ export const SpringControls: React.FC<{ onOvershootClampingChange(e, index)} /> onReverseChange(e, index)} /> diff --git a/src/draw.tsx b/src/draw.tsx index 53624c1..0b98faf 100644 --- a/src/draw.tsx +++ b/src/draw.tsx @@ -16,7 +16,7 @@ export const draw = ({ ref, duration, fps, - config, + springConfigs, draggedConfig, draggedDuration, height, @@ -26,7 +26,7 @@ export const draw = ({ ref: HTMLCanvasElement; duration: number; fps: number; - config: DraggedConfig; + springConfigs: DraggedConfig[]; draggedConfig: DraggedConfig | null; draggedDuration: number | null; width: number; @@ -38,11 +38,10 @@ export const draw = ({ if (!context) { return; } - context.clearRect(0, 0, width, height); - const trajectory = getTrajectory(duration, fps, config); + const trajectory = getTrajectory(duration, fps, springConfigs); const draggedTrajectory = draggedConfig - ? getTrajectory(draggedDuration ?? duration, fps, draggedConfig) + ? getTrajectory(draggedDuration ?? duration, fps, [draggedConfig]) : []; const max = draggedConfig diff --git a/src/get-trajectory.ts b/src/get-trajectory.ts index fc2b038..b98fdf0 100644 --- a/src/get-trajectory.ts +++ b/src/get-trajectory.ts @@ -4,16 +4,20 @@ import { DraggedConfig } from "./App"; export const getTrajectory = ( durationInFrames: number, fps: number, - { reverse, ...config }: DraggedConfig + springConfigs: DraggedConfig[] ) => { return new Array(durationInFrames).fill(true).map((_, i) => { - return spring({ - fps, - frame: i, - config, - reverse, - durationInFrames: config.durationInFrames ?? undefined, - delay: config.delay ?? undefined, + let totalValue = 0; + springConfigs.forEach((config) => { + totalValue += spring({ + fps, + frame: i, + config, + reverse: config.reverse, + durationInFrames: config.durationInFrames ?? undefined, + delay: config.delay ?? undefined, + }); }); + return totalValue; }); }; From 4ec9a03191ed1f88828aed0b55e392fa5c505b7f Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Wed, 28 Feb 2024 17:33:40 +0100 Subject: [PATCH 03/18] displays again --- src/App.tsx | 159 +++++++++++++++++++++++++---------------- src/Canvas.tsx | 9 +-- src/CanvasWrapper.tsx | 8 +-- src/Sidebar.tsx | 21 +++--- src/SpringControls.tsx | 1 + src/draw-trajectory.ts | 2 + src/draw.tsx | 28 +++++--- src/get-trajectory.ts | 5 +- 8 files changed, 143 insertions(+), 90 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index d934c4d..62adb00 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -24,6 +24,7 @@ function App() { overshootClamping: false, reverse: false, durationInFrames: null, + delay: 0, }, { @@ -37,59 +38,79 @@ function App() { }, ]); - const [draggedConfig, setDraggedConfig] = useState( - null - ); + const [draggedConfigs, setDraggedConfigs] = useState< + (DraggedConfig | null)[] + >(Array(springConfigs.length).fill(null)); const onMassChange = useCallback( (e: number[], index: number) => { - setDraggedConfig({ - ...springConfigs[index], - mass: e[0], - }); + setDraggedConfigs((old) => [ + ...old.slice(0, index), + { + ...springConfigs[index], + mass: e[0], + }, + ...old.slice(index + 1), + ]); }, [springConfigs] ); const onDampingChange = useCallback( (e: number[], index: number) => { - setDraggedConfig({ - ...springConfigs[index], - damping: e[0], - }); + setDraggedConfigs((old) => [ + ...old.slice(0, index), + { + ...springConfigs[index], + damping: e[0], + }, + ...old.slice(index + 1), + ]); }, [springConfigs] ); const onStiffnessChange = useCallback( (e: number[], index: number) => { - setDraggedConfig({ - ...springConfigs[index], - stiffness: e[0], - }); + setDraggedConfigs((old) => [ + ...old.slice(0, index), + { + ...springConfigs[index], + stiffness: e[0], + }, + ...old.slice(index + 1), + ]); }, [springConfigs] ); const onDurationInFramesChange = useCallback( (e: number | null, index: number) => { - setDraggedConfig({ - ...springConfigs[index], - durationInFrames: e, - }); + setDraggedConfigs((old) => [ + ...old.slice(0, index), + { + ...springConfigs[index], + durationInFrames: e, + }, + ...old.slice(index + 1), + ]); }, [springConfigs] ); const onDelayChange = useCallback( (e: number, index: number) => { - setDraggedConfig({ - ...springConfigs[index], - delay: e, - }); - setSpringConfigs([ - ...springConfigs.slice(0, index), - { ...springConfigs[index], delay: e }, - ...springConfigs.slice(index + 1), + setDraggedConfigs((old) => [ + ...old.slice(0, index), + { + ...springConfigs[index], + delay: e, + }, + ...old.slice(index + 1), + ]); + setSpringConfigs((old) => [ + ...old.slice(0, index), + { ...old[index], delay: e }, + ...old.slice(index + 1), ]); }, [springConfigs] @@ -97,14 +118,18 @@ function App() { const onOvershootClampingChange = useCallback( (checked: boolean, index: number) => { - setDraggedConfig({ - ...springConfigs[index], - overshootClamping: checked, - }); - setSpringConfigs([ - ...springConfigs.slice(0, index), - { ...springConfigs[index], overshootClamping: checked }, - ...springConfigs.slice(index + 1), + setDraggedConfigs((old) => [ + ...old.slice(0, index), + { + ...springConfigs[index], + overshootClamping: checked, + }, + ...old.slice(index + 1), + ]); + setSpringConfigs((old) => [ + ...old.slice(0, index), + { ...old[index], overshootClamping: checked }, + ...old.slice(index + 1), ]); }, [springConfigs] @@ -112,14 +137,18 @@ function App() { const onReverseChange = useCallback( (checked: boolean, index: number) => { - setDraggedConfig({ - ...springConfigs[index], - reverse: checked, - }); - setSpringConfigs([ - ...springConfigs.slice(0, index), - { ...springConfigs[index], reverse: checked }, - ...springConfigs.slice(index + 1), + setDraggedConfigs((old) => [ + ...old.slice(0, index), + { + ...springConfigs[index], + reverse: checked, + }, + ...old.slice(index + 1), + ]); + setSpringConfigs((old) => [ + ...old.slice(0, index), + { ...old[index], reverse: checked }, + ...old.slice(index + 1), ]); }, [springConfigs] @@ -127,16 +156,20 @@ function App() { const onRelease = useCallback( (index: number) => { - if (draggedConfig) { - setSpringConfigs([ - ...springConfigs.slice(0, index), - draggedConfig as DraggedConfig, - ...springConfigs.slice(index + 1), + if (draggedConfigs && draggedConfigs[index]) { + setSpringConfigs((old) => [ + ...old.slice(0, index), + draggedConfigs[index] as DraggedConfig, + ...old.slice(index + 1), ]); } - setDraggedConfig(null); + setDraggedConfigs((old) => [ + ...old.slice(0, index), + null, + ...old.slice(index + 1), + ]); }, - [draggedConfig, springConfigs] + [draggedConfigs] ); const duration = springConfigs.reduce((max, config) => { @@ -148,16 +181,20 @@ function App() { return calculatedDuration > max ? calculatedDuration : max; }, 0); - const draggedDuration = draggedConfig - ? draggedConfig.durationInFrames - ? draggedConfig.durationInFrames + draggedConfig.delay - : measureSpring({ - fps, - threshold: 0.001, - config: draggedConfig, - }) + draggedConfig.delay + const draggedDuration = draggedConfigs.some((config) => config !== null) + ? draggedConfigs.reduce((max, draggedConfig) => { + if (draggedConfig === null) { + return max; + } + const calculatedDuration = + draggedConfig.delay + + (draggedConfig.durationInFrames + ? draggedConfig.durationInFrames + : measureSpring({ fps, threshold: 0.001, config: draggedConfig })); + return calculatedDuration > max ? calculatedDuration : max; + }, 0) : null; - + console.log("duration:", duration); return (
0 ? draggedDuration : null } @@ -200,7 +237,7 @@ function App() {
(); export const Canvas: React.FC<{ width: number; height: number; - draggedConfig: DraggedConfig | null; + draggedConfigs: (DraggedConfig | null)[]; draggedDuration: number | null; duration: number; springConfigs: DraggedConfig[]; @@ -16,7 +16,7 @@ export const Canvas: React.FC<{ }> = ({ height, width, - draggedConfig, + draggedConfigs, draggedDuration, springConfigs, duration, @@ -33,6 +33,7 @@ export const Canvas: React.FC<{ const [durationType, setDurationType] = React.useState<"seconds" | "frames">( "seconds" ); + console.log("draggedDuration: ", draggedDuration, "duration: ", duration); const durationLabel = durationType === "seconds" @@ -49,7 +50,7 @@ export const Canvas: React.FC<{ ref: canvasRef.current, duration: draggedDuration ?? duration, springConfigs, - draggedConfig, + draggedConfigs, fps, draggedDuration, height, @@ -59,7 +60,7 @@ export const Canvas: React.FC<{ }, [ draggedDuration, duration, - draggedConfig, + draggedConfigs, fps, width, height, diff --git a/src/CanvasWrapper.tsx b/src/CanvasWrapper.tsx index a284071..9c7f5b1 100644 --- a/src/CanvasWrapper.tsx +++ b/src/CanvasWrapper.tsx @@ -4,14 +4,14 @@ import { Canvas } from "./Canvas"; import { DraggedConfig } from "./App"; export const CanvasWrapper: React.FC<{ - draggedConfig: DraggedConfig | null; + draggedConfigs: (DraggedConfig | null)[]; draggedDuration: number | null; duration: number; springConfigs: DraggedConfig[]; fps: number; -}> = ({ springConfigs, draggedConfig, draggedDuration, duration, fps }) => { +}> = ({ springConfigs, draggedConfigs, draggedDuration, duration, fps }) => { const outer = useRef(null); - + console.log("duration: ", duration, "draggedDuration: ", draggedDuration); const elementSize = PlayerInternals.useElementSize(outer, { shouldApplyCssTransforms: false, triggerOnWindowResize: true, @@ -31,7 +31,7 @@ export const CanvasWrapper: React.FC<{ {elementSize ? ( void; - onDampingChange: (e: [number], index: number) => void; - onStiffnessChange: (e: [number], index: number) => void; + onMassChange: (e: number[], index: number) => void; + onDampingChange: (e: number[], index: number) => void; + onStiffnessChange: (e: number[], index: number) => void; onDurationInFramesChange: (e: number | null, index: number) => void; onDelayChange: (e: number, index: number) => void; onRelease: (index: number) => void; @@ -19,7 +19,7 @@ export const Sidebar: React.FC<{ onReverseChange: (checked: boolean, index: number) => void; }> = ({ springConfigs, - draggedConfig, + draggedConfigs, onDampingChange, onMassChange, onStiffnessChange, @@ -50,16 +50,17 @@ export const Sidebar: React.FC<{ return ( { + console.log(index); return ( <> diff --git a/src/draw-trajectory.ts b/src/draw-trajectory.ts index b3b219b..aeb8491 100644 --- a/src/draw-trajectory.ts +++ b/src/draw-trajectory.ts @@ -49,6 +49,8 @@ export const drawTrajectory = ({ animate: boolean; fps: number; }) => { + console.log("animate: ", animate); + console.log("primary: ", primary); const intervalBetweenDraw = 1000 / fps; const segmentWidth = (canvasWidth - PADDING_LEFT - PADDING_RIGHT) / diff --git a/src/draw.tsx b/src/draw.tsx index 0b98faf..32dab09 100644 --- a/src/draw.tsx +++ b/src/draw.tsx @@ -17,7 +17,7 @@ export const draw = ({ duration, fps, springConfigs, - draggedConfig, + draggedConfigs, draggedDuration, height, width, @@ -27,24 +27,31 @@ export const draw = ({ duration: number; fps: number; springConfigs: DraggedConfig[]; - draggedConfig: DraggedConfig | null; + draggedConfigs: (DraggedConfig | null)[]; draggedDuration: number | null; width: number; height: number; labelText: string; }) => { const context = ref.getContext("2d"); - if (!context) { return; } context.clearRect(0, 0, width, height); const trajectory = getTrajectory(duration, fps, springConfigs); - const draggedTrajectory = draggedConfig - ? getTrajectory(draggedDuration ?? duration, fps, [draggedConfig]) - : []; - const max = draggedConfig + const hasSomeDragged = draggedConfigs.some(Boolean); + + const draggedTrajectory = hasSomeDragged + ? getTrajectory( + draggedDuration ?? duration, + fps, + draggedConfigs as DraggedConfig[] + ) + : []; + console.log("dragedConfigs", draggedConfigs); + console.log(trajectory); + const max = hasSomeDragged ? Math.max(...draggedTrajectory) : Math.max(...trajectory); @@ -90,13 +97,14 @@ export const draw = ({ canvasWidth: width, context, max, - primary: !draggedConfig, - animate: !draggedConfig, + primary: !hasSomeDragged, // Used to be !draggedConfig + animate: !hasSomeDragged, fps, }); toStop.push(stopPrimary); - if (draggedConfig) { + if (hasSomeDragged) { + console.log(trajectory); toStop.push( drawTrajectory({ springTrajectory: draggedTrajectory, diff --git a/src/get-trajectory.ts b/src/get-trajectory.ts index b98fdf0..1fe983f 100644 --- a/src/get-trajectory.ts +++ b/src/get-trajectory.ts @@ -4,11 +4,14 @@ import { DraggedConfig } from "./App"; export const getTrajectory = ( durationInFrames: number, fps: number, - springConfigs: DraggedConfig[] + springConfigs: (DraggedConfig | null)[] ) => { return new Array(durationInFrames).fill(true).map((_, i) => { let totalValue = 0; springConfigs.forEach((config) => { + if (!config) { + return; + } totalValue += spring({ fps, frame: i, From 21a2a1f46a7987750e56a90f58896a661f28062b Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Wed, 28 Feb 2024 17:35:55 +0100 Subject: [PATCH 04/18] rm logs --- src/App.tsx | 1 - src/Canvas.tsx | 1 - src/CanvasWrapper.tsx | 1 - src/SpringControls.tsx | 1 - src/draw-trajectory.ts | 2 -- src/draw.tsx | 3 --- 6 files changed, 9 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 62adb00..39270d0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -194,7 +194,6 @@ function App() { return calculatedDuration > max ? calculatedDuration : max; }, 0) : null; - console.log("duration:", duration); return (
( "seconds" ); - console.log("draggedDuration: ", draggedDuration, "duration: ", duration); const durationLabel = durationType === "seconds" diff --git a/src/CanvasWrapper.tsx b/src/CanvasWrapper.tsx index 9c7f5b1..74c2579 100644 --- a/src/CanvasWrapper.tsx +++ b/src/CanvasWrapper.tsx @@ -11,7 +11,6 @@ export const CanvasWrapper: React.FC<{ fps: number; }> = ({ springConfigs, draggedConfigs, draggedDuration, duration, fps }) => { const outer = useRef(null); - console.log("duration: ", duration, "draggedDuration: ", draggedDuration); const elementSize = PlayerInternals.useElementSize(outer, { shouldApplyCssTransforms: false, triggerOnWindowResize: true, diff --git a/src/SpringControls.tsx b/src/SpringControls.tsx index 230b8c7..d655bb7 100644 --- a/src/SpringControls.tsx +++ b/src/SpringControls.tsx @@ -40,7 +40,6 @@ export const SpringControls: React.FC<{ fixedDurationInFrames, index, }) => { - console.log(index); return ( <> diff --git a/src/draw-trajectory.ts b/src/draw-trajectory.ts index aeb8491..b3b219b 100644 --- a/src/draw-trajectory.ts +++ b/src/draw-trajectory.ts @@ -49,8 +49,6 @@ export const drawTrajectory = ({ animate: boolean; fps: number; }) => { - console.log("animate: ", animate); - console.log("primary: ", primary); const intervalBetweenDraw = 1000 / fps; const segmentWidth = (canvasWidth - PADDING_LEFT - PADDING_RIGHT) / diff --git a/src/draw.tsx b/src/draw.tsx index 32dab09..425cf91 100644 --- a/src/draw.tsx +++ b/src/draw.tsx @@ -49,8 +49,6 @@ export const draw = ({ draggedConfigs as DraggedConfig[] ) : []; - console.log("dragedConfigs", draggedConfigs); - console.log(trajectory); const max = hasSomeDragged ? Math.max(...draggedTrajectory) : Math.max(...trajectory); @@ -104,7 +102,6 @@ export const draw = ({ toStop.push(stopPrimary); if (hasSomeDragged) { - console.log(trajectory); toStop.push( drawTrajectory({ springTrajectory: draggedTrajectory, From 1be41041be2b25a6de7a14f99a9ef5d88d301c26 Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Thu, 7 Mar 2024 10:21:34 +0100 Subject: [PATCH 05/18] correct drag indication --- src/App.tsx | 172 +++++++++++++++++++++++++----------------- src/Canvas.tsx | 6 +- src/CanvasWrapper.tsx | 6 +- src/Sidebar.tsx | 18 +++-- src/draw.tsx | 17 +++-- src/get-trajectory.ts | 4 +- 6 files changed, 132 insertions(+), 91 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 39270d0..38f82af 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,14 +9,19 @@ import { Header } from "./Header"; const fps = 60; -export type DraggedConfig = SpringConfig & { +export type ExtendedSpringConfig = SpringConfig & { reverse: boolean; durationInFrames: number | null; delay: number; }; +export type DraggedConfig = { + index: number; + configs: (ExtendedSpringConfig | null)[]; +}; + function App() { - const [springConfigs, setSpringConfigs] = useState([ + const [springConfigs, setSpringConfigs] = useState([ { damping: DEFAULT_DAMPING, mass: DEFAULT_MASS, @@ -38,75 +43,91 @@ function App() { }, ]); - const [draggedConfigs, setDraggedConfigs] = useState< - (DraggedConfig | null)[] - >(Array(springConfigs.length).fill(null)); + const [draggedConfigs, setDraggedConfigs] = useState({ + index: 0, + configs: Array(springConfigs.length).fill(null), + }); const onMassChange = useCallback( (e: number[], index: number) => { - setDraggedConfigs((old) => [ - ...old.slice(0, index), - { - ...springConfigs[index], - mass: e[0], - }, - ...old.slice(index + 1), - ]); + setDraggedConfigs((old) => ({ + ...old, + configs: [ + ...old.configs.slice(0, index), + { + ...springConfigs[index], + mass: e[0], + }, + ...old.configs.slice(index + 1), + ], + })); }, [springConfigs] ); const onDampingChange = useCallback( (e: number[], index: number) => { - setDraggedConfigs((old) => [ - ...old.slice(0, index), - { - ...springConfigs[index], - damping: e[0], - }, - ...old.slice(index + 1), - ]); + setDraggedConfigs((old) => ({ + ...old, + configs: [ + ...old.configs.slice(0, index), + { + ...springConfigs[index], + damping: e[0], + }, + ...old.configs.slice(index + 1), + ], + })); }, [springConfigs] ); const onStiffnessChange = useCallback( (e: number[], index: number) => { - setDraggedConfigs((old) => [ - ...old.slice(0, index), - { - ...springConfigs[index], - stiffness: e[0], - }, - ...old.slice(index + 1), - ]); + setDraggedConfigs((old) => ({ + ...old, + configs: [ + ...old.configs.slice(0, index), + { + ...springConfigs[index], + stiffness: e[0], + }, + ...old.configs.slice(index + 1), + ], + })); }, [springConfigs] ); const onDurationInFramesChange = useCallback( (e: number | null, index: number) => { - setDraggedConfigs((old) => [ - ...old.slice(0, index), - { - ...springConfigs[index], - durationInFrames: e, - }, - ...old.slice(index + 1), - ]); + setDraggedConfigs((old) => ({ + ...old, + configs: [ + ...old.configs.slice(0, index), + { + ...springConfigs[index], + durationInFrames: e, + }, + ...old.configs.slice(index + 1), + ], + })); }, [springConfigs] ); const onDelayChange = useCallback( (e: number, index: number) => { - setDraggedConfigs((old) => [ - ...old.slice(0, index), - { - ...springConfigs[index], - delay: e, - }, - ...old.slice(index + 1), - ]); + setDraggedConfigs((old) => ({ + ...old, + configs: [ + ...old.configs.slice(0, index), + { + ...springConfigs[index], + delay: e, + }, + ...old.configs.slice(index + 1), + ], + })); setSpringConfigs((old) => [ ...old.slice(0, index), { ...old[index], delay: e }, @@ -118,14 +139,17 @@ function App() { const onOvershootClampingChange = useCallback( (checked: boolean, index: number) => { - setDraggedConfigs((old) => [ - ...old.slice(0, index), - { - ...springConfigs[index], - overshootClamping: checked, - }, - ...old.slice(index + 1), - ]); + setDraggedConfigs((old) => ({ + ...old, + configs: [ + ...old.configs.slice(0, index), + { + ...springConfigs[index], + overshootClamping: checked, + }, + ...old.configs.slice(index + 1), + ], + })); setSpringConfigs((old) => [ ...old.slice(0, index), { ...old[index], overshootClamping: checked }, @@ -137,14 +161,17 @@ function App() { const onReverseChange = useCallback( (checked: boolean, index: number) => { - setDraggedConfigs((old) => [ - ...old.slice(0, index), - { - ...springConfigs[index], - reverse: checked, - }, - ...old.slice(index + 1), - ]); + setDraggedConfigs((old) => ({ + ...old, + configs: [ + ...old.configs.slice(0, index), + { + ...springConfigs[index], + reverse: checked, + }, + ...old.configs.slice(index + 1), + ], + })); setSpringConfigs((old) => [ ...old.slice(0, index), { ...old[index], reverse: checked }, @@ -156,18 +183,21 @@ function App() { const onRelease = useCallback( (index: number) => { - if (draggedConfigs && draggedConfigs[index]) { + if (draggedConfigs && draggedConfigs.configs[index]) { setSpringConfigs((old) => [ ...old.slice(0, index), - draggedConfigs[index] as DraggedConfig, + draggedConfigs.configs[index] as ExtendedSpringConfig, ...old.slice(index + 1), ]); } - setDraggedConfigs((old) => [ - ...old.slice(0, index), - null, - ...old.slice(index + 1), - ]); + setDraggedConfigs((old) => ({ + index: 0, + configs: [ + ...old.configs.slice(0, index), + null, + ...old.configs.slice(index + 1), + ], + })); }, [draggedConfigs] ); @@ -181,8 +211,10 @@ function App() { return calculatedDuration > max ? calculatedDuration : max; }, 0); - const draggedDuration = draggedConfigs.some((config) => config !== null) - ? draggedConfigs.reduce((max, draggedConfig) => { + const draggedDuration = draggedConfigs.configs.some( + (config) => config !== null + ) + ? draggedConfigs.configs.reduce((max, draggedConfig) => { if (draggedConfig === null) { return max; } diff --git a/src/Canvas.tsx b/src/Canvas.tsx index 20610fc..19a9f7c 100644 --- a/src/Canvas.tsx +++ b/src/Canvas.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useMemo } from "react"; import { draw, stopDrawing } from "./draw"; -import { DraggedConfig } from "./App"; +import { DraggedConfig, ExtendedSpringConfig } from "./App"; import { AnimationDuration } from "./AnimationDuration"; const canvasRef = React.createRef(); @@ -8,10 +8,10 @@ const canvasRef = React.createRef(); export const Canvas: React.FC<{ width: number; height: number; - draggedConfigs: (DraggedConfig | null)[]; + draggedConfigs: DraggedConfig; draggedDuration: number | null; duration: number; - springConfigs: DraggedConfig[]; + springConfigs: ExtendedSpringConfig[]; fps: number; }> = ({ height, diff --git a/src/CanvasWrapper.tsx b/src/CanvasWrapper.tsx index 74c2579..668231b 100644 --- a/src/CanvasWrapper.tsx +++ b/src/CanvasWrapper.tsx @@ -1,13 +1,13 @@ import { PlayerInternals } from "@remotion/player"; import { useRef } from "react"; import { Canvas } from "./Canvas"; -import { DraggedConfig } from "./App"; +import { DraggedConfig, ExtendedSpringConfig } from "./App"; export const CanvasWrapper: React.FC<{ - draggedConfigs: (DraggedConfig | null)[]; + draggedConfigs: DraggedConfig; draggedDuration: number | null; duration: number; - springConfigs: DraggedConfig[]; + springConfigs: ExtendedSpringConfig[]; fps: number; }> = ({ springConfigs, draggedConfigs, draggedDuration, duration, fps }) => { const outer = useRef(null); diff --git a/src/Sidebar.tsx b/src/Sidebar.tsx index fff8b7b..a8b88cd 100644 --- a/src/Sidebar.tsx +++ b/src/Sidebar.tsx @@ -2,12 +2,12 @@ import React from "react"; import { CodeFrameTabs } from "./CodeFrame"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "./components/ui/tabs"; import { PADDING_LEFT } from "./draw-trajectory"; -import { DraggedConfig } from "./App"; +import { DraggedConfig, ExtendedSpringConfig } from "./App"; import { SpringControls } from "./SpringControls"; export const Sidebar: React.FC<{ - springConfigs: DraggedConfig[]; - draggedConfigs: (DraggedConfig | null)[]; + springConfigs: ExtendedSpringConfig[]; + draggedConfigs: DraggedConfig; calculatedDurationInFrames: number; onMassChange: (e: number[], index: number) => void; onDampingChange: (e: number[], index: number) => void; @@ -50,17 +50,19 @@ export const Sidebar: React.FC<{ return ( {}; @@ -26,8 +26,8 @@ export const draw = ({ ref: HTMLCanvasElement; duration: number; fps: number; - springConfigs: DraggedConfig[]; - draggedConfigs: (DraggedConfig | null)[]; + springConfigs: ExtendedSpringConfig[]; + draggedConfigs: DraggedConfig; draggedDuration: number | null; width: number; height: number; @@ -40,13 +40,20 @@ export const draw = ({ context.clearRect(0, 0, width, height); const trajectory = getTrajectory(duration, fps, springConfigs); - const hasSomeDragged = draggedConfigs.some(Boolean); + const hasSomeDragged = draggedConfigs.configs.some(Boolean); + + const currentIdx = draggedConfigs.index; + const draggedConfigsToDraw = [ + ...springConfigs.slice(0, currentIdx), + draggedConfigs.configs[currentIdx], + ...springConfigs.slice(currentIdx + 1), + ]; const draggedTrajectory = hasSomeDragged ? getTrajectory( draggedDuration ?? duration, fps, - draggedConfigs as DraggedConfig[] + draggedConfigsToDraw as ExtendedSpringConfig[] ) : []; const max = hasSomeDragged diff --git a/src/get-trajectory.ts b/src/get-trajectory.ts index 1fe983f..9230af1 100644 --- a/src/get-trajectory.ts +++ b/src/get-trajectory.ts @@ -1,10 +1,10 @@ import { spring } from "remotion"; -import { DraggedConfig } from "./App"; +import { ExtendedSpringConfig } from "./App"; export const getTrajectory = ( durationInFrames: number, fps: number, - springConfigs: (DraggedConfig | null)[] + springConfigs: (ExtendedSpringConfig | null)[] ) => { return new Array(durationInFrames).fill(true).map((_, i) => { let totalValue = 0; From a849a229b3da43a840a98f3399894c2787c7d69d Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Thu, 7 Mar 2024 13:27:34 +0100 Subject: [PATCH 06/18] improvements --- src/App.tsx | 59 ++++++++++++++++++------------------------------- src/Sidebar.tsx | 1 + 2 files changed, 23 insertions(+), 37 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 38f82af..71c90ad 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -51,7 +51,7 @@ function App() { const onMassChange = useCallback( (e: number[], index: number) => { setDraggedConfigs((old) => ({ - ...old, + index, configs: [ ...old.configs.slice(0, index), { @@ -67,7 +67,7 @@ function App() { const onDampingChange = useCallback( (e: number[], index: number) => { setDraggedConfigs((old) => ({ - ...old, + index, configs: [ ...old.configs.slice(0, index), { @@ -84,7 +84,7 @@ function App() { const onStiffnessChange = useCallback( (e: number[], index: number) => { setDraggedConfigs((old) => ({ - ...old, + index, configs: [ ...old.configs.slice(0, index), { @@ -111,14 +111,24 @@ function App() { ...old.configs.slice(index + 1), ], })); + + setSpringConfigs((old) => [ + ...old.slice(0, index), + { + ...springConfigs[index], + durationInFrames: e, + }, + ...old.slice(index + 1), + ]); }, + [springConfigs] ); const onDelayChange = useCallback( (e: number, index: number) => { setDraggedConfigs((old) => ({ - ...old, + index, configs: [ ...old.configs.slice(0, index), { @@ -139,47 +149,22 @@ function App() { const onOvershootClampingChange = useCallback( (checked: boolean, index: number) => { - setDraggedConfigs((old) => ({ - ...old, - configs: [ - ...old.configs.slice(0, index), - { - ...springConfigs[index], - overshootClamping: checked, - }, - ...old.configs.slice(index + 1), - ], - })); setSpringConfigs((old) => [ ...old.slice(0, index), { ...old[index], overshootClamping: checked }, ...old.slice(index + 1), ]); }, - [springConfigs] + [] ); - const onReverseChange = useCallback( - (checked: boolean, index: number) => { - setDraggedConfigs((old) => ({ - ...old, - configs: [ - ...old.configs.slice(0, index), - { - ...springConfigs[index], - reverse: checked, - }, - ...old.configs.slice(index + 1), - ], - })); - setSpringConfigs((old) => [ - ...old.slice(0, index), - { ...old[index], reverse: checked }, - ...old.slice(index + 1), - ]); - }, - [springConfigs] - ); + const onReverseChange = useCallback((checked: boolean, index: number) => { + setSpringConfigs((old) => [ + ...old.slice(0, index), + { ...old[index], reverse: checked }, + ...old.slice(index + 1), + ]); + }, []); const onRelease = useCallback( (index: number) => { diff --git a/src/Sidebar.tsx b/src/Sidebar.tsx index a8b88cd..459839d 100644 --- a/src/Sidebar.tsx +++ b/src/Sidebar.tsx @@ -38,6 +38,7 @@ export const Sidebar: React.FC<{ display: "flex", flexDirection: "column", borderLeft: "1px solid #242424", + overflow: "scroll", }} > From 853ee12b7699a574a019cf34d36c1943f81389d6 Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Thu, 7 Mar 2024 14:32:05 +0100 Subject: [PATCH 07/18] add and delete springs --- src/App.tsx | 50 ++++++++++++++++++----------- src/Sidebar.tsx | 73 +++++++++++++++++++++++++----------------- src/SpringControls.tsx | 52 ++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 48 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 71c90ad..21ca4c3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -20,27 +20,19 @@ export type DraggedConfig = { configs: (ExtendedSpringConfig | null)[]; }; +const DEFAULT_SPRING = { + damping: DEFAULT_DAMPING, + mass: DEFAULT_MASS, + stiffness: DEFAULT_STIFFNESS, + overshootClamping: false, + reverse: false, + durationInFrames: null, + delay: 0, +}; + function App() { const [springConfigs, setSpringConfigs] = useState([ - { - damping: DEFAULT_DAMPING, - mass: DEFAULT_MASS, - stiffness: DEFAULT_STIFFNESS, - overshootClamping: false, - reverse: false, - durationInFrames: null, - - delay: 0, - }, - { - damping: DEFAULT_DAMPING, - mass: DEFAULT_MASS, - stiffness: DEFAULT_STIFFNESS, - overshootClamping: false, - reverse: false, - durationInFrames: null, - delay: 0, - }, + DEFAULT_SPRING, ]); const [draggedConfigs, setDraggedConfigs] = useState({ @@ -48,6 +40,24 @@ function App() { configs: Array(springConfigs.length).fill(null), }); + const addSpring = useCallback(() => { + setSpringConfigs([...springConfigs, DEFAULT_SPRING]); + setDraggedConfigs((old) => ({ + ...old, + configs: [...old.configs, null], + })); + springConfigs.push(DEFAULT_SPRING); + draggedConfigs.configs.push(DEFAULT_SPRING); + }, [draggedConfigs.configs, springConfigs]); + + const removeSpring = useCallback((index: number) => { + setSpringConfigs((old) => [...old.splice(0, index), ...old.splice(index)]); + setDraggedConfigs((old) => ({ + ...old, + configs: [...old.configs.splice(0, index), ...old.configs.splice(index)], + })); + }, []); + const onMassChange = useCallback( (e: number[], index: number) => { setDraggedConfigs((old) => ({ @@ -255,6 +265,8 @@ function App() { springConfigs={springConfigs} draggedConfigs={draggedConfigs} calculatedDurationInFrames={duration} + addSpring={addSpring} + removeSpring={removeSpring} onMassChange={onMassChange} onDampingChange={onDampingChange} onStiffnessChange={onStiffnessChange} diff --git a/src/Sidebar.tsx b/src/Sidebar.tsx index 459839d..9550a05 100644 --- a/src/Sidebar.tsx +++ b/src/Sidebar.tsx @@ -4,11 +4,15 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "./components/ui/tabs"; import { PADDING_LEFT } from "./draw-trajectory"; import { DraggedConfig, ExtendedSpringConfig } from "./App"; import { SpringControls } from "./SpringControls"; +import { Button } from "./components/ui/button"; +import { Spacing } from "./Spacing"; export const Sidebar: React.FC<{ springConfigs: ExtendedSpringConfig[]; draggedConfigs: DraggedConfig; calculatedDurationInFrames: number; + addSpring: () => void; + removeSpring: (index: number) => void; onMassChange: (e: number[], index: number) => void; onDampingChange: (e: number[], index: number) => void; onStiffnessChange: (e: number[], index: number) => void; @@ -29,6 +33,8 @@ export const Sidebar: React.FC<{ onOvershootClampingChange, onReverseChange, onDelayChange, + addSpring, + removeSpring, }) => { return (
Code - {springConfigs.map((config, idx) => { - return ( - - ); - })} + <> + {springConfigs.map((config, idx) => { + return ( + + ); + })} + + + void; }> = ({ mass, damping, @@ -39,9 +41,55 @@ export const SpringControls: React.FC<{ calculatedDurationInFrames, fixedDurationInFrames, index, + removeSpring, }) => { + const crossIcon = ( + + + + ); return ( <> +
+

+ Spring {index + 1} +

+ {index > 0 ? ( + + ) : null} +
+ onRelease(index)} /> + onRelease(index)} /> + onRelease(index)} /> + onRelease(index)} /> + <> Date: Thu, 7 Mar 2024 14:59:02 +0100 Subject: [PATCH 08/18] generate code --- src/CodeFrame.tsx | 42 ++++++++++++++++++++++++++++++++++++++---- src/Sidebar.tsx | 10 +--------- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/CodeFrame.tsx b/src/CodeFrame.tsx index 5783d78..220d7be 100644 --- a/src/CodeFrame.tsx +++ b/src/CodeFrame.tsx @@ -6,6 +6,7 @@ import { Button } from "./components/ui/button"; import { Spacing } from "./Spacing"; import { copyText } from "./copy-text"; import toast, { Toaster } from "react-hot-toast"; +import { ExtendedSpringConfig } from "./App"; type Props = { damping: number; @@ -17,6 +18,7 @@ type Props = { reverse: boolean; durationInFrames: number | null; delay: number; + index: number; }; const CodeFrame: React.FC< @@ -32,6 +34,7 @@ const CodeFrame: React.FC< platform, durationInFrames, delay, + index, }) => { const [h, setH] = useState(null); @@ -44,7 +47,7 @@ const CodeFrame: React.FC< isDefaultDamping && isDefaultMass && isDefaultStiffness; const lines = [ - "const spr = spring({", + `const spr${index + 1} = spring({`, platform === "remotion" ? " frame," : null, platform === "remotion" ? " fps," : null, platform === "reanimated" ? " toValue: 1," : null, @@ -68,6 +71,7 @@ const CodeFrame: React.FC< damping, mass, stiffness, + index, platform, durationInFrames, delay, @@ -120,7 +124,9 @@ const CodeFrame: React.FC< ); }; -export function CodeFrameTabs(props: Props) { +export function CodeFrameTabs(props: { + springConfigs: ExtendedSpringConfig[]; +}) { return ( @@ -128,10 +134,38 @@ export function CodeFrameTabs(props: Props) { Reanimated - + {props.springConfigs.map((config, i) => { + return ( + + ); + })} - + {props.springConfigs.map((config, i) => { + return ( + + ); + })} ); diff --git a/src/Sidebar.tsx b/src/Sidebar.tsx index 9550a05..d942d66 100644 --- a/src/Sidebar.tsx +++ b/src/Sidebar.tsx @@ -93,15 +93,7 @@ export const Sidebar: React.FC<{
- +
From 18920a100e594719efeae060af559416c8360805 Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Thu, 7 Mar 2024 15:29:43 +0100 Subject: [PATCH 09/18] better code --- src/CodeFrame.tsx | 138 ++++++++++++++-------------------------------- 1 file changed, 42 insertions(+), 96 deletions(-) diff --git a/src/CodeFrame.tsx b/src/CodeFrame.tsx index 220d7be..9503e97 100644 --- a/src/CodeFrame.tsx +++ b/src/CodeFrame.tsx @@ -8,76 +8,51 @@ import { copyText } from "./copy-text"; import toast, { Toaster } from "react-hot-toast"; import { ExtendedSpringConfig } from "./App"; -type Props = { - damping: number; - mass: number; - stiffness: number; - // eslint-disable-next-line react/boolean-prop-naming - overshotClamping: boolean; - // eslint-disable-next-line react/boolean-prop-naming - reverse: boolean; - durationInFrames: number | null; - delay: number; - index: number; -}; - -const CodeFrame: React.FC< - Props & { - platform: "remotion" | "reanimated"; - } -> = ({ - damping, - mass, - stiffness, - overshotClamping, - reverse, - platform, - durationInFrames, - delay, - index, -}) => { +const CodeFrame: React.FC<{ + springConfigs: ExtendedSpringConfig[]; + platform: "remotion" | "reanimated"; +}> = ({ springConfigs, platform }) => { const [h, setH] = useState(null); const code = useMemo(() => { - const isDefaultDamping = DEFAULT_DAMPING === damping; - const isDefaultMass = DEFAULT_MASS === mass; - const isDefaultStiffness = DEFAULT_STIFFNESS === stiffness; + const allLines: string[] = []; + + springConfigs.forEach((config, index) => { + const isDefaultDamping = DEFAULT_DAMPING === config.damping; + const isDefaultMass = DEFAULT_MASS === config.mass; + const isDefaultStiffness = DEFAULT_STIFFNESS === config.stiffness; - const isAllDefault = - isDefaultDamping && isDefaultMass && isDefaultStiffness; + const isAllDefault = + isDefaultDamping && isDefaultMass && isDefaultStiffness; + + const lines = [ + `const spr${index + 1} = spring({`, + platform === "remotion" ? " frame," : null, + platform === "remotion" ? " fps," : null, + platform === "reanimated" ? " toValue: 1," : null, + isAllDefault ? null : " config: {", + isDefaultDamping ? null : ` damping: ${config.damping}`, + isDefaultMass ? null : ` mass: ${config.mass}`, + isDefaultStiffness ? null : ` stiffness: ${config.stiffness}`, + isAllDefault ? null : " },", + config.durationInFrames === null || platform === "reanimated" + ? null + : ` durationInFrames: ${config.durationInFrames},`, + config.delay === 0 || platform === "reanimated" + ? 0 + : ` delay: ${config.delay},`, + config.overshootClamping ? " overshootClamping: true," : null, + config.reverse ? " reverse: true," : null, + "});", + ] + .filter(Boolean) + .join("\n"); + + allLines.push(lines); + }); - const lines = [ - `const spr${index + 1} = spring({`, - platform === "remotion" ? " frame," : null, - platform === "remotion" ? " fps," : null, - platform === "reanimated" ? " toValue: 1," : null, - isAllDefault ? null : " config: {", - isDefaultDamping ? null : ` damping: ${damping}`, - isDefaultMass ? null : ` mass: ${mass}`, - isDefaultStiffness ? null : ` stiffness: ${stiffness}`, - isAllDefault ? null : " },", - durationInFrames === null || platform === "reanimated" - ? null - : ` durationInFrames: ${durationInFrames},`, - delay === 0 || platform === "reanimated" ? 0 : ` delay: ${delay},`, - overshotClamping ? " overshootClamping: true," : null, - reverse ? " reverse: true," : null, - "});", - ] - .filter(Boolean) - .join("\n"); - return lines; - }, [ - damping, - mass, - stiffness, - index, - platform, - durationInFrames, - delay, - overshotClamping, - reverse, - ]); + return allLines.join("\n\n"); + }, [springConfigs, platform]); useEffect(() => { codeToHtml(code, { @@ -104,7 +79,6 @@ const CodeFrame: React.FC< backgroundColor: "#24292E", paddingTop: 14, paddingLeft: 20, - height: 300, borderRadius: 8, }} > @@ -134,38 +108,10 @@ export function CodeFrameTabs(props: { Reanimated - {props.springConfigs.map((config, i) => { - return ( - - ); - })} + - {props.springConfigs.map((config, i) => { - return ( - - ); - })} +
); From b8035feb2cda3b63f5dc7bbcfbf9206580a971d6 Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Thu, 7 Mar 2024 15:56:46 +0100 Subject: [PATCH 10/18] works --- src/App.tsx | 7 ++++--- src/draw.tsx | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 21ca4c3..7c3d146 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -40,14 +40,15 @@ function App() { configs: Array(springConfigs.length).fill(null), }); + console.log(draggedConfigs.configs); + const addSpring = useCallback(() => { + console.log("old.configs: ", draggedConfigs.configs); setSpringConfigs([...springConfigs, DEFAULT_SPRING]); setDraggedConfigs((old) => ({ - ...old, + index: old.index, configs: [...old.configs, null], })); - springConfigs.push(DEFAULT_SPRING); - draggedConfigs.configs.push(DEFAULT_SPRING); }, [draggedConfigs.configs, springConfigs]); const removeSpring = useCallback((index: number) => { diff --git a/src/draw.tsx b/src/draw.tsx index 6bf38a3..f7415d0 100644 --- a/src/draw.tsx +++ b/src/draw.tsx @@ -9,6 +9,7 @@ import { } from "./draw-trajectory"; import { DraggedConfig, ExtendedSpringConfig } from "./App"; import { measureText } from "@remotion/layout-utils"; +import { totalmem } from "os"; export let stopDrawing = () => {}; @@ -95,7 +96,6 @@ export const draw = ({ context.closePath(); const toStop: (() => void)[] = []; - const stopPrimary = drawTrajectory({ springTrajectory: trajectory, canvasHeight: height, @@ -106,6 +106,7 @@ export const draw = ({ animate: !hasSomeDragged, fps, }); + toStop.push(stopPrimary); if (hasSomeDragged) { From 230c9a654836d5d698fefded17d6496ac88322ec Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Thu, 7 Mar 2024 16:33:34 +0100 Subject: [PATCH 11/18] local storage --- src/App.tsx | 140 +++++++++++++++++------------------------------- src/Sidebar.tsx | 12 ++--- src/draw.tsx | 5 +- 3 files changed, 57 insertions(+), 100 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 7c3d146..04b912a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -17,7 +17,7 @@ export type ExtendedSpringConfig = SpringConfig & { export type DraggedConfig = { index: number; - configs: (ExtendedSpringConfig | null)[]; + config: ExtendedSpringConfig | null; }; const DEFAULT_SPRING = { @@ -31,62 +31,45 @@ const DEFAULT_SPRING = { }; function App() { - const [springConfigs, setSpringConfigs] = useState([ - DEFAULT_SPRING, - ]); - + const initialConfig = window.localStorage.getItem("springConfigs") + ? JSON.parse(window.localStorage.getItem("springConfigs") as string) + : [DEFAULT_SPRING]; + const [springConfigs, setSpringConfigs] = + useState(initialConfig); + + const updateLocalStorage = useCallback(() => { + window.localStorage.setItem("springConfigs", JSON.stringify(springConfigs)); + }, [springConfigs]); const [draggedConfigs, setDraggedConfigs] = useState({ index: 0, - configs: Array(springConfigs.length).fill(null), + config: null, }); - console.log(draggedConfigs.configs); - const addSpring = useCallback(() => { - console.log("old.configs: ", draggedConfigs.configs); setSpringConfigs([...springConfigs, DEFAULT_SPRING]); - setDraggedConfigs((old) => ({ - index: old.index, - configs: [...old.configs, null], - })); - }, [draggedConfigs.configs, springConfigs]); + }, [springConfigs]); const removeSpring = useCallback((index: number) => { setSpringConfigs((old) => [...old.splice(0, index), ...old.splice(index)]); - setDraggedConfigs((old) => ({ - ...old, - configs: [...old.configs.splice(0, index), ...old.configs.splice(index)], - })); }, []); const onMassChange = useCallback( (e: number[], index: number) => { - setDraggedConfigs((old) => ({ + setDraggedConfigs(() => ({ index, - configs: [ - ...old.configs.slice(0, index), - { - ...springConfigs[index], - mass: e[0], - }, - ...old.configs.slice(index + 1), - ], + config: { ...springConfigs[index], mass: e[0] }, })); }, [springConfigs] ); const onDampingChange = useCallback( (e: number[], index: number) => { - setDraggedConfigs((old) => ({ + setDraggedConfigs(() => ({ index, - configs: [ - ...old.configs.slice(0, index), - { - ...springConfigs[index], - damping: e[0], - }, - ...old.configs.slice(index + 1), - ], + config: { + ...springConfigs[index], + damping: e[0], + }, })); }, [springConfigs] @@ -94,16 +77,12 @@ function App() { const onStiffnessChange = useCallback( (e: number[], index: number) => { - setDraggedConfigs((old) => ({ + setDraggedConfigs(() => ({ index, - configs: [ - ...old.configs.slice(0, index), - { - ...springConfigs[index], - stiffness: e[0], - }, - ...old.configs.slice(index + 1), - ], + config: { + ...springConfigs[index], + stiffness: e[0], + }, })); }, [springConfigs] @@ -111,16 +90,12 @@ function App() { const onDurationInFramesChange = useCallback( (e: number | null, index: number) => { - setDraggedConfigs((old) => ({ - ...old, - configs: [ - ...old.configs.slice(0, index), - { - ...springConfigs[index], - durationInFrames: e, - }, - ...old.configs.slice(index + 1), - ], + setDraggedConfigs(() => ({ + index, + config: { + ...springConfigs[index], + durationInFrames: e, + }, })); setSpringConfigs((old) => [ @@ -138,16 +113,12 @@ function App() { const onDelayChange = useCallback( (e: number, index: number) => { - setDraggedConfigs((old) => ({ + setDraggedConfigs(() => ({ index, - configs: [ - ...old.configs.slice(0, index), - { - ...springConfigs[index], - delay: e, - }, - ...old.configs.slice(index + 1), - ], + config: { + ...springConfigs[index], + delay: e, + }, })); setSpringConfigs((old) => [ ...old.slice(0, index), @@ -179,23 +150,17 @@ function App() { const onRelease = useCallback( (index: number) => { - if (draggedConfigs && draggedConfigs.configs[index]) { + if (draggedConfigs && draggedConfigs.config) { setSpringConfigs((old) => [ ...old.slice(0, index), - draggedConfigs.configs[index] as ExtendedSpringConfig, + draggedConfigs.config as ExtendedSpringConfig, ...old.slice(index + 1), ]); } - setDraggedConfigs((old) => ({ - index: 0, - configs: [ - ...old.configs.slice(0, index), - null, - ...old.configs.slice(index + 1), - ], - })); + setDraggedConfigs({ index: 0, config: null }); + updateLocalStorage(); }, - [draggedConfigs] + [draggedConfigs, updateLocalStorage] ); const duration = springConfigs.reduce((max, config) => { @@ -207,21 +172,16 @@ function App() { return calculatedDuration > max ? calculatedDuration : max; }, 0); - const draggedDuration = draggedConfigs.configs.some( - (config) => config !== null - ) - ? draggedConfigs.configs.reduce((max, draggedConfig) => { - if (draggedConfig === null) { - return max; - } - const calculatedDuration = - draggedConfig.delay + - (draggedConfig.durationInFrames - ? draggedConfig.durationInFrames - : measureSpring({ fps, threshold: 0.001, config: draggedConfig })); - return calculatedDuration > max ? calculatedDuration : max; - }, 0) - : null; + const draggedDuration = + // eslint-disable-next-line no-negated-condition + draggedConfigs.config !== null + ? measureSpring({ + fps, + threshold: 0.001, + config: draggedConfigs.config, + }) + : null; + return (
{}; @@ -41,12 +40,12 @@ export const draw = ({ context.clearRect(0, 0, width, height); const trajectory = getTrajectory(duration, fps, springConfigs); - const hasSomeDragged = draggedConfigs.configs.some(Boolean); + const hasSomeDragged = draggedConfigs.config !== null; const currentIdx = draggedConfigs.index; const draggedConfigsToDraw = [ ...springConfigs.slice(0, currentIdx), - draggedConfigs.configs[currentIdx], + draggedConfigs.config, ...springConfigs.slice(currentIdx + 1), ]; From aa84c126e58c92f9e4368fa32bf3e5ba1b39fcfa Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Thu, 7 Mar 2024 17:15:40 +0100 Subject: [PATCH 12/18] persisting fix --- src/App.tsx | 5 +++++ src/Sidebar.tsx | 49 +++++++++++++++++++++++++++++++++--------- src/draw-trajectory.ts | 2 -- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 04b912a..b4f61e9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -53,6 +53,10 @@ function App() { setSpringConfigs((old) => [...old.splice(0, index), ...old.splice(index)]); }, []); + const resetSpring = useCallback(() => { + setSpringConfigs([DEFAULT_SPRING]); + }, []); + const onMassChange = useCallback( (e: number[], index: number) => { setDraggedConfigs(() => ({ @@ -228,6 +232,7 @@ function App() { calculatedDurationInFrames={duration} addSpring={addSpring} removeSpring={removeSpring} + resetSpring={resetSpring} onMassChange={onMassChange} onDampingChange={onDampingChange} onStiffnessChange={onStiffnessChange} diff --git a/src/Sidebar.tsx b/src/Sidebar.tsx index 93ed3c9..4dcea37 100644 --- a/src/Sidebar.tsx +++ b/src/Sidebar.tsx @@ -21,6 +21,7 @@ export const Sidebar: React.FC<{ onRelease: (index: number) => void; onOvershootClampingChange: (checked: boolean, index: number) => void; onReverseChange: (checked: boolean, index: number) => void; + resetSpring: () => void; }> = ({ springConfigs, draggedConfigs, @@ -35,6 +36,7 @@ export const Sidebar: React.FC<{ onDelayChange, addSpring, removeSpring, + resetSpring, }) => { return (
); })} - - +
+ + + +
diff --git a/src/draw-trajectory.ts b/src/draw-trajectory.ts index b3b219b..10425fc 100644 --- a/src/draw-trajectory.ts +++ b/src/draw-trajectory.ts @@ -59,7 +59,6 @@ export const drawTrajectory = ({ let lastDraw = Date.now(); let stopped = false; - const executeDraw = async () => { for (let i = 0; i < springTrajectory.length; i++) { const timeSinceLastDraw = Date.now() - lastDraw; @@ -92,7 +91,6 @@ export const drawTrajectory = ({ context.stroke(); context.closePath(); lastDraw = Date.now(); - if (animate) { ( document.getElementById("scale") as HTMLElement From f258019dd9f8ffe5c91b5a131a4938d87337fd0f Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Fri, 8 Mar 2024 08:25:17 +0100 Subject: [PATCH 13/18] Animation preview fix --- src/draw-trajectory.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/draw-trajectory.ts b/src/draw-trajectory.ts index 10425fc..a53b30a 100644 --- a/src/draw-trajectory.ts +++ b/src/draw-trajectory.ts @@ -91,21 +91,22 @@ export const drawTrajectory = ({ context.stroke(); context.closePath(); lastDraw = Date.now(); + const divisor = Math.round(max); if (animate) { ( document.getElementById("scale") as HTMLElement - ).style.transform = `scale(${springTrajectory[i]})`; + ).style.transform = `scale(${springTrajectory[i] / divisor})`; ( document.getElementById("translate") as HTMLElement ).style.transform = `translateY(${interpolate( - springTrajectory[i], + springTrajectory[i] / divisor, [0, 1], [100, 0] )}px)`; ( document.getElementById("rotate") as HTMLElement ).style.transform = `rotate(${interpolate( - springTrajectory[i], + springTrajectory[i] / divisor, [0, 1], [Math.PI * 2, 0] )}rad)`; From d4b44731c7ad04f21d0b88d3722aa902a2c0c2c4 Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Fri, 8 Mar 2024 08:44:36 +0100 Subject: [PATCH 14/18] local storage improvement --- src/App.tsx | 10 +++++++--- src/draw.tsx | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index b4f61e9..0136cec 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ -import { useCallback, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { measureSpring, SpringConfig } from "remotion"; import { AnimationPreview } from "./AnimationPreview"; @@ -38,6 +38,7 @@ function App() { useState(initialConfig); const updateLocalStorage = useCallback(() => { + console.log("persisting to local storage: ", springConfigs); window.localStorage.setItem("springConfigs", JSON.stringify(springConfigs)); }, [springConfigs]); const [draggedConfigs, setDraggedConfigs] = useState({ @@ -49,6 +50,10 @@ function App() { setSpringConfigs([...springConfigs, DEFAULT_SPRING]); }, [springConfigs]); + useEffect(() => { + updateLocalStorage(); + }, [springConfigs, updateLocalStorage]); + const removeSpring = useCallback((index: number) => { setSpringConfigs((old) => [...old.splice(0, index), ...old.splice(index)]); }, []); @@ -162,9 +167,8 @@ function App() { ]); } setDraggedConfigs({ index: 0, config: null }); - updateLocalStorage(); }, - [draggedConfigs, updateLocalStorage] + [draggedConfigs] ); const duration = springConfigs.reduce((max, config) => { diff --git a/src/draw.tsx b/src/draw.tsx index ed31b6e..578b826 100644 --- a/src/draw.tsx +++ b/src/draw.tsx @@ -37,6 +37,8 @@ export const draw = ({ if (!context) { return; } + + console.log("width: ", width); context.clearRect(0, 0, width, height); const trajectory = getTrajectory(duration, fps, springConfigs); From 41e068cbaaf69c40e1f2a1cf42bc532f24c8c4bf Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Fri, 8 Mar 2024 08:45:04 +0100 Subject: [PATCH 15/18] rm log --- src/draw.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/draw.tsx b/src/draw.tsx index 578b826..57b89d9 100644 --- a/src/draw.tsx +++ b/src/draw.tsx @@ -38,7 +38,6 @@ export const draw = ({ return; } - console.log("width: ", width); context.clearRect(0, 0, width, height); const trajectory = getTrajectory(duration, fps, springConfigs); From dbfae0977311d772b60f4d201e0e60bf335aa547 Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Fri, 8 Mar 2024 09:14:53 +0100 Subject: [PATCH 16/18] addition of springs in code --- src/App.tsx | 1 - src/CodeFrame.tsx | 11 +++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/App.tsx b/src/App.tsx index 0136cec..be7b7dd 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -38,7 +38,6 @@ function App() { useState(initialConfig); const updateLocalStorage = useCallback(() => { - console.log("persisting to local storage: ", springConfigs); window.localStorage.setItem("springConfigs", JSON.stringify(springConfigs)); }, [springConfigs]); const [draggedConfigs, setDraggedConfigs] = useState({ diff --git a/src/CodeFrame.tsx b/src/CodeFrame.tsx index 9503e97..abcfcf8 100644 --- a/src/CodeFrame.tsx +++ b/src/CodeFrame.tsx @@ -50,6 +50,16 @@ const CodeFrame: React.FC<{ allLines.push(lines); }); + const additionLine = [`const spr =`]; + springConfigs.forEach((config, index) => { + if (index < springConfigs.length - 1) { + additionLine.push(`spr${index + 1} +`); + } else { + additionLine.push(`spr${index + 1};`); + } + }); + const joined = additionLine.join(" "); + allLines.push(joined); return allLines.join("\n\n"); }, [springConfigs, platform]); @@ -79,6 +89,7 @@ const CodeFrame: React.FC<{ backgroundColor: "#24292E", paddingTop: 14, paddingLeft: 20, + paddingBottom: 14, borderRadius: 8, }} > From a8f967deb9543e32e1db882e294081c5b6d35660 Mon Sep 17 00:00:00 2001 From: Patric Salvisberg Date: Fri, 8 Mar 2024 09:52:22 +0100 Subject: [PATCH 17/18] Sidebar improvements --- src/Sidebar.tsx | 104 ++++++++++++++++++++++++----------------- src/SpringControls.tsx | 58 ++++++++++++----------- 2 files changed, 91 insertions(+), 71 deletions(-) diff --git a/src/Sidebar.tsx b/src/Sidebar.tsx index 4dcea37..e51c426 100644 --- a/src/Sidebar.tsx +++ b/src/Sidebar.tsx @@ -58,52 +58,68 @@ export const Sidebar: React.FC<{ <> {springConfigs.map((config, idx) => { return ( - + <> + + {idx < springConfigs.length - 1 ? ( +
+ + +
+ ) : null} + ); })} +