Appearance
Tweens
The Tween is the basic building block of animation in AnimX. It smoothly changes an element's properties over time, reading the current style as the starting point and automatically updating the screen every frame.
AnimX handles all the complex math and rendering automatically based on the final values you provide.
Instantiation Methods
AnimX gives you four main ways to create an animation, depending on what you need to do:
| Method | What it does |
|---|---|
AnimX.animate(targets, options) | Animates from current state → to your values |
AnimX.animateFrom(targets, options) | Snaps to your values instantly, then animates back to current state |
AnimX.sequence(targets, from, to) | You control both ends — animates from → to |
AnimX.apply(targets, options) | No animation — instantly sets properties |
Flexible Types
The targets parameter accepts multiple formats (CSS Selectors, DOM Elements, NodeLists, or Arrays). Refer to the Flexible Types guide for resolution mechanics.
Use animate for normal animations, animateFrom for things appearing on screen, sequence when you need exact start and end points, and apply for instant changes.
Forward Animation
AnimX.animate(target, options) reads the element's current style when it runs, and smoothly animates toward your new values. The options object lets you set the properties, duration, easing, and other settings.
The first argument is what you want to animate, and the second is how you want to animate it.
AnimX supports native shorthand properties for CSS transforms:
| Shorthand | CSS equivalent |
|---|---|
x, y, z | translateX, translateY, translateZ |
rotation | rotate (degrees) |
rotationX, rotationY | rotateX, rotateY |
scale, scaleX, scaleY | scale() |
skewX, skewY | skew() |
Standard CSS properties are supported using camelCase notation (e.g., backgroundColor, borderRadius, opacity, width, fontSize).
js
AnimX.animate('.box', {
x: 220, // px by default
opacity: 0.5,
backgroundColor: '#ff2d6a',
borderRadius: '50%',
duration: 1,
})Duration and Delay
duration sets how long the animation takes in seconds (default: 0.5s).
delay is how long to wait before starting the animation (in seconds).
js
AnimX.animate('.box', {
x: 300,
duration: 1.2, // takes 1.2 seconds
delay: 0.4, // waits 400ms before starting
})Neither duration nor delay affect the tween's position in a Timeline — that's controlled by the position argument you pass to .animate() on the timeline.
animateFrom — Entrance Interpolation
animateFrom plays an animation backward. It instantly jumps to your provided values, and then animates back to the element's original style.
This is perfect for entrance animations. You don't need to write messy CSS to hide things before they animate in:
js
// On page load, the card appears from below
AnimX.animateFrom('.card', {
y: 60, // start 60px below
opacity: 0, // start invisible
duration: 0.7,
ease: 'expo.out',
})When finished, the element ends up exactly how you styled it in CSS.
AnimX.sequence lets you define exactly where the animation starts and ends:
js
AnimX.sequence('.box',
{ x: -100, opacity: 0 }, // from
{ x: 0, opacity: 1, duration: 0.6 } // to
)AnimX.apply changes properties instantly without animating. It is great for resetting states:
js
AnimX.apply('.box', { x: 0, opacity: 1 })Easing
Easing controls the speed of the animation over its duration. Different easings make the animation start slow, end slow, or bounce, without changing the total time it takes.
The primary easing families:
linear
power2.out
expo.out
back.out
elastic.out
bounce.out
Easing families support three directional variants:
| Variant | Character |
|---|---|
.in | Initial acceleration |
.out | Terminal deceleration |
.inOut | Bidirectional acceleration/deceleration |
Omitting the variant defaults to .out.
Easing Family Characteristics:
linear— Constant velocity interpolation.power1–4— Exponential curves. Higher numerical suffix indicates steeper acceleration.expo.out— High-velocity initial acceleration with protracted deceleration.back.out— Extrapolates past the target value before settling.elastic.out— Harmonic oscillation around the target value.bounce.out— Simulates inelastic collision decay.
Parameterized easings:
js
ease: 'back.out(2.5)' // default overshoot is 1.70158 — higher = bigger overshoot
ease: 'elastic.out(1, 0.3)' // amplitude, period — lower period = faster oscillation
ease: 'steps(6)' // 6 discrete jumps — like a sprite animation
ease: 'steps(6, start)' // jump at the start of each interval instead of end
ease: 'cubic-bezier(0.34, 1.56, 0.64, 1)' // custom bezier curve
ease: t => t * t // raw easing function — receives 0–1, returns 0–1Repeat & Yoyo
repeat plays the animation multiple times. The number you pass is how many extra times it plays (e.g., repeat: 3 means 4 plays total). Use -1 to loop forever.
yoyo makes the animation play backward on every other loop. Without it, the animation snaps back to the start each time. With it, the animation goes back and forth smoothly.
repeatDelay adds a pause (in seconds) between each loop.
js
// Plays once, then 3 more times = 4 total. Yoyos back between each.
AnimX.animate('.box', {
x: 200,
repeat: 3,
yoyo: true,
repeatDelay: 0.2, // 200ms pause at each end before changing direction
})
// Loop forever
AnimX.animate('.box', { x: 200, repeat: -1, yoyo: true })
// Without yoyo — snaps back to start after each cycle
AnimX.animate('.box', { x: 200, repeat: -1 })The progress bar in the preceding example visually confirms the back-and-forth yoyo effect.
Stagger Execution
When you animate multiple elements at once, they all animate at the exact same time by default.
The stagger property adds a small delay between each element, creating a cascading wave effect.
Simple form — a number, seconds between each element:
js
AnimX.animate('.item', {
y: -30,
stagger: 0.08, // element 0 starts at 0s, element 1 at 80ms, element 2 at 160ms...
})Config form — more control:
js
AnimX.animate('.item', {
y: -30,
stagger: {
each: 0.08, // seconds between each element's start
// OR:
amount: 0.6, // total time window — AnimX distributes all elements across it
from: 'center', // which element starts first:
// 'start' (default), 'end', 'center', 'edges', or an index number
ease: 'power2.in', // curves the *distribution* — elements near the 'from' point
// get their delays closer together; distant ones get spread out
}
})each vs amount: Use each when you want consistent spacing regardless of how many elements there are. Use amount when you want the whole stagger wave to always finish within a fixed time budget.
The from property specifies where the wave starts. Valid options include 'start', 'end', 'center', 'edges', or a specific index number.
The ease option inside stagger changes the timing between elements; it does not change the easing of the animation itself.
2D Grid Configuration — Useful for animating grids of elements:
js
AnimX.animate('.cell', {
scale: 0,
opacity: 0,
stagger: {
amount: 1,
grid: [5, 4], // [columns, rows] — tells AnimX the layout
from: 'center', // starts from the middle cell, ripples outward
}
})Callbacks
AnimX can run your own code at key moments during the animation. These are just normal functions you add to your options object.
press play
js
const tween = AnimX.animate('.box', {
x: 200,
duration: 1.5,
onStart: () => {
// Fires once, when the tween begins playing for the first time.
// Good for adding a CSS class, starting audio, showing a tooltip.
el.classList.add('is-animating')
},
onUpdate: () => {
// Fires every frame while the tween is active.
// Access the tween via the closure — tween.progress is 0→1.
label.textContent = (tween.progress * 100).toFixed(0) + '%'
},
onComplete: () => {
// Fires once, when the tween finishes its last cycle.
// If repeat:-1, this never fires.
el.classList.remove('is-animating')
},
onRepeat: () => {
// Fires each time a cycle repeats (not the first play, not the last complete).
},
onReverseComplete: () => {
// Fires when the tween completes while playing in reverse —
// i.e. it played backward all the way back to t=0.
console.log('back at start')
},
})Note on onUpdate context: You can access the tween.progress property (which goes from 0 to 1) inside your function to see how far along the animation is.
If you want different easing curves for different properties on the same element, use a Timeline:
When you run multiple animations on the same element at the same time, AnimX combines them perfectly.
js
const tl = AnimX.timeline()
tl.animate('.box', { x: 300, duration: 1.4, ease: 'expo.out' }, 0)
tl.animate('.box', { y: -80, duration: 1.4, ease: 'bounce.out' }, 0)Playback Management
Animations start playing automatically unless you set paused: true. You can control them manually using these methods:
js
const tween = AnimX.animate('.box', {
x: 300,
duration: 1.5,
paused: true,
})
tween.play() // start or resume from current position
tween.pause() // freeze at current position
tween.reverse() // play backward from current positionSeeking methods let you skip around the animation:
js
tween.seek(0.75) // jump to 750ms (absolute time in seconds)
tween.progress = 0.5 // jump to 50% — progress is a 0–1 get/set property
tween.progress = 0 // jump back to start
tween.progress = 1 // jump to endtimeScale changes the playback speed without changing the easing curve:
js
tween.timeScale = 2 // plays at 2× speed
tween.timeScale = 0.5 // plays at half speed (slow motion)
tween.timeScale = -1 // plays backward at normal speedinvalidate() clears the animation's memory and forces it to re-read the element's current styles the next time it plays.
js
tween.invalidate() // re-read live DOM values on next play
tween.play()kill() stops the animation completely and cleans it up from memory.
js
tween.kill() // stop + clean up — the tween object becomes inertRelative Values
Numbers starting with +=, -=, or *= are calculated relative to the element's current position when the animation starts.
This lets you move different elements by the same amount, even if they started in different places.
+= Operator
If you animate multiple elements with +=, each element moves relative to its own starting position.
x: 0
x: 50
x: 100
js
// All three boxes shift +110px from wherever they currently are.
// Box at x:0 → ends at x:110
// Box at x:50 → ends at x:160
// Box at x:100 → ends at x:210
AnimX.animate(boxes, { x: '+=110', stagger: 0.1 })-= and *= Operators
-= subtracts from the current value. *= multiplies the current value (useful for scaling or fading).
x: '-=140'
opacity: '*=0.15'
js
// '-=' — moves left by 140px from its current x (160 → 20)
AnimX.animate(minusBox, { x: '-=140', duration: 0.8, ease: 'power2.out' })
// '*=' — multiplies current opacity by 0.15 (1 → 0.15)
AnimX.animate(mulBox, { opacity: '*=0.15', duration: 0.8, ease: 'power2.inOut' })All of these relative values calculate the real, live position of the element exactly when the animation runs.
Quick reference
js
// Four factory methods
AnimX.animate(targets, options) // current → your values
AnimX.animateFrom(targets, options) // your values → current
AnimX.sequence(targets, from, to) // explicit from → to
AnimX.apply(targets, options) // instant set, no animation
// Core timing options
duration // number — seconds (default: 0.5)
delay // number — seconds before the tween starts
ease // string | function — easing curve (default: 'power2.out')
paused // boolean — don't autoplay on creation
// Looping options
repeat // number — extra plays after first (−1 = forever)
yoyo // boolean — alternate direction on each cycle
repeatDelay // number — seconds to pause between cycles
// Multi-target distribution
stagger // number | { each, amount, from, ease, grid }
// Lifecycle callbacks (no arguments passed — access tween via closure)
onStart
onUpdate
onComplete
onRepeat
onReverseComplete
// Instance API
tween.play()
tween.pause()
tween.reverse()
tween.seek(seconds) // jump to time position
tween.progress // 0–1 get/set
tween.timeScale // speed multiplier, get/set
tween.kill() // stop and remove from ticker
tween.invalidate() // re-read live values on next play