FasterMotion
Getting Started

Core Concepts

Fundamental concepts in FasterMotion

Understanding these core concepts will help you master FasterMotion and create powerful animations with the declarative FasterMotion.dom() API.

The FasterMotion.dom() API

The FasterMotion.dom() method is the primary API for creating DOM animations. It uses a declarative configuration object rather than method chaining.

Basic Syntax

FasterMotion.dom(config: DomConfig): Animation
  • config: Configuration object defining the animation
  • Returns: Animation instance with control methods

Example

const animation = FasterMotion.dom({
  target: '.box',
  to: { x: 100, rotation: 360 },
  duration: 1000,
  ease: 'spring.bouncy'
});

Animation Configuration

target

Type: string | HTMLElement

The element(s) to animate - can be a CSS selector or direct element reference.

// CSS selector
FasterMotion.dom({
  target: '#box',
  to: { x: 100 }
});

// HTMLElement
const el = document.querySelector('#box');
FasterMotion.dom({
  target: el,
  to: { x: 100 }
});

to

Type: object

Target property values to animate to from current values.

FasterMotion.dom({
  target: '.box',
  to: {
    x: 100,           // translateX (pixels)
    y: 50,            // translateY (pixels)
    rotation: 360,    // rotate (degrees)
    scale: 1.5,       // uniform scale
    opacity: 1        // opacity
  }
});

from

Type: object

Starting property values. When both from and to are specified, animates from from values to to values.

// Fade in from invisible position
FasterMotion.dom({
  target: '.box',
  from: { opacity: 0, y: 50 },
  to: { opacity: 1, y: 0 }
});

// From only (animates to current values)
FasterMotion.dom({
  target: '.box',
  from: { x: -100 }  // Animates from x:-100 to current x position
});

Animatable Properties

Transform Properties

All transform properties use hardware acceleration for optimal performance:

{
  x: 100,           // translateX (pixels)
  y: 50,            // translateY (pixels)
  rotation: 360,    // rotate (degrees)
  scale: 1.5,       // uniform scale
  scaleX: 2,        // horizontal scale only
  scaleY: 0.5,      // vertical scale only
  skewX: 10,        // horizontal skew (degrees)
  skewY: 5          // vertical skew (degrees)
}

Visual Properties

{
  opacity: 0.5,
  backgroundColor: '#ff0000',
  color: '#ffffff',
  borderRadius: '10px',
  width: '200px',
  height: '100px'
}

Custom Properties

Animate any numeric property on JavaScript objects:

const counter = { value: 0 };

FasterMotion.dom({
  target: counter,
  to: { value: 100 },
  duration: 2000,
  onUpdate: () => {
    document.querySelector('#count').textContent = Math.round(counter.value);
  }
});

Timeline

A Timeline sequences multiple animations with precise timing control.

Creating Timelines

const tl = FasterMotion.dom({
  type: 'timeline',
  paused: true,    // Start paused
  repeat: -1,      // Infinite loop (-1)
  yoyo: true,      // Reverse on repeat
  items: [
    // Animation items go here
  ]
});

Timeline Items

Each item in the items array represents an animation:

{
  target: '.box',
  to: { x: 100 },
  duration: 500,
  at: 0  // Start time in milliseconds
}

Timing Control

Use the at property to control when animations start:

FasterMotion.dom({
  type: 'timeline',
  items: [
    { target: '.box1', to: { x: 100 }, duration: 500, at: 0 },
    { target: '.box2', to: { x: 100 }, duration: 500, at: 500 },   // After first
    { target: '.box3', to: { x: 100 }, duration: 500, at: 250 }    // Overlap first
  ]
});

Timeline Control

const tl = FasterMotion.dom({ type: 'timeline', items: [...] });

// Playback control
tl.play();           // Play/resume
tl.pause();          // Pause
tl.reverse();        // Reverse direction
tl.restart();        // Restart from beginning

// Seeking
tl.seek(2000);       // Jump to 2000ms
tl.progress(0.5);    // Jump to 50%

// Speed control
tl.timeScale(2);     // Double speed
tl.timeScale(0.5);   // Half speed

Easing

Easing functions control the rate of change during animation, creating natural motion.

Standard Easings

'linear'        // Constant speed
'ease'          // Slight ease in and out
'ease-in'       // Slow start
'ease-out'      // Slow end
'ease-in-out'   // Slow start and end

Cubic Bezier

'cubic.in'      // Accelerate
'cubic.out'     // Decelerate
'cubic.inOut'   // Accelerate then decelerate

Back (Overshoot)

Creates an overshoot effect:

'back.in'       // Overshoot at start
'back.out'      // Overshoot at end
'back.inOut'    // Overshoot at both ends

Elastic (Bounce)

Creates an elastic bounce effect:

'elastic.in'
'elastic.out'
'elastic.inOut'

Bounce

Creates a bouncing ball effect:

'bounce.in'
'bounce.out'
'bounce.inOut'

Spring (Physics-Based)

Natural physics-based motion:

'spring.bouncy'     // More bounce
'spring.smooth'     // Balanced
'spring.wobbly'     // More oscillation

Custom Bezier

FasterMotion.dom({
  target: '.box',
  to: { x: 100 },
  ease: 'cubic-bezier(0.4, 0, 0.2, 1)',
  duration: 1000
});

Duration and Delay

duration

Type: number (milliseconds)

Animation duration in milliseconds (1000ms = 1 second).

FasterMotion.dom({
  target: '.box',
  to: { x: 100 },
  duration: 1000    // 1 second
});

Common Durations:

  • 300ms - Fast (button clicks, micro-interactions)
  • 500ms - Medium (modals, dropdowns)
  • 1000ms - Slow (page transitions)
  • 2000ms - Very slow (parallax effects)

delay

Type: number (milliseconds)

Delay before animation starts.

FasterMotion.dom({
  target: '.box',
  to: { x: 100 },
  duration: 1000,
  delay: 500      // Wait 500ms before starting
});

Callbacks

Execute code at specific animation milestones:

onStart

Type: () => void

Called when animation starts (after delay).

FasterMotion.dom({
  target: '.box',
  to: { x: 100 },
  onStart: () => {
    console.log('Animation started');
  }
});

onUpdate

Type: (progress: number) => void

Called on each frame during animation. Progress is 0 to 1.

FasterMotion.dom({
  target: '.box',
  to: { x: 100 },
  onUpdate: (progress) => {
    console.log('Progress:', Math.round(progress * 100) + '%');
  }
});

onComplete

Type: () => void

Called when animation completes.

FasterMotion.dom({
  target: '.box',
  to: { x: 100 },
  onComplete: () => {
    console.log('Animation completed');
  }
});

Controlling Animations

Every animation returns an Animation instance with control methods:

const animation = FasterMotion.dom({
  target: '.box',
  to: { x: 100 },
  duration: 1000,
  paused: true    // Create paused
});

// Playback control
animation.play();           // Start/resume
animation.pause();          // Pause
animation.reverse();        // Reverse direction
animation.restart();        // Restart from beginning

// Seeking
animation.seek(500);        // Jump to 500ms
animation.progress(0.5);    // Jump to 50%

// Speed control
animation.timeScale(2);     // Double speed
animation.timeScale(0.5);   // Half speed

// Cleanup
animation.kill();           // Destroy animation

Trigger Modes

FasterMotion provides three trigger modes for interactive animations:

onClick

Trigger animation on click:

FasterMotion.dom({
  target: '#button',
  to: { scale: 1.1 },
  from: { scale: 1 },
  duration: 200,
  trigger: {
    target: '#button',
    mode: 'onClick'
  }
});

onHover

Trigger on mouse enter/leave:

FasterMotion.dom({
  target: '#card',
  to: { y: -10, scale: 1.02 },
  from: { y: 0, scale: 1 },
  duration: 300,
  trigger: {
    target: '#card',
    mode: 'onHover',
    toggle: true  // Reverse on mouse leave
  }
});

onScroll

Trigger when element enters viewport:

FasterMotion.dom({
  target: '.box',
  to: { opacity: 1, y: 0 },
  from: { opacity: 0, y: 50 },
  trigger: {
    mode: 'onScroll',
    scrollTarget: '.box'
  }
});

Scroll Animations

Fine-grained control over scroll-based animations:

FasterMotion.dom({
  target: '.hero',
  to: { opacity: 0, scale: 0.9 },
  scroll: {
    trigger: '.hero',
    start: 'top top',       // When element top hits viewport top
    end: 'bottom top',      // When element bottom hits viewport top
    scrub: true             // Sync with scroll position
  }
});

Scroll Configuration

  • trigger: Element that triggers the animation
  • start: When animation starts (format: "element_position viewport_position")
  • end: When animation completes
  • scrub: If true, animation progress follows scroll position
  • markers: Show debug markers (development only)

Best Practices

Performance

  1. Use transform properties (x, y, rotation, scale) instead of left, top, width, height
  2. Hardware acceleration is automatic for transform properties
  3. Batch animations in timelines instead of individual tweens
  4. Use paused: true to create animations without starting them immediately

Code Organization

// Good: Reusable animation factory
const fadeIn = (target, delay = 0) => {
  return FasterMotion.dom({
    target,
    from: { opacity: 0, y: 30 },
    to: { opacity: 1, y: 0 },
    duration: 800,
    delay,
    ease: 'ease-out'
  });
};

// Use it
fadeIn('.title', 0);
fadeIn('.subtitle', 200);
fadeIn('.content', 400);

Memory Management

// Store reference to animation
const animation = FasterMotion.dom({
  target: '.box',
  to: { x: 100 },
  duration: 1000
});

// Clean up when done (e.g., when element is removed)
animation.kill();

Declarative vs Imperative

FasterMotion uses a declarative API - you describe what you want to happen, not how:

// Declarative (FasterMotion way)
FasterMotion.dom({
  target: '.box',
  to: { x: 100, opacity: 1 },
  duration: 1000,
  ease: 'ease-out'
});

// vs. Imperative (manual animation loop)
let progress = 0;
const animate = () => {
  progress += 0.016;
  if (progress < 1) {
    box.style.transform = `translateX(${progress * 100}px)`;
    box.style.opacity = progress;
    requestAnimationFrame(animate);
  }
};
animate();

Common Patterns

Stagger

Animate multiple elements with a delay:

document.querySelectorAll('.item').forEach((item, i) => {
  FasterMotion.dom({
    target: item,
    from: { opacity: 0, y: 30 },
    to: { opacity: 1, y: 0 },
    duration: 600,
    delay: i * 100,  // Stagger by 100ms
    ease: 'ease-out'
  });
});

Sequential Animations

Use timeline for precise sequencing:

FasterMotion.dom({
  type: 'timeline',
  items: [
    { target: '.step1', to: { opacity: 1 }, duration: 500, at: 0 },
    { target: '.step2', to: { opacity: 1 }, duration: 500, at: 500 },
    { target: '.step3', to: { opacity: 1 }, duration: 500, at: 1000 }
  ]
});

Infinite Loop

FasterMotion.dom({
  target: '.loading',
  to: { rotation: 360 },
  duration: 1000,
  repeat: -1,      // Infinite
  ease: 'linear'   // Constant speed for smooth rotation
});

Yoyo Effect

FasterMotion.dom({
  target: '.pulse',
  to: { scale: 1.1 },
  duration: 800,
  repeat: -1,
  yoyo: true      // Reverse each repeat
});

Next Steps

Now that you understand the core concepts:

On this page