Hooks
React hooks for accessing timing information and transforms.
useTimingInfo
Access timing information for the current element.
Important: This hook requires TimelineRoot to work correctly in render clones. See timeline-root.md.
Import
import { useTimingInfo } from "@editframe/react";
Returns
{ref: RefObject<HTMLElement>; // Attach to your componentownCurrentTimeMs: number; // Current time within this elementdurationMs: number; // Total duration of elementpercentComplete: number; // Progress (0-1)isActive: boolean; // Is currently playingstartTimeMs: number; // Start time in parentendTimeMs: number; // End time in parent}
Basic Usage
import { Timegroup, useTimingInfo } from "@editframe/react";const AnimatedScene = () => {const { ref, percentComplete, ownCurrentTimeMs } = useTimingInfo();return (<Timegroup ref={ref} mode="fixed" duration="5s" className="absolute w-full h-full"><div style={{ opacity: percentComplete }}>Fading in... {(ownCurrentTimeMs / 1000).toFixed(2)}s</div></Timegroup>);};
Fade In/Out
const FadeInOut = ({ children }: { children: React.ReactNode }) => {const { ref, percentComplete } = useTimingInfo();// Fade in first half, fade out second halfconst opacity = percentComplete < 0.5? percentComplete * 2: (1 - percentComplete) * 2;return (<Timegroup ref={ref} mode="fixed" duration="5s" className="absolute w-full h-full"><div style={{ opacity }}>{children}</div></Timegroup>);};
Scale Animation
const ScaleIn = ({ children }: { children: React.ReactNode }) => {const { ref, percentComplete } = useTimingInfo();return (<Timegroup ref={ref} mode="fixed" duration="3s" className="absolute w-full h-full flex items-center justify-center"><div style={{ transform: `scale(${percentComplete})` }}>{children}</div></Timegroup>);};
Progress Bar
const SceneWithProgress = () => {const { ref, percentComplete, ownCurrentTimeMs, durationMs } = useTimingInfo();return (<Timegroup ref={ref} mode="fixed" duration="10s" className="absolute w-full h-full bg-black flex flex-col items-center justify-center"><h1 className="text-white text-4xl mb-4">Scene Content</h1><div className="w-96 bg-gray-700 h-2 rounded"><divclassName="bg-blue-500 h-full rounded transition-all"style={{ width: `${percentComplete * 100}%` }}/></div><p className="text-white mt-2">{(ownCurrentTimeMs / 1000).toFixed(1)}s / {(durationMs / 1000).toFixed(1)}s</p></Timegroup>);};
Conditional Rendering
const TimedReveal = () => {const { ref, ownCurrentTimeMs } = useTimingInfo();return (<Timegroup ref={ref} mode="fixed" duration="10s" className="absolute w-full h-full">{ownCurrentTimeMs > 2000 && (<Text duration="8s" className="text-white text-4xl">Appears after 2 seconds</Text>)}{ownCurrentTimeMs > 5000 && (<Image src="/assets/logo.png" className="absolute top-8 right-8 w-32" />)}</Timegroup>);};
Complex Animation
const ComplexAnimation = ({ children }: { children: React.ReactNode }) => {const { ref, percentComplete } = useTimingInfo();// Different animations per stagelet transform = '';let opacity = 1;if (percentComplete < 0.25) {// Slide in from leftconst progress = percentComplete * 4;transform = `translateX(${-100 + progress * 100}%)`;} else if (percentComplete < 0.75) {// Stay centeredtransform = 'translateX(0)';} else {// Slide out to rightconst progress = (percentComplete - 0.75) * 4;transform = `translateX(${progress * 100}%)`;opacity = 1 - progress;}return (<Timegroup ref={ref} mode="fixed" duration="8s" className="absolute w-full h-full flex items-center justify-center"><div style={{ transform, opacity }}>{children}</div></Timegroup>);};
usePanZoomTransform
Access pan/zoom transform values for synchronized UI elements.
Import
import { usePanZoomTransform } from "@editframe/react";
Returns
{x: number; // Pan X offsety: number; // Pan Y offsetscale: number; // Zoom scale}
Basic Usage
import { PanZoom, usePanZoomTransform } from "@editframe/react";const SyncedOverlay = () => {const { x, y, scale } = usePanZoomTransform();return (<divclassName="absolute top-0 left-0 pointer-events-none"style={{transform: `translate(${x}px, ${y}px) scale(${scale})`,}}><div className="text-white text-2xl">Follows pan/zoom</div></div>);};
Display Transform Info
const TransformInfo = () => {const { x, y, scale } = usePanZoomTransform();return (<div className="absolute top-4 right-4 bg-black/80 text-white p-2 rounded text-sm font-mono"><div>X: {x.toFixed(0)}px</div><div>Y: {y.toFixed(0)}px</div><div>Scale: {scale.toFixed(2)}x</div></div>);};