Overview
The Animatable module creates reactive animation controllers that allow you to dynamically update animated values with automatic smooth transitions. Perfect for interactive animations, game development, and UI that responds to user input.
Importing
import { createAnimatable, Animatable } from 'animejs';
Creating Animatables
createAnimatable()
Create a reactive animation controller:
const animatable = createAnimatable(targets, parameters);
Parameters:
targets - DOM elements or objects to animate
parameters - Configuration object defining animatable properties
Basic Example
import { createAnimatable } from 'animejs';
const box = createAnimatable('.box', {
translateX: 0,
translateY: 0,
scale: 1
});
// Later, smoothly transition to new values
box.translateX(250);
box.scale(1.5);
Configuration
Property Definitions
Define animatable properties with durations:
const element = createAnimatable('.element', {
translateX: 500, // Default duration (500ms)
translateY: 800, // Another duration
rotate: 1000, // 1 second duration
opacity: 300 // 300ms duration
});
Advanced Property Configuration
Use object syntax for more control:
const element = createAnimatable('.element', {
translateX: {
duration: 600,
unit: 'px',
modifier: (value) => Math.round(value)
},
scale: {
duration: 400,
composition: 'blend'
}
});
Transition duration in milliseconds
Unit to append to values (e.g., ‘px’, ’%’, ‘deg’)
Function to modify values before rendering
Composition mode: ‘replace’, ‘blend’, or ‘none’
Updating Values
Simple Updates
Call property methods to animate to new values:
const box = createAnimatable('.box', {
translateX: 500,
translateY: 500,
rotate: 800
});
// Animate to new values
box.translateX(300); // Animate to 300 over 500ms
box.translateY(150); // Animate to 150 over 500ms
box.rotate(180); // Animate to 180 over 800ms
Chaining Updates
Property methods return the animatable instance:
const box = createAnimatable('.box', {
x: 500,
y: 500,
scale: 500
});
box.x(100)
.y(200)
.scale(1.5);
Custom Duration and Easing
Override duration and easing per update:
const box = createAnimatable('.box', {
translateX: 500
});
// Update with custom duration
box.translateX(300, 1000);
// Update with custom duration and easing
box.translateX(200, 800, 'inOutQuad');
box.translateX(100, 600, 'spring');
Reading Values
Get Current Value
Call property method with no arguments:
const box = createAnimatable('.box', {
translateX: 500,
scale: 500
});
box.translateX(200);
// Get current value
const currentX = box.translateX(); // Returns current animated value
const currentScale = box.scale();
Array Values
For complex properties that return arrays:
const element = createAnimatable('.element', {
transform: 500
});
// Set array of values
element.transform([1, 0, 0, 1, 100, 200]);
// Get current array
const current = element.transform(); // Returns array
Interactive Examples
Mouse Tracking
const cursor = createAnimatable('.cursor', {
translateX: 300,
translateY: 300
});
document.addEventListener('mousemove', (e) => {
cursor.translateX(e.clientX);
cursor.translateY(e.clientY);
});
const parallax = createAnimatable('.parallax', {
translateY: 800
});
window.addEventListener('scroll', () => {
const scrollY = window.scrollY;
parallax.translateY(scrollY * 0.5); // Parallax effect
});
const player = createAnimatable('.player', {
translateX: 200,
translateY: 200,
rotate: 400
});
function updatePlayer(joystickX, joystickY, angle) {
player.translateX(joystickX * 500)
.translateY(joystickY * 500)
.rotate(angle);
}
Smooth Value Following
const follower = createAnimatable('.follower', {
x: 800,
y: 800,
scale: 400
});
let targetX = 0;
let targetY = 0;
setInterval(() => {
// Smooth follow behavior
follower.x(targetX)
.y(targetY);
}, 16);
// Update target on interaction
document.addEventListener('click', (e) => {
targetX = e.clientX;
targetY = e.clientY;
});
Global Callbacks
Animatables support global callbacks:
Called when first property starts animating
Called on every frame update
Called when all properties finish animating
const box = createAnimatable('.box', {
translateX: 500,
translateY: 500,
onBegin: () => {
console.log('Animation started');
},
onUpdate: () => {
console.log('Updating...');
},
onComplete: () => {
console.log('All animations complete');
}
});
box.translateX(200).translateY(300);
Animatable Properties
Array of target elements/objects
Object containing animation instances for each property
Animation instance managing global callbacks
const box = createAnimatable('.box', {
x: 500,
y: 500
});
console.log(box.targets); // [HTMLElement]
console.log(box.animations); // { x: Animation, y: Animation }
Revert and Cleanup
.revert()
Cleanup animatable and revert all animations:
const box = createAnimatable('.box', {
translateX: 500,
translateY: 500
});
box.translateX(200).translateY(100);
// Later, cleanup
box.revert();
// Properties are now noop functions
box.translateX(300); // Does nothing
Advanced Usage
Multiple Targets
const boxes = createAnimatable('.box', {
scale: 400,
rotate: 600
});
// All .box elements animate together
boxes.scale(1.5).rotate(90);
Custom Modifiers
const counter = createAnimatable('.counter', {
textContent: {
duration: 2000,
modifier: (value) => Math.floor(value)
}
});
counter.textContent(100); // Counts from 0 to 100
Mixed Units
const element = createAnimatable('.element', {
width: { duration: 500, unit: 'px' },
height: { duration: 500, unit: '%' },
rotate: { duration: 800, unit: 'deg' }
});
element.width(300) // 300px
.height(50) // 50%
.rotate(180); // 180deg
Animatables are optimized for frequent updates. Each property has its own animation instance, allowing independent timing.
Avoid creating animatables in loops or on every frame. Create once and reuse.
// Good: Create once
const player = createAnimatable('.player', {
x: 200,
y: 200
});
function update(newX, newY) {
player.x(newX).y(newY);
}
// Bad: Creating every frame
function update(newX, newY) {
// Don't do this!
const player = createAnimatable('.player', { x: 200, y: 200 });
player.x(newX).y(newY);
}
Complete Example
import { createAnimatable } from 'animejs';
// Create animatable with multiple properties
const spaceship = createAnimatable('.spaceship', {
translateX: { duration: 200, unit: 'px' },
translateY: { duration: 200, unit: 'px' },
rotate: { duration: 400, unit: 'deg' },
scale: { duration: 300 },
onUpdate: () => {
// Update game state
},
onComplete: () => {
console.log('Movement complete');
}
});
// Keyboard controls
document.addEventListener('keydown', (e) => {
const current = {
x: spaceship.translateX(),
y: spaceship.translateY(),
angle: spaceship.rotate()
};
switch(e.key) {
case 'ArrowUp':
spaceship.translateY(current.y - 50);
break;
case 'ArrowDown':
spaceship.translateY(current.y + 50);
break;
case 'ArrowLeft':
spaceship.translateX(current.x - 50)
.rotate(current.angle - 15);
break;
case 'ArrowRight':
spaceship.translateX(current.x + 50)
.rotate(current.angle + 15);
break;
case ' ':
spaceship.scale(1.2, 100, 'outQuad');
setTimeout(() => spaceship.scale(1, 100), 100);
break;
}
});