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:
- Creating a
MotionValue to represent progress
- Syncing the MotionValue to Helios frame updates
- Using
useTransform to derive animation values
- 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);
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.