FasterMotion
API ReferenceFmtion Format

Parameters & Bindings

The parameter system that drives all animations in .fmtion files

Parameters are the central control system in .fmtion files. They use hierarchical path-based keys and can be driven by scroll position, user interactions, or programmatically.

Parameter Types

TypeDescriptionExample Default
boolBoolean on/off statefalse
floatFloating-point number (typically 0-1)0
intInteger number0
triggerOne-shot event that auto-resetsfalse

Defining Parameters

{
  "parameters": {
    "hero/scrollProgress": {
      "type": "float",
      "default": 0,
      "min": 0,
      "max": 1,
      "name": "Hero Scroll Progress"
    },
    "hero/hovered": {
      "type": "bool",
      "default": false
    },
    "menu/open": {
      "type": "bool",
      "default": false
    },
    "counter/value": {
      "type": "int",
      "default": 0,
      "min": 0,
      "max": 100,
      "step": 1
    },
    "form/submit": {
      "type": "trigger",
      "default": false
    }
  }
}

Parameter Paths

Parameters use forward-slash paths for organization:

hero/hovered              # Hero section hover state
hero/scrollProgress       # Hero scroll progress (0-1)
menu/open                 # Menu open state
menu/items/count          # Nested path
cards/0/hovered           # Array-like paths

Best Practices

// Good - organized by component
"hero/title/visible"
"hero/title/hovered"
"menu/items/active"

// Avoid - flat naming
"heroTitleVisible"
"menuItemsActive"

Scroll Bindings

Scroll bindings automatically update parameters based on scroll position.

Basic Scroll Binding

{
  "scrollBindings": [
    {
      "id": "hero-scroll",
      "parameter": "hero/scrollProgress",
      "trigger": ".hero-section",
      "start": "top bottom",
      "end": "bottom top"
    }
  ]
}

As the user scrolls, hero/scrollProgress smoothly transitions from 0 to 1.

Position Syntax

Format: "{element edge} {viewport position}"

Element Edge:

ValueDescription
topTop of the element
centerCenter of the element
bottomBottom of the element
25%25% from top of element

Viewport Position:

ValueDescription
topTop of viewport
centerCenter of viewport
bottomBottom of viewport
80%80% from top of viewport

Common Patterns

{
  "scrollBindings": [
    // Full scroll through element
    {
      "id": "full-scroll",
      "parameter": "section/progress",
      "trigger": ".section",
      "start": "top bottom",
      "end": "bottom top"
    },

    // Trigger when element enters viewport
    {
      "id": "enter-viewport",
      "parameter": "section/visible",
      "trigger": ".section",
      "start": "top 80%",
      "end": "top 50%",
      "outputType": "bool",
      "threshold": 0.5
    },

    // Pin element during scroll
    {
      "id": "pinned-scroll",
      "parameter": "pinned/progress",
      "trigger": ".pinned-section",
      "start": "top top",
      "end": "+=200%",
      "pin": true,
      "pinSpacing": true,
      "scrub": 0.5
    }
  ]
}

Bool Output Type

Convert scroll progress to boolean using a threshold:

{
  "id": "fade-in-trigger",
  "parameter": "content/visible",
  "trigger": ".content",
  "start": "top 80%",
  "end": "top 60%",
  "outputType": "bool",
  "threshold": 0.5
}

When scroll progress crosses 0.5, the parameter becomes true.

Pinning

Pin an element while scrolling through content:

{
  "id": "hero-pin",
  "parameter": "hero/progress",
  "trigger": ".hero",
  "start": "top top",
  "end": "+=100%",
  "pin": true,
  "pinSpacing": true
}

The +=100% means the scroll range extends 100% of viewport height beyond the element.

Interaction Listeners

Listeners respond to DOM events and update parameters.

Basic Listener

{
  "listeners": [
    {
      "id": "hover-enter",
      "target": ".card",
      "event": "mouseenter",
      "actions": [
        { "set": "card/hovered", "value": true }
      ]
    },
    {
      "id": "hover-leave",
      "target": ".card",
      "event": "mouseleave",
      "actions": [
        { "set": "card/hovered", "value": false }
      ]
    }
  ]
}

Supported Events

CategoryEvents
Mouseclick, dblclick, mouseenter, mouseleave, mousedown, mouseup, mousemove
Pointerpointerenter, pointerleave, pointerdown, pointerup
Touchtouchstart, touchend
Focusfocus, blur
Keyboardkeydown, keyup
Otherscroll, resize

Action Types

ValueDescription
true / falseSet boolean value
0.5Set numeric value
"toggle"Toggle boolean parameter
"fire"Fire a trigger parameter
"increment"Increment by amount
"decrement"Decrement by amount

Toggle Example

{
  "id": "menu-toggle",
  "target": ".menu-button",
  "event": "click",
  "actions": [
    { "set": "menu/open", "value": "toggle" }
  ],
  "preventDefault": true
}

Increment/Decrement

{
  "listeners": [
    {
      "id": "counter-increment",
      "target": ".increment-btn",
      "event": "click",
      "actions": [
        { "set": "counter/value", "value": "increment", "amount": 1 }
      ]
    },
    {
      "id": "counter-decrement",
      "target": ".decrement-btn",
      "event": "click",
      "actions": [
        { "set": "counter/value", "value": "decrement", "amount": 1 }
      ]
    }
  ]
}

Delayed Actions

Execute actions with delays:

{
  "id": "delayed-sequence",
  "target": ".trigger",
  "event": "click",
  "actions": [
    { "set": "step/one", "value": true },
    { "set": "step/two", "value": true, "delay": 500 },
    { "set": "step/three", "value": true, "delay": 1000 }
  ]
}

Conditional Actions

Only execute when condition is met:

{
  "id": "conditional-action",
  "target": ".modal-open-btn",
  "event": "click",
  "actions": [
    { "set": "modal/open", "value": true }
  ],
  "condition": "menu/open == false"
}

Event Options

{
  "id": "form-submit",
  "target": "form",
  "event": "submit",
  "actions": [
    { "set": "form/submitted", "value": "fire" }
  ],
  "preventDefault": true,
  "stopPropagation": true,
  "debounce": 300
}
OptionDescription
preventDefaultPrevent default browser behavior
stopPropagationStop event from bubbling
debounceDebounce time in ms
throttleThrottle time in ms

Using Parameters with Animations

Float Driver (Scroll Sync)

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

Animation scrubs based on parameter value (0-1).

Bool Driver (On/Off)

{
  "dom": [
    {
      "selector": ".card",
      "driver": "card/hovered",
      "driverType": "bool",
      "from": { "scale": 1 },
      "to": { "scale": 1.1 },
      "duration": 200,
      "reverseOnFalse": true
    }
  ]
}

Animation plays forward when true, reverses when false.

Programmatic Access

After loading a .fmtion file, access parameters via the result:

const result = await FasterMotion.load('/animation.fmtion');

// Set parameter
result.fmtion?.parameters?.set('hero/hovered', true);

// Toggle boolean
result.fmtion?.parameters?.toggle('menu/open');

// Get current value
const isOpen = result.fmtion?.parameters?.get('menu/open');

// Fire trigger
result.fmtion?.parameters?.fire('form/submit');

Complete Example

{
  "meta": { "name": "Interactive Card" },
  "parameters": {
    "card/hovered": {
      "type": "bool",
      "default": false
    },
    "card/scrollProgress": {
      "type": "float",
      "default": 0,
      "min": 0,
      "max": 1
    },
    "card/clicks": {
      "type": "int",
      "default": 0,
      "min": 0,
      "max": 999
    }
  },
  "scrollBindings": [
    {
      "id": "card-scroll",
      "parameter": "card/scrollProgress",
      "trigger": ".card-section",
      "start": "top bottom",
      "end": "bottom top"
    }
  ],
  "listeners": [
    {
      "id": "card-hover-enter",
      "target": ".card",
      "event": "mouseenter",
      "actions": [{ "set": "card/hovered", "value": true }]
    },
    {
      "id": "card-hover-leave",
      "target": ".card",
      "event": "mouseleave",
      "actions": [{ "set": "card/hovered", "value": false }]
    },
    {
      "id": "card-click",
      "target": ".card",
      "event": "click",
      "actions": [{ "set": "card/clicks", "value": "increment", "amount": 1 }]
    }
  ],
  "dom": [
    {
      "selector": ".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": 300,
      "ease": "easeOut",
      "reverseOnFalse": true
    },
    {
      "selector": ".card-content",
      "driver": "card/scrollProgress",
      "from": { "opacity": 0, "y": 50 },
      "to": { "opacity": 1, "y": 0 }
    }
  ],
  "canvas": []
}

See Also

On this page