Ani
Core API

timeline (WebAPI)

The main controller that runs an animation, manages its state, and controls its playback. Powered by the Web Animations API.

The dynamicTimeline API compiles your declarative animation tree into native browser keyframes and plays them using Element.animate(). This allows animations to run on the compositor thread (where possible), resulting in silky smooth performance even when the JavaScript main thread is busy.

Example

import { a } from "@freestylejs/ani-core";

// 1. Define the animation structure.
const myAnimation = a.sequence([
  a.ani({ to: { translateX: 100 }, duration: 1 }),
  a.ani({ to: { translateY: 100 }, duration: 1 }),
]);

// 2. Create a web-native timeline.
const timeline = a.timeline(myAnimation);

// 3. Play on a specific DOM element.
const element = document.getElementById("box");
if (element) {
    timeline.play(element, {
        from: { translateX: 0, translateY: 0 },
        repeat: Infinity
    });
}

Usage & Concepts

Overview

Unlike the standard dynamicTimeline which runs frame-by-frame via JavaScript, timeline uses the browser's native animation engine. This offers significant performance benefits, especially for continuous animations (loops) or on lower-end devices.

Runs natively using web AnimationAPI, timeline does not emit onUpdate events.

State management is handled entirely by the browser's CSSOM calculations.

Key Differences from dynamicTimeline

FeaturedynamicTimeline (JS)timeline (Native)
EngineJavaScript requestAnimationFrameBrowser Element.animate()
PerformanceGood, but blocked by main threadExcellent, often compositor-threaded
EventsonUpdate for every frameNo frame updates
PropertiesAny numeric propertyCSS properties only

Best Practices

  • Do use timeline for purely visual UI transitions (fades, slides, scaling) and infinite background loops.
  • Do use standard CSS property names like translateX instead of shorthands like x to ensure compatibility.
  • Don't use timeline if you need to sync non-DOM elements (like Canvas or WebGL) or if you need to react to value changes every frame.

Limitation 1: Internal Value Can not be accessed.

Use dynamicTimeline, if you should access internal animation value directly.

timeline uses WebAnimationAPI so we can not access value directly, which is managed by browser internal logics.

But you can access animation values via getAnimations api, but it is not recommended approach.

Timing Functions

Since timeline compiles to native CSS Keyframes, standard easing functions are compiled directly to CSS strings, while complex physics-based timings are sampled into a series of linear keyframes.

Timing FunctionCompilation Behavior
linear()Compiles to linear. Recommended.
bezier()Compiles to cubic-bezier(...). Recommended.
spring()Sampled(but can not be duration goes into Infinity). Compiles into high-density linear keyframes (60fps).
dynamicSpring()Sampled(but can not be duration goes into Infinity). Compiles frame-by-frame stateful simulation.
User CustomSampled, provided the function is stateless (pure function of time).

Note: Using spring() or custom timing functions with timeline will generate a larger number of keyframes to approximate the curve. This is generally performant but significantly more verbose than standard CSS easing. Stateful animations like dynamicSpring (which depend on velocity from the previous frame) cannot be pre-compiled and are not supported.