FasterMotion
API ReferenceFmtion Format

Canvas Animations

Canvas 2D rendering with skeletal animation, IK, mesh deformation, and state machines

Canvas areas in .fmtion files provide GPU-accelerated 2D rendering with advanced features like skeletal animation, inverse kinematics, mesh deformation, and state machines.

Basic Canvas Area

{
  "canvas": [
    {
      "id": "scene-1",
      "name": "Hero Scene",
      "mountSelector": "#canvas-container",
      "width": 1920,
      "height": 1080,
      "backgroundColor": "#1a1a2e",
      "fps": 60,
      "duration": 5000,
      "viewport": {
        "fit": "contain",
        "alignment": "center",
        "responsive": true
      },
      "objects": [],
      "tracks": []
    }
  ]
}

CanvasArea Fields

FieldTypeRequiredDescription
idstringYesUnique canvas area ID
namestringYesDisplay name
mountSelectorstringYesCSS selector for mount point
widthnumberYesCanvas width in pixels
heightnumberYesCanvas height in pixels
backgroundColorstringNoBackground color
fpsnumberNoFrame rate (default: 60)
durationnumberNoScene duration in ms
viewportViewportSettingsNoResponsive viewport settings
objectsCanvasObject[]YesCanvas objects
tracksCanvasTrack[]YesAnimation tracks

Advanced Fields

FieldTypeDescription
skeletonsSkeleton[]Skeletal animation systems
animationsAnimationClip[]Animation clips
stateMachinesCanvasStateMachine[]State machines
ikChainsIKChain[]IK chains
ikTargetsIKTarget[]IK targets
constraintsConstraint[]Bone constraints
meshesSkinnedMesh[]Skinned meshes
effectsEffect[]Visual effects
filtersWebGLFilter[]WebGL filters
proceduralProceduralConfigProcedural animation
textAnimatorsTextAnimator[]Text animators
trimPathTracksTrimPathTrack[]Trim path animations
pathFollowTracksPathFollowTrack[]Path follow animations

Viewport Settings

{
  "viewport": {
    "fit": "contain",
    "alignment": "center",
    "responsive": true,
    "maxScale": 2,
    "minScale": 0.5
  }
}
Fit ModeDescription
containScale to fit within container
coverScale to cover container
fillStretch to fill container
noneNo scaling
fitWidthScale to match container width
fitHeightScale to match container height
scaleDownScale down only, never up

Canvas Objects

Object Types

TypeDescription
circleCircle shape
rectangleRectangle shape
pathSVG path shape
imageImage/sprite
textText element
groupContainer for other objects

Circle

{
  "id": "circle-1",
  "name": "Main Circle",
  "type": "circle",
  "x": 960,
  "y": 540,
  "scaleX": 1,
  "scaleY": 1,
  "rotation": 0,
  "opacity": 1,
  "properties": {
    "radius": 100,
    "fill": "#6366f1",
    "stroke": "#4f46e5",
    "strokeWidth": 2
  }
}

Rectangle

{
  "id": "rect-1",
  "name": "Card",
  "type": "rectangle",
  "x": 100,
  "y": 100,
  "properties": {
    "width": 200,
    "height": 150,
    "fill": "#22d3ee",
    "cornerRadius": 16
  }
}

Path

{
  "id": "path-1",
  "name": "Custom Shape",
  "type": "path",
  "x": 0,
  "y": 0,
  "properties": {
    "d": "M100,100 L200,100 L150,200 Z",
    "fill": "#f43f5e",
    "stroke": "#e11d48",
    "strokeWidth": 2
  }
}

Image

{
  "id": "image-1",
  "name": "Character Sprite",
  "type": "image",
  "x": 400,
  "y": 300,
  "properties": {
    "src": "/images/character.png",
    "width": 200,
    "height": 300
  }
}

Text

{
  "id": "text-1",
  "name": "Title",
  "type": "text",
  "x": 100,
  "y": 50,
  "properties": {
    "content": "Hello World",
    "fontFamily": "Inter",
    "fontSize": 48,
    "fontWeight": "bold",
    "fill": "#ffffff",
    "textAlign": "center"
  }
}

Group

{
  "id": "group-1",
  "name": "Character Group",
  "type": "group",
  "x": 400,
  "y": 300,
  "children": [
    { "id": "body", "type": "image", ... },
    { "id": "head", "type": "circle", ... }
  ]
}

Animation Tracks

Animate object properties over time:

{
  "tracks": [
    {
      "id": "circle-x-track",
      "objectId": "circle-1",
      "property": "x",
      "keyframes": [
        { "time": 0, "value": 200, "easing": "easeOutCubic" },
        { "time": 2500, "value": 960 },
        { "time": 5000, "value": 1720, "easing": "easeInCubic" }
      ]
    },
    {
      "id": "circle-opacity-track",
      "objectId": "circle-1",
      "property": "opacity",
      "keyframes": [
        { "time": 0, "value": 0 },
        { "time": 500, "value": 1 },
        { "time": 4500, "value": 1 },
        { "time": 5000, "value": 0 }
      ]
    }
  ]
}

Parameter-Driven Tracks

{
  "id": "scroll-driven-track",
  "objectId": "circle-1",
  "property": "x",
  "parameterDriver": "hero/scrollProgress",
  "keyframes": [
    { "time": 0, "value": 100 },
    { "time": 1000, "value": 900 }
  ]
}

Skeletal Animation

Skeleton Definition

{
  "skeletons": [
    {
      "id": "character",
      "name": "Main Character",
      "x": 400,
      "y": 500,
      "bones": [
        {
          "id": "root",
          "name": "root",
          "parentBoneName": null,
          "length": 0,
          "x": 0,
          "y": 0,
          "rotation": 0
        },
        {
          "id": "spine",
          "name": "spine",
          "parentBoneName": "root",
          "length": 80,
          "rotation": -90
        },
        {
          "id": "arm-upper-l",
          "name": "arm-upper-l",
          "parentBoneName": "spine",
          "length": 60,
          "rotation": 45,
          "minRotation": -45,
          "maxRotation": 180
        },
        {
          "id": "arm-lower-l",
          "name": "arm-lower-l",
          "parentBoneName": "arm-upper-l",
          "length": 50,
          "rotation": 30
        }
      ],
      "attachments": [
        {
          "id": "body-attach",
          "name": "Body Sprite",
          "boneName": "spine",
          "objectId": "body-sprite",
          "inheritPosition": true,
          "inheritRotation": true,
          "inheritScale": true
        }
      ]
    }
  ]
}

Animation Clips

{
  "animations": [
    {
      "id": "wave",
      "name": "Wave Animation",
      "duration": 1000,
      "loop": true,
      "skeletonId": "character",
      "boneTracks": [
        {
          "boneName": "arm-upper-l",
          "rotation": [
            { "time": 0, "value": 45, "easing": "easeInOutCubic" },
            { "time": 500, "value": 120 },
            { "time": 1000, "value": 45 }
          ]
        },
        {
          "boneName": "arm-lower-l",
          "rotation": [
            { "time": 0, "value": 30 },
            { "time": 250, "value": 60 },
            { "time": 500, "value": 30 },
            { "time": 750, "value": 60 },
            { "time": 1000, "value": 30 }
          ]
        }
      ]
    }
  ]
}

IK Chains

{
  "ikChains": [
    {
      "id": "arm-ik",
      "name": "Arm IK",
      "skeletonId": "character",
      "startBoneName": "arm-upper-l",
      "endBoneName": "arm-lower-l",
      "iterations": 10,
      "tolerance": 0.01,
      "bendDirection": 1
    }
  ],
  "ikTargets": [
    {
      "id": "hand-target",
      "name": "Hand Target",
      "chainId": "arm-ik",
      "x": 500,
      "y": 200,
      "weight": 1
    }
  ]
}

Constraints

Aim Constraint

{
  "constraints": [
    {
      "id": "look-at",
      "name": "Look At Target",
      "type": "aim",
      "enabled": true,
      "weight": 1,
      "config": {
        "boneName": "head",
        "targetType": "position",
        "target": { "x": 800, "y": 300 },
        "offset": 0,
        "damping": 0.1
      }
    }
  ]
}

Path Constraint

{
  "constraints": [
    {
      "id": "spine-path",
      "name": "Spine Path",
      "type": "path",
      "config": {
        "boneName": "spine",
        "pathData": "M0,0 Q100,50 200,0",
        "position": 0.5,
        "translateX": true,
        "translateY": true,
        "rotate": true
      }
    }
  ]
}

State Machines

State machines provide parameter-driven animation control with states, transitions, and layers.

{
  "stateMachines": [
    {
      "id": "character-sm",
      "name": "Character State Machine",
      "skeletonId": "character",
      "parameters": [
        { "id": "isWalking", "name": "Is Walking", "type": "boolean", "defaultValue": false },
        { "id": "speed", "name": "Speed", "type": "number", "defaultValue": 0, "min": 0, "max": 1 },
        { "id": "jump", "name": "Jump", "type": "trigger" }
      ],
      "layers": [
        {
          "id": "base-layer",
          "name": "Base Layer",
          "weight": 1,
          "states": [
            { "id": "entry", "name": "Entry", "type": "entry", "position": { "x": 100, "y": 200 } },
            { "id": "exit", "name": "Exit", "type": "exit", "position": { "x": 500, "y": 200 } },
            { "id": "idle", "name": "Idle", "type": "animation", "animationId": "idle-anim", "loopMode": "loop" },
            { "id": "walk", "name": "Walk", "type": "animation", "animationId": "walk-anim", "loopMode": "loop" }
          ],
          "transitions": [
            {
              "id": "entry-to-idle",
              "fromStateId": "entry",
              "toStateId": "idle",
              "duration": 0
            },
            {
              "id": "idle-to-walk",
              "fromStateId": "idle",
              "toStateId": "walk",
              "duration": 200,
              "conditions": [
                { "id": "c1", "parameterId": "isWalking", "operator": "==", "value": true }
              ]
            },
            {
              "id": "walk-to-idle",
              "fromStateId": "walk",
              "toStateId": "idle",
              "duration": 200,
              "conditions": [
                { "id": "c2", "parameterId": "isWalking", "operator": "==", "value": false }
              ]
            }
          ]
        }
      ]
    }
  ]
}

State Types

TypeDescription
entryStarting point of a layer (required)
exitEnding point of a layer
anyWildcard - transitions from any state
animationPlays a single animation clip
blend1dBlends animations based on a number parameter
blendDirectDirect weight control per animation

Animation State Properties

PropertyTypeDescription
animationIdstringReference to animation clip
speednumberPlayback speed multiplier (default: 1)
loopModestringLoop behavior: 'none', 'loop', or 'pingPong'

Loop Modes:

  • none - Plays once and stops at the end
  • loop - Repeats from the beginning when reaching the end
  • pingPong - Plays forward, then backward, repeating

Transition Properties

PropertyTypeDescription
fromStateIdstringSource state ID
toStateIdstringTarget state ID
durationnumberBlend duration in milliseconds
exitTimenumberProgress (0-1) at which transition can fire
conditionModestring'all' (AND) or 'any' (OR) for multiple conditions
conditionsarrayConditions that must be met

Condition Operators

OperatorDescription
==Equal to
!=Not equal to
>Greater than
<Less than
>=Greater than or equal
<=Less than or equal
firedTrigger parameter was fired

Blend States

Blend states interpolate between multiple animations based on parameters:

{
  "states": [
    {
      "id": "walk-blend",
      "name": "Walk Blend",
      "type": "blend1d",
      "inputParameterId": "speed",
      "blendAnimations": [
        { "animationId": "idle-anim", "value": 0 },
        { "animationId": "walk-anim", "value": 0.5 },
        { "animationId": "run-anim", "value": 1 }
      ]
    }
  ]
}

Mesh Deformation

{
  "meshes": [
    {
      "id": "body-mesh",
      "name": "Body Mesh",
      "skeletonId": "character",
      "skinningMode": "lbs",
      "vertices": [
        { "x": 0, "y": 0, "weights": [{ "boneName": "spine", "weight": 1 }] },
        { "x": 100, "y": 0, "weights": [{ "boneName": "spine", "weight": 0.5 }, { "boneName": "arm-upper-l", "weight": 0.5 }] }
      ],
      "triangles": [0, 1, 2, 1, 3, 2],
      "textureId": "body-texture",
      "fill": "#6366f1"
    }
  ]
}

Procedural Animation

{
  "procedural": {
    "springBones": [
      {
        "boneName": "hair-1",
        "skeletonId": "character",
        "stiffness": 100,
        "damping": 10,
        "mass": 1
      }
    ],
    "jiggleBones": [
      {
        "boneName": "belly",
        "skeletonId": "character",
        "stiffness": 50,
        "damping": 5,
        "maxDistance": 20
      }
    ],
    "boneChains": [
      {
        "name": "tail",
        "skeletonId": "character",
        "boneNames": ["tail-1", "tail-2", "tail-3"],
        "stiffness": 80,
        "damping": 8,
        "gravity": { "x": 0, "y": 100 }
      }
    ]
  }
}

Effects and Filters

{
  "effects": [
    {
      "id": "glow-effect",
      "name": "Glow",
      "type": "glow",
      "enabled": true,
      "properties": {
        "radius": 20,
        "intensity": 0.8,
        "color": "#6366f1"
      }
    }
  ],
  "filters": [
    {
      "id": "blur-filter",
      "name": "Background Blur",
      "type": "blur",
      "enabled": true,
      "properties": {
        "strength": 5,
        "quality": 4
      }
    }
  ]
}

Trim Path Tracks

{
  "trimPathTracks": [
    {
      "id": "draw-path",
      "name": "Draw On",
      "target": "canvas://path-1",
      "simultaneous": true,
      "keyframes": [
        { "time": 0, "start": 0, "end": 0, "offset": 0 },
        { "time": 1000, "start": 0, "end": 1, "offset": 0, "easing": "easeOutCubic" }
      ]
    }
  ]
}

Complete Example

{
  "canvas": [
    {
      "id": "character-scene",
      "name": "Character Animation",
      "mountSelector": "#canvas",
      "width": 800,
      "height": 600,
      "backgroundColor": "#1a1a2e",
      "fps": 60,
      "duration": 3000,
      "viewport": {
        "fit": "contain",
        "responsive": true
      },
      "objects": [
        {
          "id": "body",
          "name": "Body",
          "type": "image",
          "x": 0,
          "y": 0,
          "properties": {
            "src": "/images/body.png",
            "width": 100,
            "height": 200
          }
        }
      ],
      "skeletons": [
        {
          "id": "char",
          "name": "Character",
          "x": 400,
          "y": 500,
          "bones": [
            { "id": "root", "name": "root", "parentBoneName": null, "length": 0 },
            { "id": "spine", "name": "spine", "parentBoneName": "root", "length": 80, "rotation": -90 }
          ],
          "attachments": [
            { "id": "body-attach", "boneName": "spine", "objectId": "body", "inheritPosition": true, "inheritRotation": true }
          ]
        }
      ],
      "animations": [
        {
          "id": "idle",
          "name": "Idle",
          "duration": 2000,
          "loop": true,
          "skeletonId": "char",
          "boneTracks": [
            {
              "boneName": "spine",
              "y": [
                { "time": 0, "value": 0 },
                { "time": 1000, "value": -5 },
                { "time": 2000, "value": 0 }
              ]
            }
          ]
        }
      ],
      "tracks": []
    }
  ]
}

See Also

On this page