Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/BintzGavin/helios/llms.txt

Use this file to discover all available pages before exploring further.

Framer Motion can be synchronized with Helios by using MotionValue and useTransform to drive animations based on Helios frame updates.

Installation

Install Framer Motion alongside Helios:
npm install framer-motion @helios-project/core react react-dom

Basic integration

The integration pattern involves:
  1. Creating a MotionValue to represent progress
  2. Syncing the MotionValue to Helios frame updates
  3. Using useTransform to derive animation values
  4. Applying transforms to motion components
import React, { useEffect } from 'react';
import { motion, useMotionValue, useTransform } from 'framer-motion';
import { Helios } from '@helios-project/core';
import { useVideoFrame } from './hooks/useVideoFrame';

const duration = 5;
const fps = 30;
const helios = new Helios({ duration, fps });

// Bind to document timeline so it can be driven by the player/renderer
helios.bindToDocumentTimeline();

// Expose to window for debugging/player control
if (typeof window !== 'undefined') {
    window.helios = helios;
}

export default function App() {
    const { currentFrame, duration, fps } = useVideoFrame(helios);

    // 1. Create a MotionValue to represent "time" or "progress"
    const progress = useMotionValue(0);

    // 2. Sync MotionValue to Helios frame on every update
    useEffect(() => {
        const p = currentFrame / (duration * fps);
        progress.set(p);
    }, [currentFrame, duration, fps, progress]);

    // 3. Drive animations using useTransform
    // Rotate 360 degrees over the full duration
    const rotate = useTransform(progress, [0, 1], [0, 360]);

    // Scale up and down
    const scale = useTransform(progress, [0, 0.5, 1], [1, 1.5, 1]);

    // Change color
    const backgroundColor = useTransform(
        progress,
        [0, 0.5, 1],
        ["#ff0055", "#0099ff", "#ff0055"]
    );

    return (
        <div style={{
            width: '100vw',
            height: '100vh',
            display: 'flex',
            justifyContent: 'center',
            alignItems: 'center',
            backgroundColor: '#111',
            color: 'white',
            fontFamily: 'sans-serif',
            flexDirection: 'column'
        }}>
            <motion.div
                style={{
                    width: 150,
                    height: 150,
                    borderRadius: 30,
                    rotate,
                    scale,
                    backgroundColor
                }}
            />
            <div style={{ marginTop: 40, fontSize: 24 }}>
                Frame: {Math.round(currentFrame)} / {duration * fps}
            </div>
        </div>
    );
}

useVideoFrame hook

Create a custom hook to sync React state with Helios:
import { useState, useEffect } from 'react';

export function useVideoFrame(helios) {
    const [state, setState] = useState({
        currentFrame: helios.getState().currentFrame,
        duration: helios.duration,
        fps: helios.fps
    });

    useEffect(() => {
        // Update local state when helios state changes
        const update = (newState) => {
            setState({
                currentFrame: newState.currentFrame,
                duration: helios.duration,
                fps: helios.fps
            });
        };

        // Subscribe returns an unsubscribe function
        return helios.subscribe(update);
    }, [helios]);

    return state;
}

Integration pattern

Progress-based animation

Calculate normalized progress (0 to 1):
const p = currentFrame / (duration * fps);
progress.set(p);

Transform mappings

Map progress to animation values:
// Simple linear transform
const rotate = useTransform(progress, [0, 1], [0, 360]);

// Multi-keyframe transform
const scale = useTransform(progress, [0, 0.5, 1], [1, 1.5, 1]);

// Color transforms
const backgroundColor = useTransform(
    progress,
    [0, 0.5, 1],
    ["#ff0055", "#0099ff", "#ff0055"]
);

Applying to motion components

Use the style prop to apply MotionValues:
<motion.div
    style={{
        rotate,
        scale,
        backgroundColor
    }}
/>

Why this works

Framer Motion’s MotionValue and useTransform provide:
  • Reactive animation values without triggering re-renders
  • Declarative transform mappings
  • Smooth interpolation between keyframes
  • Full compatibility with Helios frame control
This approach ensures deterministic rendering while maintaining Framer Motion’s developer experience.

Build docs developers (and LLMs) love