Skip to content

Renderer

A Renderer provides an automatic render loop for a Scene, powered by requestAnimationFrame. It continuously re-renders the scene each frame, enabling smooth animations and interactive effects. The renderer also provides a transition() method for animating element properties.

Creating a Renderer

ts
import {
    createRenderer,
    createScene,
} from '@ripl/core';

const scene = createScene('.my-container', {
    children: [circle, rect],
});

const renderer = createRenderer(scene);

Options

OptionTypeDefaultDescription
autoStartbooleantrueStart the render loop immediately
autoStopbooleantrueStop the render loop when idle (no transitions, mouse leaves)
ts
const renderer = createRenderer(scene, {
    autoStart: false,
    autoStop: false,
});

Properties

PropertyTypeDescription
isBusybooleanWhether any transitions are currently running
autoStartbooleanWhether the renderer auto-starts
autoStopbooleanWhether the renderer auto-stops when idle

Render Loop

When running, the renderer executes a tick on every animation frame:

  1. Clears the context
  2. Advances all active transitions
  3. Renders every element in the scene buffer
  4. Requests the next frame

With autoStop enabled (default), the renderer automatically stops when there are no active transitions and the mouse leaves the scene. It restarts when the mouse re-enters or a new transition is created.

Transitions

The transition() method smoothly animates element properties from their current values to new target values. It returns a Promise-like Transition that resolves when the animation completes.

Basic Transition

ts
await renderer.transition(circle, {
    duration: 1000,
    state: {
        radius: 100,
        fillStyle: '#ff006e',
    },
});

Transition Options

OptionTypeDefaultDescription
durationnumber0Duration in milliseconds
easeEaseeaseLinearEasing function
delaynumber0Delay before starting (ms)
loopbooleanfalseLoop the transition
direction'forward' | 'reverse''forward'Playback direction
stateobjectTarget property values
onComplete(element) => voidCallback when each element completes

Easing Functions

Ripl provides a full set of easing functions:

ts
import {
    easeInCubic,
    easeInOutCubic, easeInOutQuad, easeInOutQuart,
    easeInOutQuint, easeInQuad, easeInQuart,
    easeInQuint, easeLinear, easeOutCubic,
    easeOutQuad, easeOutQuart, easeOutQuint,
} from '@ripl/core';

await renderer.transition(circle, {
    duration: 800,
    ease: easeOutCubic,
    state: { radius: 100 },
});

Chaining Transitions

Because transition() returns a promise, you can chain animations sequentially:

ts
await renderer.transition(circle, {
    duration: 500,
    ease: easeOutCubic,
    state: { radius: 100 },
});

await renderer.transition(circle, {
    duration: 500,
    ease: easeOutCubic,
    state: { radius: 50 },
});

Animating Multiple Elements

Pass an array of elements or a group to animate them all with the same options:

ts
await renderer.transition([circle, rect], {
    duration: 800,
    ease: easeOutCubic,
    state: { fillStyle: '#ff006e' },
});

Per-Element Options

Pass a function instead of an options object to customize the transition per element. This is useful for staggered animations:

ts
await renderer.transition(group, (element, index, total) => ({
    duration: 500,
    delay: index * 100, // stagger by 100ms
    ease: easeOutCubic,
    state: { fillStyle: '#ff006e' },
}));

Manual Control

start()

Manually start the render loop:

ts
renderer.start();

stop()

Manually stop the render loop. Clears all active transitions:

ts
renderer.stop();

Events

EventPayloadDescription
start{ startTime }Render loop started
stop{ startTime, endTime }Render loop stopped
ts
renderer.on('start', (event) => {
    console.log('Renderer started at', event.data.startTime);
});

Cleanup

The renderer automatically destroys itself when the scene is destroyed. You can also destroy it manually:

ts
renderer.destroy(); // stops the loop and cleans up

Demo

Click "Animate" to run a transition. Click "Stagger" to see per-element staggered animation.