FasterMotion
API ReferenceFmtion Format

3D Content

Three.js WebGL scenes with cameras, lights, objects, and animations

The .fmtion format supports Three.js 3D scenes with cameras, lights, objects, materials, and animations. 3D content can be scroll-synced or parameter-driven.

Basic 3D Scene

{
  "three": {
    "settings": {
      "container": "#three-container",
      "antialias": true,
      "shadows": true,
      "pixelRatio": 2
    },
    "defaultSceneId": "main",
    "scenes": [
      {
        "id": "main",
        "name": "Main Scene",
        "backgroundColor": 0x1a1a2e,
        "camera": {
          "type": "perspective",
          "position": [0, 5, 10],
          "fov": 75,
          "near": 0.1,
          "far": 1000
        },
        "lights": [],
        "objects": [],
        "tracks": []
      }
    ]
  }
}

ThreeDContent Structure

interface ThreeDContent {
  settings?: ThreeDSettings;  // Global 3D settings
  defaultSceneId: string;     // Default scene to render
  scenes: FmtionScene3D[];    // Array of 3D scenes
}

interface ThreeDSettings {
  container?: string;     // CSS selector for container
  antialias?: boolean;    // Enable antialiasing
  shadows?: boolean;      // Enable shadows
  pixelRatio?: number;    // Pixel ratio (default: device ratio)
}

Camera

interface Camera3D {
  type: 'perspective' | 'orthographic';
  position: [number, number, number];  // [x, y, z]
  fov?: number;          // Field of view (perspective only)
  near?: number;         // Near clipping plane
  far?: number;          // Far clipping plane
  size?: number;         // Orthographic size
}

Perspective Camera

{
  "camera": {
    "type": "perspective",
    "position": [0, 5, 10],
    "fov": 75,
    "near": 0.1,
    "far": 1000
  }
}

Orthographic Camera

{
  "camera": {
    "type": "orthographic",
    "position": [0, 10, 0],
    "size": 10,
    "near": 0.1,
    "far": 100
  }
}

Lights

Light Types

TypeDescription
ambientAmbient light (fills shadows)
directionalDirectional light (sun-like)
pointPoint light (bulb-like)
spotSpotlight (cone-shaped)
hemisphereHemisphere light (sky/ground)

Ambient Light

{
  "lights": [
    {
      "id": "ambient",
      "type": "ambient",
      "name": "Ambient Light",
      "color": 0xffffff,
      "intensity": 0.4
    }
  ]
}

Directional Light

{
  "lights": [
    {
      "id": "sun",
      "type": "directional",
      "name": "Sun",
      "color": 0xffffff,
      "intensity": 1,
      "position": [5, 10, 5],
      "castShadow": true
    }
  ]
}

Point Light

{
  "lights": [
    {
      "id": "bulb",
      "type": "point",
      "name": "Bulb",
      "color": 0xffaa00,
      "intensity": 1,
      "position": [0, 3, 0],
      "distance": 20,
      "decay": 2
    }
  ]
}

Spot Light

{
  "lights": [
    {
      "id": "spotlight",
      "type": "spot",
      "name": "Spotlight",
      "color": 0xffffff,
      "intensity": 1,
      "position": [5, 10, 0],
      "angle": 0.5,
      "penumbra": 0.5,
      "castShadow": true
    }
  ]
}

Hemisphere Light

{
  "lights": [
    {
      "id": "sky",
      "type": "hemisphere",
      "name": "Sky Light",
      "color": 0x87ceeb,
      "groundColor": 0x362312,
      "intensity": 0.6
    }
  ]
}

Objects

Object Types

TypeDescription
boxBox geometry
sphereSphere geometry
planePlane geometry
cylinderCylinder geometry
coneCone geometry
torusTorus geometry
torus-knotTorus knot geometry
curved-planeCurved plane
gltfGLTF/GLB model

Basic Object Structure

interface FmtionObject3D {
  id: string;
  name: string;
  type: string;
  position: [number, number, number];
  rotation: [number, number, number];  // Degrees
  scale: [number, number, number];
  visible: boolean;
  material: Material3D;
  params?: Record<string, unknown>;  // Type-specific params
  modifiers?: Modifier3D[];
  src?: string;  // For GLTF models
}

Box

{
  "id": "cube",
  "name": "Cube",
  "type": "box",
  "position": [0, 1, 0],
  "rotation": [0, 0, 0],
  "scale": [1, 1, 1],
  "visible": true,
  "material": {
    "color": 0x6366f1,
    "metalness": 0.3,
    "roughness": 0.7
  },
  "params": {
    "width": 2,
    "height": 2,
    "depth": 2
  }
}

Sphere

{
  "id": "sphere",
  "name": "Sphere",
  "type": "sphere",
  "position": [3, 1, 0],
  "rotation": [0, 0, 0],
  "scale": [1, 1, 1],
  "visible": true,
  "material": {
    "color": 0x22d3ee,
    "metalness": 0.8,
    "roughness": 0.2
  },
  "params": {
    "radius": 1,
    "widthSegments": 32,
    "heightSegments": 32
  }
}

Plane (Floor)

{
  "id": "floor",
  "name": "Floor",
  "type": "plane",
  "position": [0, 0, 0],
  "rotation": [-90, 0, 0],
  "scale": [20, 20, 1],
  "visible": true,
  "material": {
    "color": 0x333333,
    "metalness": 0.1,
    "roughness": 0.9
  }
}

GLTF Model

{
  "id": "character",
  "name": "Character Model",
  "type": "gltf",
  "src": "/models/character.glb",
  "position": [0, 0, 0],
  "rotation": [0, 0, 0],
  "scale": [1, 1, 1],
  "visible": true,
  "material": {
    "color": 0xffffff
  }
}

Materials

interface Material3D {
  color: number;              // Hex color (e.g., 0x6366f1)
  metalness?: number;         // 0-1
  roughness?: number;         // 0-1
  opacity?: number;           // 0-1
  map?: string;               // Diffuse texture URL
  normalMap?: string;         // Normal map URL
  roughnessMap?: string;      // Roughness map URL
  metalnessMap?: string;      // Metalness map URL
  emissive?: number;          // Emissive color
  emissiveIntensity?: number; // Emissive intensity
}

Metallic Material

{
  "material": {
    "color": 0xc0c0c0,
    "metalness": 1,
    "roughness": 0.1
  }
}

Textured Material

{
  "material": {
    "color": 0xffffff,
    "metalness": 0,
    "roughness": 0.5,
    "map": "/textures/wood-diffuse.jpg",
    "normalMap": "/textures/wood-normal.jpg",
    "roughnessMap": "/textures/wood-roughness.jpg"
  }
}

Emissive Material

{
  "material": {
    "color": 0x000000,
    "metalness": 0,
    "roughness": 1,
    "emissive": 0xff0000,
    "emissiveIntensity": 2
  }
}

Animation Tracks

Animate 3D objects, lights, and cameras:

{
  "tracks": [
    {
      "id": "cube-rotation",
      "target": "cube",
      "property": "rotation.y",
      "keyframes": [
        { "time": 0, "value": 0 },
        { "time": 5000, "value": 360 }
      ]
    },
    {
      "id": "cube-position",
      "target": "cube",
      "property": "position.y",
      "keyframes": [
        { "time": 0, "value": 1 },
        { "time": 2500, "value": 3, "easing": "easeOutCubic" },
        { "time": 5000, "value": 1, "easing": "easeInCubic" }
      ]
    }
  ]
}

Animatable Properties

TargetProperties
Objectsposition.x/y/z, rotation.x/y/z, scale.x/y/z, visible
Materialscolor, metalness, roughness, opacity, emissive, emissiveIntensity
Lightsintensity, color, position.x/y/z
Cameraposition.x/y/z, fov

Parameter-Driven Animation

{
  "tracks": [
    {
      "id": "scroll-rotation",
      "target": "product",
      "property": "rotation.y",
      "parameterDriver": "scene/scrollProgress",
      "keyframes": [
        { "time": 0, "value": 0 },
        { "time": 1000, "value": 720 }
      ]
    }
  ]
}

Scroll-Synced 3D

Using Parameters

{
  "meta": { "name": "Product Showcase" },
  "parameters": {
    "scene/scrollProgress": {
      "type": "float",
      "default": 0,
      "min": 0,
      "max": 1
    }
  },
  "scrollBindings": [
    {
      "id": "scene-scroll",
      "parameter": "scene/scrollProgress",
      "trigger": ".product-section",
      "start": "top top",
      "end": "bottom top",
      "pin": true,
      "pinSpacing": true
    }
  ],
  "listeners": [],
  "dom": [],
  "canvas": [],
  "three": {
    "settings": {
      "container": "#product-3d",
      "antialias": true
    },
    "defaultSceneId": "product",
    "scenes": [
      {
        "id": "product",
        "name": "Product Scene",
        "backgroundColor": 0x0a0a0a,
        "camera": {
          "type": "perspective",
          "position": [0, 2, 5],
          "fov": 60
        },
        "lights": [
          { "id": "ambient", "type": "ambient", "name": "Ambient", "color": 0xffffff, "intensity": 0.3 },
          { "id": "key", "type": "directional", "name": "Key", "color": 0xffffff, "intensity": 1, "position": [5, 5, 5] }
        ],
        "objects": [
          {
            "id": "product-model",
            "name": "Product",
            "type": "gltf",
            "src": "/models/product.glb",
            "position": [0, 0, 0],
            "rotation": [0, 0, 0],
            "scale": [1, 1, 1],
            "visible": true,
            "material": { "color": 0xffffff }
          }
        ],
        "tracks": [
          {
            "id": "product-rotation",
            "target": "product-model",
            "property": "rotation.y",
            "parameterDriver": "scene/scrollProgress",
            "keyframes": [
              { "time": 0, "value": 0 },
              { "time": 1000, "value": 720 }
            ]
          },
          {
            "id": "camera-zoom",
            "target": "camera",
            "property": "position.z",
            "parameterDriver": "scene/scrollProgress",
            "keyframes": [
              { "time": 0, "value": 5 },
              { "time": 500, "value": 3 },
              { "time": 1000, "value": 5 }
            ]
          }
        ]
      }
    ]
  }
}

Modifiers

Transform objects with modifiers:

{
  "id": "twisted-box",
  "name": "Twisted Box",
  "type": "box",
  "position": [0, 0, 0],
  "rotation": [0, 0, 0],
  "scale": [1, 1, 1],
  "visible": true,
  "material": { "color": 0x6366f1 },
  "modifiers": [
    {
      "type": "twist",
      "enabled": true,
      "params": {
        "angle": 45,
        "axis": "y"
      }
    },
    {
      "type": "noise",
      "enabled": true,
      "params": {
        "amount": 0.1,
        "frequency": 2
      }
    }
  ]
}

Modifier Types

TypeDescription
bendBend geometry
twistTwist geometry
noiseAdd noise displacement
displaceDisplace vertices

Programmatic Control

const result = await FasterMotion.load('/3d-scene.fmtion');

// Start rendering
result.fmtion?.three?.start();

// Stop rendering
result.fmtion?.three?.stop();

// Get scene
const scene = result.fmtion?.three?.getScene('main');

// Access Three.js objects directly
const mesh = scene?.getObject('cube');
mesh?.position.set(1, 2, 3);
mesh?.rotation.y = Math.PI;

Complete Example

{
  "meta": { "name": "3D Product Showcase" },
  "parameters": {
    "scene/progress": { "type": "float", "default": 0 }
  },
  "scrollBindings": [
    {
      "id": "scroll",
      "parameter": "scene/progress",
      "trigger": ".showcase",
      "start": "top top",
      "end": "+=200%",
      "pin": true,
      "pinSpacing": true
    }
  ],
  "listeners": [],
  "dom": [],
  "canvas": [],
  "three": {
    "settings": {
      "container": "#showcase-3d",
      "antialias": true,
      "shadows": true
    },
    "defaultSceneId": "showcase",
    "scenes": [
      {
        "id": "showcase",
        "name": "Product Showcase",
        "backgroundColor": 0x0f0f23,
        "camera": {
          "type": "perspective",
          "position": [0, 2, 6],
          "fov": 50
        },
        "lights": [
          {
            "id": "ambient",
            "type": "ambient",
            "name": "Ambient",
            "color": 0x404040,
            "intensity": 1
          },
          {
            "id": "key",
            "type": "directional",
            "name": "Key Light",
            "color": 0xffffff,
            "intensity": 1.5,
            "position": [5, 8, 5],
            "castShadow": true
          },
          {
            "id": "fill",
            "type": "directional",
            "name": "Fill Light",
            "color": 0x6366f1,
            "intensity": 0.5,
            "position": [-5, 3, -5]
          },
          {
            "id": "rim",
            "type": "spot",
            "name": "Rim Light",
            "color": 0x22d3ee,
            "intensity": 1,
            "position": [0, 5, -5],
            "angle": 0.6
          }
        ],
        "objects": [
          {
            "id": "product",
            "name": "Product",
            "type": "gltf",
            "src": "/models/headphones.glb",
            "position": [0, 0, 0],
            "rotation": [0, 0, 0],
            "scale": [1, 1, 1],
            "visible": true,
            "material": { "color": 0xffffff }
          },
          {
            "id": "platform",
            "name": "Platform",
            "type": "cylinder",
            "position": [0, -0.5, 0],
            "rotation": [0, 0, 0],
            "scale": [1, 1, 1],
            "visible": true,
            "material": {
              "color": 0x1a1a2e,
              "metalness": 0.9,
              "roughness": 0.1
            },
            "params": {
              "radiusTop": 2,
              "radiusBottom": 2,
              "height": 0.2,
              "radialSegments": 64
            }
          }
        ],
        "tracks": [
          {
            "id": "product-rotation",
            "target": "product",
            "property": "rotation.y",
            "parameterDriver": "scene/progress",
            "keyframes": [
              { "time": 0, "value": 0 },
              { "time": 1000, "value": 360 }
            ]
          },
          {
            "id": "camera-orbit",
            "target": "camera",
            "property": "position.x",
            "parameterDriver": "scene/progress",
            "keyframes": [
              { "time": 0, "value": 0 },
              { "time": 500, "value": 4 },
              { "time": 1000, "value": 0 }
            ]
          }
        ]
      }
    ]
  }
}

See Also

On this page