API ReferenceCore
Timeline - Advanced Features
Control methods, common patterns, and advanced timeline features
Advanced features for controlling, sequencing, and optimizing timeline animations with FasterMotion.
Control Methods
Timeline provides complete playback control with methods for playing, pausing, seeking, and more.
play()
Play or resume the timeline.
const tl = FasterMotion.dom({
type: 'timeline',
paused: true,
items: [/* ... */]
});
tl.play(); // Start playbackpause()
Pause the timeline.
tl.pause();restart()
Restart from the beginning.
tl.revert(); // Reset to initial state
tl.play(); // Play from startreverse()
Reverse the timeline direction.
tl.reverse();Try it: Playback Controls
const tl = FasterMotion.dom({
type: 'timeline',
paused: true,
items: [
{ target: '#box', to: { x: 150 }, duration: 800, at: 0 },
{ target: '#box', to: { y: 100 }, duration: 800, at: 800 },
{ target: '#box', to: { rotation: 360 }, duration: 800, at: 1600 }
]
});
// Control with buttons
function play() { tl.play(); }
function pause() { tl.pause(); }
function restart() { tl.revert(); tl.play(); }
function reverse() { tl.reverse(); }setProgress()
Jump to a specific progress point (0 to 1).
tl.setProgress(0.5); // Jump to 50%
tl.setProgress(1); // Jump to endTry it: Timeline Scrubber
const tl = FasterMotion.dom({
type: 'timeline',
paused: true,
items: [
{ target: '#box', to: { x: 150 }, duration: 1000, at: 0 },
{ target: '#box', to: { y: 100 }, duration: 1000, at: 1000 },
{ target: '#box', to: { rotation: 360 }, duration: 1000, at: 2000 }
]
});
// Scrub with slider
slider.addEventListener('input', (e) => {
const progress = e.target.value / 100;
tl.setProgress(progress);
});timeScale()
Change playback speed.
tl.timeScale(2); // Double speed
tl.timeScale(0.5); // Half speed
tl.timeScale(1); // Normal speedTry it: TimeScale Control
const tl = FasterMotion.dom({
type: 'timeline',
repeat: -1,
items: [
{ target: '#box', to: { x: 150 }, duration: 1000, at: 0 },
{ target: '#box', to: { y: 100 }, duration: 1000, at: 1000 },
{ target: '#box', to: { x: 0 }, duration: 1000, at: 2000 },
{ target: '#box', to: { y: 0 }, duration: 1000, at: 3000 }
]
});
// Control speed with slider
slider.addEventListener('input', (e) => {
const speed = parseFloat(e.target.value);
tl.timeScale(speed);
});revert()
Reset the timeline and restore original values.
tl.revert(); // Resets animation and restores initial stateTimeline Properties
Get/Set Time
// Get current time
const time = tl.time(); // in milliseconds
// Set current time
tl.time(1000); // Jump to 1000msRepeat
const tl = FasterMotion.dom({
type: 'timeline',
repeat: 2, // Play 3 times total (initial + 2 repeats)
items: [/* ... */]
});
// Infinite repeat
const tl2 = FasterMotion.dom({
type: 'timeline',
repeat: -1,
items: [/* ... */]
});Yoyo
const tl = FasterMotion.dom({
type: 'timeline',
repeat: -1,
yoyo: true, // Reverse on each repeat
items: [/* ... */]
});Try it: Infinite Yoyo Loop
const tl = FasterMotion.dom({
type: 'timeline',
repeat: -1,
yoyo: true,
items: [
{ target: '#box', to: { x: 150 }, duration: 1000, ease: 'ease-in-out', at: 0 },
{ target: '#box', to: { y: 100 }, duration: 1000, ease: 'ease-in-out', at: 1000 },
{ target: '#box', to: { rotation: 360 }, duration: 1000, ease: 'linear', at: 2000 }
]
});Common Patterns
Real-world timeline patterns for common UI animations.
Sequential Fade In
const tl = FasterMotion.dom({
type: 'timeline',
items: [
{ target: '.title', type: 'from', from: { opacity: 0, y: 30 }, duration: 600, at: 0 },
{ target: '.subtitle', type: 'from', from: { opacity: 0 }, duration: 400, at: 400 },
{ target: '.description', type: 'from', from: { opacity: 0 }, duration: 400, at: 600 },
{ target: '.button', type: 'from', from: { opacity: 0, scale: 0.8 }, duration: 400, at: 700 }
]
});Try it: Sequential Fade In
const tl = FasterMotion.dom({
type: 'timeline',
paused: true,
items: [
{ target: '.title', type: 'from', from: { opacity: 0, y: 30 }, duration: 600, at: 0 },
{ target: '.subtitle', type: 'from', from: { opacity: 0 }, duration: 400, at: 400 },
{ target: '.description', type: 'from', from: { opacity: 0 }, duration: 400, at: 600 },
{ target: '.button-demo', type: 'from', from: { opacity: 0, scale: 0.8 }, duration: 400, at: 700 }
]
});
tl.play();Stagger Animation
// Build items array with stagger timing
const items = [];
document.querySelectorAll('.card').forEach((card, i) => {
items.push({
target: card,
type: 'from',
from: { opacity: 0, y: 50 },
duration: 600,
at: i * 100 // Stagger by 100ms
});
});
const tl = FasterMotion.dom({
type: 'timeline',
items: items
});Try it: Stagger Animation
// Build items array with stagger timing
const items = [];
document.querySelectorAll('.card').forEach((card, i) => {
items.push({
target: card,
type: 'from',
from: { opacity: 0, y: 50 },
duration: 600,
at: i * 150 // Stagger by 150ms
});
});
const tl = FasterMotion.dom({
type: 'timeline',
paused: true,
items: items
});
tl.play();Loading Sequence
const tl = FasterMotion.dom({
type: 'timeline',
items: [
{ target: '.loader', to: { rotation: 360 }, duration: 1000, ease: 'linear', at: 0 },
{ target: '.loader', to: { scale: 0 }, duration: 300, at: 1000 },
{ target: '.content', type: 'from', from: { opacity: 0 }, duration: 600, at: 1300 }
]
});Try it: Loading Sequence
const tl = FasterMotion.dom({
type: 'timeline',
paused: true,
items: [
{ target: '.loader', to: { rotation: 360 }, duration: 1000, ease: 'linear', at: 0 },
{ target: '.loader', to: { scale: 0 }, duration: 300, at: 1000 },
{ target: '.content', type: 'from', from: { opacity: 0 }, duration: 600, at: 1300 }
]
});
tl.play();Coordinated Animations
const tl = FasterMotion.dom({
type: 'timeline',
items: [
// Background slides in
{ target: '.bg', type: 'from', from: { x: '-100%' }, duration: 800, ease: 'ease-out', at: 0 },
// Text appears while bg is moving (400ms before bg ends)
{ target: '.title', type: 'from', from: { opacity: 0, y: 30 }, duration: 600, at: 400 },
// Button appears after title starts (200ms before title ends)
{ target: '.button', type: 'from', from: { scale: 0 }, duration: 400, ease: 'back.out', at: 800 }
]
});Infinite Loop
const tl = FasterMotion.dom({
type: 'timeline',
repeat: -1,
yoyo: true,
items: [
{ target: '.box', to: { x: 100 }, duration: 1000, ease: 'ease-in-out', at: 0 },
{ target: '.box', to: { y: 100 }, duration: 1000, ease: 'ease-in-out', at: 1000 },
{ target: '.box', to: { rotation: 360 }, duration: 1000, ease: 'linear', at: 2000 }
]
});Button Click Feedback
function animateButton(button) {
const tl = FasterMotion.dom({
type: 'timeline',
items: [
{ target: button, to: { scale: 0.95 }, duration: 100, at: 0 },
{ target: button, to: { scale: 1.05 }, duration: 100, at: 100 },
{ target: button, to: { scale: 1 }, duration: 100, at: 200 }
]
});
return tl;
}
document.querySelector('.button').addEventListener('click', (e) => {
animateButton(e.target);
});Advanced Usage
Nested Timelines
function createIntro() {
const tl = FasterMotion.timeline();
tl.from('.logo', { opacity: 0, scale: 0.5, duration: 600 })
.from('.tagline', { opacity: 0, y: 20, duration: 400 });
return tl;
}
function createContent() {
const tl = FasterMotion.timeline();
tl.from('.title', { opacity: 0, duration: 600 })
.from('.body', { opacity: 0, duration: 600 });
return tl;
}
// Main timeline
const master = FasterMotion.timeline();
master.add(createIntro())
.add(createContent(), '-=200');Callback Functions
const tl = FasterMotion.dom({
type: 'timeline',
onComplete: () => {
console.log('Timeline completed');
},
items: [
{
target: '.box',
to: { x: 100 },
duration: 500,
onStart: () => console.log('Animation started'),
onComplete: () => console.log('Animation completed')
}
]
});Dynamic Timeline
// Build items array dynamically
const items = [];
function addAnimation(selector, props, at) {
items.push({ target: selector, to: props, duration: 500, at });
}
addAnimation('.box1', { x: 100 }, 0);
addAnimation('.box2', { y: 100 }, 500);
// Create timeline when ready
const tl = FasterMotion.dom({
type: 'timeline',
paused: true,
items: items
});
tl.play();Performance Tips
Reusable Timelines
// Create once
const fadeIn = FasterMotion.dom({
type: 'timeline',
paused: true,
items: [
{
target: '.modal',
type: 'from',
from: { opacity: 0, scale: 0.9 },
duration: 300,
at: 0
}
]
});
// Reuse multiple times
document.querySelectorAll('.trigger').forEach(trigger => {
trigger.addEventListener('click', () => {
fadeIn.revert();
fadeIn.play();
});
});Clear on Destroy
let tl = FasterMotion.dom({
type: 'timeline',
items: [/* ... */]
});
// Clean up when done
tl.revert();
tl = null;TypeScript Support
import { FasterMotion } from 'faster-motion';
interface TimelineItem {
target: string | HTMLElement;
to?: object;
from?: object;
type?: 'from' | 'fromTo' | 'staggerTo';
duration: number;
at?: number;
ease?: string;
stagger?: number;
}
const tl = FasterMotion.dom({
type: 'timeline',
paused: true,
repeat: -1,
yoyo: true,
items: [
{ target: '.box', to: { x: 100 }, duration: 500, at: 0 },
{ target: '.box', to: { y: 100 }, duration: 500, at: 500 }
] as TimelineItem[]
});See Also
- Timeline - Basics - Timeline creation and positioning
- Tween - Individual tween animations
- Easing - Easing functions
- Examples - More timeline examples