> ## 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 integration

> Learn how to integrate Framer Motion animations with Helios using MotionValues and transforms

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:

```bash theme={null}
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

```jsx theme={null}
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:

```javascript theme={null}
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):

```javascript theme={null}
const p = currentFrame / (duration * fps);
progress.set(p);
```

### Transform mappings

Map progress to animation values:

```javascript theme={null}
// 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:

```jsx theme={null}
<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.
