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.
Helios works perfectly with vanilla JavaScript, giving you complete control without framework overhead.
Quick start
Install Helios
npm install @helios-project/core
Create your first animation
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 ();
Add animation logic
// 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
DOM animations
Canvas animations
Directly manipulate DOM elements in the subscribe callback: 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 ;
Draw frame-by-frame animations on a canvas: 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:
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:
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:
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:
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
Query DOM elements once, not in every frame: // 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' ); // ❌
// ...
});
Use requestAnimationFrame for smoothness
For interactive animations, combine with requestAnimationFrame: 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 );
Always bind to document timeline
Enable external control for rendering and playback: const helios = new Helios ({ duration: 5 , fps: 30 });
helios . bindToDocumentTimeline ();
( window as any ). helios = helios ;
Unsubscribe when removing animations: const unsubscribe = helios . subscribe (( state ) => {
// Animation logic
});
// Later, when cleaning up:
unsubscribe ();
TypeScript support
Helios is built with TypeScript and provides full type safety:
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
Animation helpers Learn about interpolation, spring physics, and easing functions
Canvas rendering Create high-performance canvas animations
Sequences Build complex multi-scene animations
Export videos Render your animations to video files