Animatable objects system for creating chainable property methods that automatically generate animations, enabling a fluent API for animation control.
Create animatable object with chainable property methods for fluid animation workflows.
/**
* Create animatable object with chainable property methods
* Each property becomes a method that animates to the provided value
* @param targets - Target elements or objects to make animatable
* @param parameters - Animatable configuration
* @returns AnimatableObject with animated property methods
*/
function createAnimatable(
targets: TargetsParam,
parameters?: AnimatableParams
): AnimatableObject;Usage Example:
import { createAnimatable } from "animejs/animatable";
const box = createAnimatable(".box", {
duration: 1000,
ease: "outQuad",
});
// Chainable property animations
box
.translateX(250)
.wait(500)
.translateY(100)
.wait(300)
.rotate(360)
.scale(1.5);Base class for animatable objects with property animation tracking.
/**
* Animatable base class
* Manages property animations and provides lifecycle control
*/
class Animatable {
/**
* Array of animation targets
*/
targets: Array<HTMLElement | SVGElement | object>;
/**
* Object containing property animations
* Keys are property names, values are JSAnimation instances
*/
animations: Record<string, JSAnimation>;
/**
* JSAnimation instance for managing callbacks
*/
callbacks: JSAnimation;
/**
* Revert all animations to initial state
* Cancels all property animations and restores original values
* @returns Animatable instance for chaining
*/
revert(): Animatable;
}Animatable object with dynamic property methods and chainable API.
/**
* Animatable object with property methods
* Properties become methods that animate to provided values
*/
interface AnimatableObject extends Animatable {
/**
* Wait specified duration before next animation
* @param duration - Wait duration in milliseconds
* @returns AnimatableObject for chaining
*/
wait(duration: number): AnimatableObject;
/**
* Add callback function
* @param callback - Function to execute
* @returns AnimatableObject for chaining
*/
then(callback: Function): AnimatableObject;
/**
* Revert all animations
* @returns AnimatableObject for chaining
*/
revert(): AnimatableObject;
/**
* Dynamic property methods
* Any property can be animated as a method
* @example box.translateX(100).opacity(0.5).rotate(360)
*/
[property: string]: (value: TweenParamValue) => AnimatableObject;
}Usage Examples:
import { createAnimatable } from "animejs/animatable";
// Create animatable with defaults
const box = createAnimatable(".box", {
duration: 800,
ease: "outCubic",
});
// Chain property animations
box.opacity(0).translateX(200).rotate(180);
// Wait between animations
box.scale(1.5).wait(500).scale(1);
// Callbacks
box
.translateY(100)
.then(() => console.log("First animation done"))
.translateY(0)
.then(() => console.log("Second animation done"));
// Revert all animations
box.revert();Configure default animation parameters for all property animations:
const animatable = createAnimatable(".element", {
// Default duration
duration: 1000,
// Default easing
ease: "outQuad",
// Default composition
composition: "blend",
// Default delay
delay: 0,
// Callbacks apply to all animations
onComplete: () => console.log("Animation complete"),
});Every CSS, SVG, or object property becomes a chainable method:
import { createAnimatable } from "animejs/animatable";
const box = createAnimatable(".box");
// CSS transforms
box
.translateX(250)
.translateY(100)
.rotate(360)
.scale(1.5)
.scaleX(2)
.scaleY(0.5);
// CSS properties
box
.opacity(0.5)
.backgroundColor("#ff0000")
.width("200px")
.height("200px");
// SVG attributes
const circle = createAnimatable("circle");
circle.r(50).cx(100).cy(100).fill("#0000ff");
// JS object properties
const obj = { value: 0, progress: 0 };
const animated = createAnimatable(obj);
animated.value(100).progress(1);Add delays between chained animations:
const box = createAnimatable(".box");
box
.translateX(100)
.wait(500) // Wait 500ms
.translateY(100)
.wait(1000) // Wait 1s
.translateX(0)
.translateY(0);Execute functions in the animation chain:
const box = createAnimatable(".box");
box
.translateX(250)
.then(() => {
console.log("Reached right side");
})
.wait(500)
.translateX(0)
.then(() => {
console.log("Back to start");
});Each property animation can be controlled independently:
const box = createAnimatable(".box");
box.translateX(250).translateY(100).rotate(360);
// Access individual property animations
console.log(box.animations.translateX); // JSAnimation for translateX
console.log(box.animations.translateY); // JSAnimation for translateY
console.log(box.animations.rotate); // JSAnimation for rotate
// Control specific property animation
box.animations.rotate.pause();
box.animations.translateX.seek(500);Animatable provides a property-centric API compared to Timeline's time-centric API:
import { createAnimatable, createTimeline } from "animejs";
// Animatable: Property-centric
const animatable = createAnimatable(".box");
animatable
.translateX(100)
.wait(500)
.translateY(100)
.rotate(360);
// Timeline: Time-centric
const timeline = createTimeline();
timeline
.add(".box", { translateX: 100 })
.add(".box", { translateY: 100 }, "+=500")
.add(".box", { rotate: 360 });Build complex sequences with property animations:
const card = createAnimatable(".card", {
duration: 600,
ease: "outCubic",
});
// Intro animation
card
.opacity(0)
.translateY(-50)
.scale(0.8)
.wait(0)
.opacity(1)
.translateY(0)
.scale(1)
.then(() => console.log("Card revealed"))
.wait(2000)
// Hover effect
.scale(1.05)
.wait(300)
.scale(1)
.wait(1000)
// Exit animation
.opacity(0)
.translateY(50)
.scale(0.8)
.then(() => console.log("Card hidden"));Animate multiple elements with one animatable:
const boxes = createAnimatable(".box", {
duration: 800,
ease: "outQuad",
});
// All boxes animate together
boxes
.translateX(200)
.wait(500)
.translateY(100)
.rotate(180);Cancel and revert all property animations:
const box = createAnimatable(".box");
box
.translateX(250)
.translateY(100)
.rotate(360)
.scale(1.5);
// Later, cancel and revert everything
box.revert();
// Element returns to original stateCombine animatable with stagger for multi-element animations:
import { createAnimatable, stagger } from "animejs";
const items = createAnimatable(".item", {
duration: 600,
ease: "outQuad",
});
// Properties can use stagger
items.translateX(stagger([0, 200]));
items.opacity(stagger([0, 1]));
items.delay = stagger(100);Use animatable for interactive UI patterns:
const button = createAnimatable(".button");
button.$target.addEventListener("mouseenter", () => {
button.scale(1.1).backgroundColor("#ff6b6b");
});
button.$target.addEventListener("mouseleave", () => {
button.scale(1).backgroundColor("#4ecdc4");
});
button.$target.addEventListener("click", () => {
button
.scale(0.95)
.wait(100)
.scale(1.1)
.wait(100)
.scale(1);
});Use function values for dynamic property values:
import { createAnimatable, random } from "animejs";
const particles = createAnimatable(".particle");
// Function values for randomization
particles.translateX(() => random(-200, 200));
particles.translateY(() => random(-200, 200));
particles.scale(() => random(0.5, 1.5, 2));
particles.opacity(() => random(0.3, 1, 2));const loader = createAnimatable(".loader", {
duration: 1000,
ease: "inOutQuad",
loop: true,
direction: "alternate",
});
loader.rotate(360).scale([0.8, 1.2]);const notification = createAnimatable(".notification", {
duration: 400,
ease: "outBack",
});
notification
.opacity(0)
.translateY(-20)
.wait(0)
.opacity(1)
.translateY(0)
.then(() => console.log("Notification shown"))
.wait(3000)
.opacity(0)
.translateY(-20)
.then(() => console.log("Notification hidden"));const accordion = createAnimatable(".accordion-content", {
duration: 300,
ease: "outQuad",
});
function toggle() {
if (isOpen) {
accordion.height(0).opacity(0);
} else {
accordion.height("auto").opacity(1);
}
isOpen = !isOpen;
}const slide = createAnimatable(".carousel-slide", {
duration: 600,
ease: "outCubic",
});
function nextSlide() {
slide
.translateX(-100)
.opacity(0)
.wait(0)
.translateX(100)
.wait(0)
.translateX(0)
.opacity(1);
}
function prevSlide() {
slide
.translateX(100)
.opacity(0)
.wait(0)
.translateX(-100)
.wait(0)
.translateX(0)
.opacity(1);
}Animate plain JavaScript objects:
const data = { value: 0, progress: 0, count: 0 };
const animated = createAnimatable(data, {
duration: 2000,
});
animated
.value(100)
.progress(1)
.count(50)
.then(() => {
console.log(data); // { value: 100, progress: 1, count: 50 }
});Access the animatable's targets:
const box = createAnimatable(".box");
// Access targets array
console.log(box.targets); // Array of elements
// Access first target
const element = box.targets[0];/**
* Animatable configuration parameters
*/
interface AnimatableParams {
/** Default animation duration */
duration?: number;
/** Default easing function */
ease?: EasingParam;
/** Default composition mode */
composition?: TweenComposition;
/** Default delay */
delay?: number;
/** Default loop count */
loop?: number | boolean;
/** Default direction */
direction?: "normal" | "reverse" | "alternate";
/** Callbacks */
onBegin?: Callback<JSAnimation>;
onUpdate?: Callback<JSAnimation>;
onComplete?: Callback<JSAnimation>;
/** Any other animation parameter */
[key: string]: any;
}
/**
* Animatable object with property methods
*/
interface AnimatableObject extends Animatable {
/** Wait duration before next animation */
wait(duration: number): AnimatableObject;
/** Execute callback function */
then(callback: Function): AnimatableObject;
/** Revert all animations */
revert(): AnimatableObject;
/** Dynamic property methods */
[property: string]: (value: TweenParamValue) => AnimatableObject;
}
/**
* Tween parameter value types
*/
type TweenParamValue =
| number
| string
| [number | string, number | string]
| FunctionValue
| Array<number | string>;
/**
* Function value for dynamic values
*/
type FunctionValue = (
target: any,
index: number,
total: number
) => number | string;
/**
* Targets parameter type
*/
type TargetsParam =
| string
| HTMLElement
| SVGElement
| NodeList
| Array<HTMLElement | SVGElement>
| object
| Array<object>;
/**
* Callback function type
*/
type Callback<T> = (instance: T) => void;