diff --git a/components/animate/AnimationPreview.tsx b/components/animate/AnimationPreview.tsx index 788e605..8cb0b63 100644 --- a/components/animate/AnimationPreview.tsx +++ b/components/animate/AnimationPreview.tsx @@ -14,6 +14,8 @@ interface Props { onElementChange: (e: PreviewElement) => void; } +type AnimState = 'playing' | 'paused' | 'ended'; + const SPEEDS: { label: string; value: string }[] = [ { label: '0.25×', value: '0.25' }, { label: '0.5×', value: '0.5' }, @@ -23,9 +25,8 @@ const SPEEDS: { label: string; value: string }[] = [ export function AnimationPreview({ config, element, onElementChange }: Props) { const styleRef = useRef(null); - const elementRef = useRef(null); const [restartKey, setRestartKey] = useState(0); - const [paused, setPaused] = useState(false); + const [animState, setAnimState] = useState('playing'); const [speed, setSpeed] = useState('1'); // Inject @keyframes CSS into document head @@ -36,21 +37,32 @@ export function AnimationPreview({ config, element, onElementChange }: Props) { document.head.appendChild(styleRef.current); } styleRef.current.textContent = buildCSS(config); + // Restart preview whenever config changes so changes are immediately visible + setAnimState('playing'); + setRestartKey((k) => k + 1); }, [config]); // Cleanup on unmount useEffect(() => { - return () => { - styleRef.current?.remove(); - }; + return () => { styleRef.current?.remove(); }; }, []); const restart = () => { - setPaused(false); + setAnimState('playing'); setRestartKey((k) => k + 1); }; + const handlePlay = () => { + if (animState === 'ended') { + // Animation finished — restart it + restart(); + } else { + setAnimState('playing'); + } + }; + const scaledDuration = Math.round(config.duration / Number(speed)); + const isInfinite = config.iterationCount === 'infinite'; return ( @@ -79,12 +91,12 @@ export function AnimationPreview({ config, element, onElementChange }: Props) { {/* Animated element */}
!isInfinite && setAnimState('ended')} > {element === 'box' && (
@@ -118,17 +130,17 @@ export function AnimationPreview({ config, element, onElementChange }: Props) {