FasterMotion
API ReferenceFmtion Format

DOM Animations

Animating HTML elements with .fmtion DOM animations

DOM animations in .fmtion files allow you to animate CSS properties on HTML elements. They can be driven by scroll position, boolean states, or float parameters.

Basic Structure

{
  "dom": [
    {
      "id": "hero-fade",
      "selector": ".hero-title",
      "driver": "hero/scrollProgress",
      "driverType": "scroll",
      "from": { "opacity": 0, "y": 50 },
      "to": { "opacity": 1, "y": 0 },
      "ease": "easeOutCubic"
    }
  ]
}

DomAnimation Fields

FieldTypeRequiredDescription
idstringNoUnique animation ID
selectorstringYesCSS selector for target element(s)
driverstringNoParameter path that drives animation
driverType'scroll' | 'bool' | 'float'NoHow driver controls animation
fromobjectYesStart property values
toobjectYesEnd property values
easestringNoEasing function
durationnumberNoDuration in ms (for bool driver)
delaynumberNoDelay before starting
reverseOnFalsebooleanNoReverse when driver becomes false
splitText'chars' | 'words' | 'lines'NoSplit text for stagger
staggernumberNoStagger delay between elements (seconds)
pathstringNoSVG path for motion path animation
pathCoords'percentage' | 'pixels'NoPath coordinate system

Animatable Properties

Transform Properties

PropertyDescriptionExample
xtranslateX{ "x": 100 }
ytranslateY{ "y": -50 }
rotationrotate (degrees){ "rotation": 360 }
scaleuniform scale{ "scale": 1.2 }
scaleXhorizontal scale{ "scaleX": 0.5 }
scaleYvertical scale{ "scaleY": 1.5 }
skewXhorizontal skew{ "skewX": 10 }
skewYvertical skew{ "skewY": -5 }

Visual Properties

PropertyDescriptionExample
opacityopacity (0-1){ "opacity": 0.5 }
backgroundColorbackground color{ "backgroundColor": "#ff0000" }
colortext color{ "color": "#ffffff" }
borderRadiusborder radius{ "borderRadius": "50%" }
boxShadowbox shadow{ "boxShadow": "0 10px 30px rgba(0,0,0,0.2)" }

Dimension Properties

PropertyDescriptionExample
widthelement width{ "width": 200 }
heightelement height{ "height": 100 }

Driver Types

Float Driver (Default)

Scrubs animation based on parameter value (0-1):

{
  "selector": ".parallax-image",
  "driver": "hero/scrollProgress",
  "driverType": "float",
  "from": { "y": 0 },
  "to": { "y": -200 }
}

When hero/scrollProgress is 0, y is 0. When it's 1, y is -200.

Scroll Driver

Alias for float driver, commonly used for scroll-linked animations:

{
  "selector": ".hero-title",
  "driver": "hero/scrollProgress",
  "driverType": "scroll",
  "from": { "opacity": 0, "y": 50 },
  "to": { "opacity": 1, "y": 0 }
}

Bool Driver

Plays animation forward when true, optionally reverses when false:

{
  "selector": ".card",
  "driver": "card/hovered",
  "driverType": "bool",
  "from": { "scale": 1 },
  "to": { "scale": 1.1 },
  "duration": 300,
  "ease": "easeOut",
  "reverseOnFalse": true
}

Text Splitting

Split text into characters, words, or lines for staggered animations.

Split by Characters

{
  "selector": ".animated-heading",
  "driver": "hero/scrollProgress",
  "from": { "opacity": 0, "y": 20 },
  "to": { "opacity": 1, "y": 0 },
  "splitText": "chars",
  "stagger": 0.03
}

Each character animates with a 30ms delay after the previous one.

Split by Words

{
  "selector": ".tagline",
  "driver": "content/visible",
  "driverType": "bool",
  "from": { "opacity": 0, "x": -20 },
  "to": { "opacity": 1, "x": 0 },
  "splitText": "words",
  "stagger": 0.1,
  "duration": 500
}

Split by Lines

{
  "selector": ".paragraph",
  "driver": "content/visible",
  "driverType": "bool",
  "from": { "opacity": 0, "y": 30 },
  "to": { "opacity": 1, "y": 0 },
  "splitText": "lines",
  "stagger": 0.15,
  "duration": 600,
  "ease": "easeOutCubic"
}

Easing Functions

EasingDescription
linearConstant speed
easeInSlow start
easeOutSlow end
easeInOutSlow start and end
easeInCubicCubic ease in
easeOutCubicCubic ease out
easeInOutCubicCubic ease in/out
easeInBackOvershoot ease in
easeOutBackOvershoot ease out
easeInElasticElastic ease in
easeOutElasticElastic ease out
easeOutBounceBounce ease out
spring.bouncySpring physics

Custom Bezier

{
  "ease": {
    "type": "bezier",
    "controlPoints": [0.68, -0.55, 0.265, 1.55]
  }
}

Common Patterns

Fade In on Scroll

{
  "selector": ".fade-in-element",
  "driver": "section/visible",
  "driverType": "bool",
  "from": { "opacity": 0, "y": 30 },
  "to": { "opacity": 1, "y": 0 },
  "duration": 600,
  "ease": "easeOutCubic"
}

Parallax Effect

{
  "selector": ".parallax-bg",
  "driver": "page/scrollProgress",
  "from": { "y": 0 },
  "to": { "y": -300 },
  "ease": "linear"
}

Hover Scale

{
  "selector": ".hover-card",
  "driver": "card/hovered",
  "driverType": "bool",
  "from": {
    "scale": 1,
    "boxShadow": "0 4px 6px rgba(0,0,0,0.1)"
  },
  "to": {
    "scale": 1.05,
    "boxShadow": "0 20px 40px rgba(0,0,0,0.2)"
  },
  "duration": 200,
  "ease": "easeOut",
  "reverseOnFalse": true
}

Text Reveal

{
  "selector": ".reveal-text",
  "driver": "hero/visible",
  "driverType": "bool",
  "from": { "opacity": 0, "y": 40 },
  "to": { "opacity": 1, "y": 0 },
  "splitText": "words",
  "stagger": 0.08,
  "duration": 800,
  "ease": "easeOutCubic"
}

Color Transition

{
  "selector": ".color-shift",
  "driver": "theme/dark",
  "driverType": "bool",
  "from": {
    "backgroundColor": "#ffffff",
    "color": "#000000"
  },
  "to": {
    "backgroundColor": "#1a1a2e",
    "color": "#ffffff"
  },
  "duration": 300,
  "reverseOnFalse": true
}

Motion Path

Animate elements along an SVG path:

{
  "selector": ".flying-element",
  "driver": "path/progress",
  "from": { "x": 0, "y": 0 },
  "to": { "x": 500, "y": 200 },
  "path": "M0,0 C100,0 200,100 300,100 S500,200 500,200",
  "pathCoords": "percentage"
}

Multiple Targets

The selector can match multiple elements:

{
  "selector": ".card",
  "driver": "cards/visible",
  "driverType": "bool",
  "from": { "opacity": 0, "y": 50 },
  "to": { "opacity": 1, "y": 0 },
  "stagger": 0.1,
  "duration": 500
}

All .card elements animate with stagger delay between them.

Complete Example

{
  "meta": { "name": "Landing Page" },
  "parameters": {
    "hero/scrollProgress": { "type": "float", "default": 0 },
    "hero/visible": { "type": "bool", "default": false },
    "cta/hovered": { "type": "bool", "default": false }
  },
  "scrollBindings": [
    {
      "id": "hero-scroll",
      "parameter": "hero/scrollProgress",
      "trigger": ".hero",
      "start": "top top",
      "end": "bottom top"
    },
    {
      "id": "hero-visible",
      "parameter": "hero/visible",
      "trigger": ".hero",
      "start": "top 80%",
      "end": "top 60%",
      "outputType": "bool"
    }
  ],
  "listeners": [
    {
      "id": "cta-hover-enter",
      "target": ".cta-button",
      "event": "mouseenter",
      "actions": [{ "set": "cta/hovered", "value": true }]
    },
    {
      "id": "cta-hover-leave",
      "target": ".cta-button",
      "event": "mouseleave",
      "actions": [{ "set": "cta/hovered", "value": false }]
    }
  ],
  "dom": [
    {
      "id": "hero-parallax",
      "selector": ".hero-image",
      "driver": "hero/scrollProgress",
      "from": { "y": 0, "scale": 1 },
      "to": { "y": -200, "scale": 1.1 },
      "ease": "linear"
    },
    {
      "id": "title-reveal",
      "selector": ".hero-title",
      "driver": "hero/visible",
      "driverType": "bool",
      "from": { "opacity": 0, "y": 40 },
      "to": { "opacity": 1, "y": 0 },
      "splitText": "words",
      "stagger": 0.08,
      "duration": 800,
      "ease": "easeOutCubic"
    },
    {
      "id": "subtitle-fade",
      "selector": ".hero-subtitle",
      "driver": "hero/visible",
      "driverType": "bool",
      "from": { "opacity": 0 },
      "to": { "opacity": 1 },
      "duration": 600,
      "delay": 400
    },
    {
      "id": "cta-hover",
      "selector": ".cta-button",
      "driver": "cta/hovered",
      "driverType": "bool",
      "from": { "scale": 1 },
      "to": { "scale": 1.1 },
      "duration": 200,
      "ease": "easeOutBack",
      "reverseOnFalse": true
    }
  ],
  "canvas": []
}

See Also

On this page