> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heliosrender.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Vanilla JavaScript

> Use Helios with vanilla JavaScript for maximum control and flexibility

Helios works perfectly with vanilla JavaScript, giving you complete control without framework overhead.

## Quick start

**1. Install Helios**

```bash theme={null}
npm install @helios-project/core
```

**2. Create your first animation**

```ts main.ts theme={null}
import { Helios } from '@helios-project/core';
import './style.css';

// Initialize Helios engine
const helios = new Helios({
    duration: 5,
    fps: 30,
    autoSyncAnimations: true
});

// Expose for the Player and debugging
(window as any).helios = helios;

// Enable external control (e.g. from Renderer)
helios.bindToDocumentTimeline();
```

**3. Add animation logic**

```ts theme={null}
// Subscribe to frame updates
helios.subscribe((state) => {
    const { currentFrame } = state;
    const progress = currentFrame / (helios.duration * helios.fps);

    // Update DOM elements
    const box = document.getElementById('box');
    if (box) {
        box.style.transform = `translateX(${progress * 500}px) rotate(${currentFrame * 2}deg)`;
        box.style.opacity = String(Math.min(1, currentFrame / 30));
    }
});
```

## Animation approaches

> [tab] DOM animations
>
> Directly manipulate DOM elements in the subscribe callback:
>
> ```ts theme={null}
> import { Helios } from '@helios-project/core';
>
> const helios = new Helios({ duration: 5, fps: 30 });
> helios.bindToDocumentTimeline();
>
> const box = document.createElement('div');
> box.style.width = '100px';
> box.style.height = '100px';
> box.style.backgroundColor = 'red';
> document.body.appendChild(box);
>
> helios.subscribe((state) => {
>     const progress = state.currentFrame / (state.duration * state.fps);
>
>     // Animate position
>     const x = progress * 500;
>     box.style.transform = `translateX(${x}px)`;
>
>     // Animate opacity
>     box.style.opacity = String(Math.min(1, state.currentFrame / 30));
> });
>
> (window as any).helios = helios;
> ```

> [tab] Canvas animations
>
> Draw frame-by-frame animations on a canvas:
>
> ```ts theme={null}
> import { Helios } from '@helios-project/core';
>
> const helios = new Helios({
>     fps: 30,
>     duration: 5,
>     autoSyncAnimations: true
> });
>
> // Create Canvas element
> const canvas = document.createElement('canvas');
> canvas.width = 1920;
> canvas.height = 1080;
> canvas.style.width = '100%';
> canvas.style.height = '100%';
> document.body.appendChild(canvas);
>
> const ctx = canvas.getContext('2d')!;
>
> // Animate using subscribe
> helios.subscribe((state) => {
>     // Clear
>     ctx.fillStyle = '#f0f0f0';
>     ctx.fillRect(0, 0, canvas.width, canvas.height);
>
>     const progress = state.currentFrame / (state.duration * state.fps);
>
>     // Draw box
>     const x = (progress * (canvas.width - 200)) + 100;
>     const y = canvas.height / 2;
>
>     ctx.fillStyle = 'red';
>     ctx.beginPath();
>     ctx.rect(x - 50, y - 50, 100, 100);
>     ctx.fill();
> });
>
> // Enable external control
> helios.bindToDocumentTimeline();
>
> // Expose for debugging
> (window as any).helios = helios;
> ```

## Animation helpers

Use Helios utility functions for common animation patterns:

```ts theme={null}
import { Helios, interpolate, spring } from '@helios-project/core';

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

const helperBox = document.createElement('div');
helperBox.className = 'box';
helperBox.style.backgroundColor = 'hotpink';
helperBox.style.position = 'absolute';
helperBox.style.top = '250px';
helperBox.style.left = '50px';
helperBox.style.width = '100px';
helperBox.style.height = '100px';
document.body.appendChild(helperBox);

helios.subscribe((state) => {
    const { currentFrame } = state;

    // Interpolate x position: 0 -> 200 over frames 0-60
    const x = interpolate(currentFrame, [0, 60], [0, 200], { extrapolateRight: 'clamp' });

    // Spring scale: 0 -> 1 starting at frame 0
    const scale = spring({ 
        frame: currentFrame, 
        fps: 30, 
        from: 0, 
        to: 1, 
        config: { stiffness: 100 } 
    });

    helperBox.style.transform = `translateX(${x}px) scale(${scale})`;
});

helios.bindToDocumentTimeline();
(window as any).helios = helios;
```

## Manual sequencing

Implement sequences with conditional logic:

```ts theme={null}
import { Helios } from '@helios-project/core';

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

const app = document.getElementById('app')!;

// Create sequence boxes
function createBox(color: string, text: string) {
    const box = document.createElement('div');
    box.className = 'box';
    box.style.backgroundColor = color;
    box.textContent = text;
    box.style.position = 'absolute';
    box.style.display = 'none';
    box.style.width = '100px';
    box.style.height = '100px';
    return box;
}

const seq1 = createBox('red', 'Seq 1');
app.appendChild(seq1);

const seq2 = createBox('blue', 'Seq 2');
app.appendChild(seq2);

const seq3 = createBox('green', 'Seq 3');
app.appendChild(seq3);

// Subscribe to updates
helios.subscribe((state) => {
    const { currentFrame } = state;

    // Sequence 1: 0 - 30
    if (currentFrame >= 0 && currentFrame < 30) {
        seq1.style.display = 'flex';
    } else {
        seq1.style.display = 'none';
    }

    // Sequence 2: 30 - 60
    if (currentFrame >= 30 && currentFrame < 60) {
        seq2.style.display = 'flex';
    } else {
        seq2.style.display = 'none';
    }

    // Sequence 3: 60 - 90
    if (currentFrame >= 60 && currentFrame < 90) {
        seq3.style.display = 'flex';
    } else {
        seq3.style.display = 'none';
    }
});

helios.bindToDocumentTimeline();
(window as any).helios = helios;
```

## Advanced patterns

### Multiple animations

Orchestrate multiple elements:

```ts theme={null}
import { Helios, interpolate } from '@helios-project/core';

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

const elements = [
    { el: document.getElementById('box1')!, delay: 0, color: 'red' },
    { el: document.getElementById('box2')!, delay: 15, color: 'blue' },
    { el: document.getElementById('box3')!, delay: 30, color: 'green' }
];

helios.subscribe((state) => {
    elements.forEach(({ el, delay }) => {
        const localFrame = Math.max(0, state.currentFrame - delay);
        const x = interpolate(localFrame, [0, 60], [0, 400], { extrapolateRight: 'clamp' });
        el.style.transform = `translateX(${x}px)`;
    });
});

helios.bindToDocumentTimeline();
```

### State machines

Implement complex animation states:

```ts theme={null}
import { Helios } from '@helios-project/core';

enum AnimationState {
    INTRO = 'intro',
    MAIN = 'main',
    OUTRO = 'outro'
}

const helios = new Helios({ duration: 5, fps: 30 });
let currentState: AnimationState = AnimationState.INTRO;

helios.subscribe((state) => {
    const { currentFrame } = state;

    // Determine state
    if (currentFrame < 30) {
        currentState = AnimationState.INTRO;
    } else if (currentFrame < 120) {
        currentState = AnimationState.MAIN;
    } else {
        currentState = AnimationState.OUTRO;
    }

    // Execute state-specific logic
    switch (currentState) {
        case AnimationState.INTRO:
            // Intro animations
            break;
        case AnimationState.MAIN:
            // Main animations
            break;
        case AnimationState.OUTRO:
            // Outro animations
            break;
    }
});

helios.bindToDocumentTimeline();
```

## Best practices

> [accordion] Cache DOM queries
>
> Query DOM elements once, not in every frame:
>
> ```ts theme={null}
> // Good: Query once
> const box = document.getElementById('box');
> helios.subscribe((state) => {
>     if (box) {
>         box.style.transform = `translateX(${state.currentFrame * 5}px)`;
>     }
> });
>
> // Avoid: Query every frame
> helios.subscribe((state) => {
>     const box = document.getElementById('box'); // ❌
>     // ...
> });
> ```

> [accordion] Use requestAnimationFrame for smoothness
>
> For interactive animations, combine with `requestAnimationFrame`:
>
> ```ts theme={null}
> let latestState = helios.getState();
>
> helios.subscribe((state) => {
>     latestState = state;
> });
>
> function render() {
>     // Use latestState for rendering
>     const progress = latestState.currentFrame / (helios.duration * helios.fps);
>     // Update DOM...
>     requestAnimationFrame(render);
> }
>
> requestAnimationFrame(render);
> ```

> [accordion] Always bind to document timeline
>
> Enable external control for rendering and playback:
>
> ```ts theme={null}
> const helios = new Helios({ duration: 5, fps: 30 });
> helios.bindToDocumentTimeline();
> (window as any).helios = helios;
> ```

> [accordion] Clean up when needed
>
> Unsubscribe when removing animations:
>
> ```ts theme={null}
> const unsubscribe = helios.subscribe((state) => {
>     // Animation logic
> });
>
> // Later, when cleaning up:
> unsubscribe();
> ```

## TypeScript support

Helios is built with TypeScript and provides full type safety:

```ts theme={null}
import type { Helios, HeliosState } from '@helios-project/core';

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

helios.subscribe((state: HeliosState) => {
    const { currentFrame, duration, fps } = state;
    // Type-safe state access
});
```

## Next steps

> [card] [Animation helpers](https://docs.heliosrender.com/features/animation-helpers.md)
>
> Learn about interpolation, spring physics, and easing functions

> [card] [Canvas rendering](https://docs.heliosrender.com/guides/canvas)
>
> Create high-performance canvas animations

> [card] [Sequences](https://docs.heliosrender.com/guides/sequences)
>
> Build complex multi-scene animations

> [card] [Export videos](https://docs.heliosrender.com/guides/export)
>
> Render your animations to video files


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.