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

# Svelte integration

> Use Helios with Svelte for reactive video animations

Helios integrates beautifully with Svelte's reactive system through stores that automatically update your animations.

## Quick start

**1. Install dependencies**

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

**2. Create the Helios store**

```js lib/store.js theme={null}
import { readable } from 'svelte/store';

export const createHeliosStore = (helios) => {
    return readable(helios.getState(), (set) => {
        set(helios.getState());
        const unsubscribe = helios.subscribe((state) => {
            set(state);
        });
        return unsubscribe;
    });
};
```

**3. Create your first animation**

```svelte App.svelte theme={null}
<script>
  import { onMount } from 'svelte';
  import { Helios } from '@helios-project/core';
  import { createHeliosStore } from './lib/store';

  const duration = 5;
  const fps = 30;

  // Initialize Helios
  const helios = new Helios({
    duration,
    fps
  });

  helios.bindToDocumentTimeline();

  if (typeof window !== 'undefined') {
    window.helios = helios;
  }

  const heliosStore = createHeliosStore(helios);
</script>

<div class="container">
    <div
        class="box"
        style:opacity={$heliosStore.currentFrame / (duration * fps)}
        style:transform={`rotate(${$heliosStore.currentFrame * 2}deg)`}
    >
        Svelte DOM
    </div>
</div>

<style>
  :global(body) {
    margin: 0;
    overflow: hidden;
    background-color: #111;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .container {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 100vh;
  }
  .box {
    width: 200px;
    height: 200px;
    background-color: royalblue;
    color: white;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 24px;
    font-family: sans-serif;
    border-radius: 10px;
  }
</style>
```

## Animation approaches

> [tab] DOM animations
>
> Animate Svelte components using reactive store subscriptions:
>
> ```svelte theme={null}
> <script>
>   import { createHeliosStore } from './lib/store';
>
>   const heliosStore = createHeliosStore(helios);
> </script>
>
> <div
>   style:opacity={Math.min(1, $heliosStore.currentFrame / 30)}
>   style:transform={`translateX(${$heliosStore.currentFrame * 5}px) rotate(${$heliosStore.currentFrame * 2}deg)`}
> >
>   Animated content
> </div>
> ```

> [tab] Canvas animations
>
> Use reactive statements to draw frame-by-frame animations:
>
> ```svelte theme={null}
> <script>
>   import { onMount, onDestroy } from 'svelte';
>   import { Helios } from '@helios-project/core';
>   import { createHeliosStore } from './lib/store';
>
>   let canvas;
>   let ctx;
>   const duration = 5;
>   const fps = 30;
>
>   // Initialize Helios
>   const helios = new Helios({
>     duration,
>     fps
>   });
>
>   helios.bindToDocumentTimeline();
>
>   if (typeof window !== 'undefined') {
>     window.helios = helios;
>   }
>
>   const heliosStore = createHeliosStore(helios);
>
>   // Reactive drawing
>   $: if (ctx && $heliosStore) {
>     draw($heliosStore.currentFrame);
>   }
>
>   function draw(currentFrame) {
>       const time = currentFrame / fps * 1000;
>       const progress = (time % (duration * 1000)) / (duration * 1000);
>
>       const width = canvas.width;
>       const height = canvas.height;
>
>       // Clear
>       ctx.fillStyle = '#111';
>       ctx.fillRect(0, 0, width, height);
>
>       const x = progress * width;
>       const y = height / 2;
>       const radius = 50;
>
>       // Draw moving circle
>       ctx.fillStyle = 'royalblue';
>       ctx.beginPath();
>       ctx.arc(x, y, radius, 0, Math.PI * 2);
>       ctx.fill();
>
>       // Draw rotating square
>       const squareSize = 100;
>       ctx.save();
>       ctx.translate(width / 2, height / 2);
>       ctx.rotate(progress * Math.PI * 2);
>       ctx.fillStyle = 'tomato';
>       ctx.fillRect(-squareSize / 2, -squareSize / 2, squareSize, squareSize);
>       ctx.restore();
>   }
>
>   const resizeCanvas = () => {
>     canvas.width = window.innerWidth;
>     canvas.height = window.innerHeight;
>     if (ctx && $heliosStore) {
>       draw($heliosStore.currentFrame);
>     }
>   };
>
>   onMount(() => {
>     ctx = canvas.getContext('2d');
>     resizeCanvas();
>     window.addEventListener('resize', resizeCanvas);
>   });
>
>   onDestroy(() => {
>      if (typeof window !== 'undefined') {
>         window.removeEventListener('resize', resizeCanvas);
>      }
>   });
>
> </script>
>
> <canvas bind:this={canvas} style="display: block; width: 100%; height: 100%;"></canvas>
>
> <style>
>   :global(body) {
>     margin: 0;
>     overflow: hidden;
>     background-color: #111;
>   }
> </style>
> ```

## Animation helpers

Helios provides utility functions for common animation patterns:

```svelte theme={null}
<script>
  import { interpolate, spring } from '@helios-project/core';
  import { createHeliosStore } from './lib/store';

  const heliosStore = createHeliosStore(helios);

  // Reactive computed values
  $: x = interpolate($heliosStore.currentFrame, [0, 60], [0, 200], { extrapolateRight: 'clamp' });
  $: scale = spring({ 
    frame: $heliosStore.currentFrame, 
    fps: 30, 
    from: 0, 
    to: 1, 
    config: { stiffness: 100 } 
  });
</script>

<div style:transform={`translateX(${x}px) scale(${scale})`}
     style:width="100px"
     style:height="100px"
     style:background="hotpink">
  Animated
</div>
```

## Svelte 5 runes

For Svelte 5, you can use runes for reactive state:

```svelte theme={null}
<script>
  import { Helios } from '@helios-project/core';

  let frame = $state(0);

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

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

  let progress = $derived(frame / (5 * 30));
  let rotation = $derived(progress * 360);
</script>

<div style:transform={`rotate(${rotation}deg)`}>
  Svelte 5 Animation
</div>
```

## Sequencing patterns

Create sequences manually using reactive statements:

```svelte theme={null}
<script>
  import { createHeliosStore } from './lib/store';

  const heliosStore = createHeliosStore(helios);

  // Define sequences
  $: sequence1Active = $heliosStore.currentFrame >= 0 && $heliosStore.currentFrame < 30;
  $: sequence2Active = $heliosStore.currentFrame >= 30 && $heliosStore.currentFrame < 60;
  $: sequence3Active = $heliosStore.currentFrame >= 60 && $heliosStore.currentFrame < 90;
</script>

{#if sequence1Active}
  <div class="box red">Sequence 1</div>
{/if}

{#if sequence2Active}
  <div class="box blue">Sequence 2</div>
{/if}

{#if sequence3Active}
  <div class="box green">Sequence 3</div>
{/if}
```

## Best practices

> [accordion] Use readable stores
>
> Create readable stores for Helios state to prevent accidental modifications:
>
> ```js theme={null}
> import { readable } from 'svelte/store';
>
> export const createHeliosStore = (helios) => {
>     return readable(helios.getState(), (set) => {
>         const unsubscribe = helios.subscribe(set);
>         return unsubscribe;
>     });
> };
> ```

> [accordion] Use reactive statements for animations
>
> Leverage Svelte's `$:` reactive statements for derived animation values:
>
> ```svelte theme={null}
> <script>
>   $: progress = $heliosStore.currentFrame / (duration * fps);
>   $: rotation = progress * 360;
>   $: scale = 1 + Math.sin(progress * Math.PI) * 0.5;
> </script>
> ```

> [accordion] Clean up event listeners
>
> Always remove event listeners in `onDestroy`:
>
> ```svelte theme={null}
> <script>
>   import { onMount, onDestroy } from 'svelte';
>
>   onMount(() => {
>     window.addEventListener('resize', handleResize);
>   });
>
>   onDestroy(() => {
>     window.removeEventListener('resize', handleResize);
>   });
> </script>
> ```

> [accordion] Use style directives
>
> Use Svelte's `style:` directive for dynamic inline styles:
>
> ```svelte theme={null}
> <div 
>   style:transform={`rotate(${rotation}deg)`}
>   style:opacity={opacity}
> >
>   Content
> </div>
> ```

## TypeScript support

Helios works seamlessly with Svelte and TypeScript:

```ts theme={null}
import type { Helios } from '@helios-project/core';
import type { Readable } from 'svelte/store';
import { readable } from 'svelte/store';

interface HeliosState {
    currentFrame: number;
    duration: number;
    fps: number;
}

export function createHeliosStore(helios: Helios): Readable<HeliosState> {
    return readable(helios.getState(), (set) => {
        const unsubscribe = helios.subscribe((state) => {
            set(state);
        });
        return unsubscribe;
    });
}
```

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