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
| Type | Description | Example Default |
|---|---|---|
bool | Boolean on/off state | false |
float | Floating-point number (typically 0-1) | 0 |
int | Integer number | 0 |
trigger | One-shot event that auto-resets | false |
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 pathsBest 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:
| Value | Description |
|---|---|
top | Top of the element |
center | Center of the element |
bottom | Bottom of the element |
25% | 25% from top of element |
Viewport Position:
| Value | Description |
|---|---|
top | Top of viewport |
center | Center of viewport |
bottom | Bottom 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
| Category | Events |
|---|---|
| Mouse | click, dblclick, mouseenter, mouseleave, mousedown, mouseup, mousemove |
| Pointer | pointerenter, pointerleave, pointerdown, pointerup |
| Touch | touchstart, touchend |
| Focus | focus, blur |
| Keyboard | keydown, keyup |
| Other | scroll, resize |
Action Types
| Value | Description |
|---|---|
true / false | Set boolean value |
0.5 | Set 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
}| Option | Description |
|---|---|
preventDefault | Prevent default browser behavior |
stopPropagation | Stop event from bubbling |
debounce | Debounce time in ms |
throttle | Throttle 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
- DOM Animations - Using parameters with DOM animations
- Canvas - Parameter-driven canvas animations
- File Structure - Complete format specification