Skip to main content

Overview

The AnimationManager class handles all animations for 3D objects in Threebox, including:
  • Built-in animations from 3D model files (GLTF/GLB, FBX)
  • Custom path-following animations
  • Transformation animations (position, rotation, scale)
  • Animation queuing and playback control
Each object enrolled in the AnimationManager gets extended with animation properties and methods.

Constructor

new AnimationManager(map)
map
mapboxgl.Map
required
Mapbox GL JS map instance

Core Methods

enroll

Enrolls an object for animation management and extends it with animation capabilities.
animationManager.enroll(obj)
obj
Object3D
required
The 3D object to enroll for animation. The object will be extended with:
  • clock: THREE.Clock instance
  • hasDefaultAnimation: Boolean indicating if model has built-in animations
  • mixer: THREE.AnimationMixer instance (if animations present)
  • actions: Array of THREE.AnimationAction instances
  • animationQueue: Array for queued animations
  • Animation control methods (see Object Animation Methods below)

unenroll

Removes an object from animation management.
animationManager.unenroll(obj)
obj
Object3D
required
The 3D object to remove from animation tracking

update

Updates all enrolled objects’ animations. Called automatically by Threebox on each frame.
animationManager.update(now)
now
number
required
Current timestamp in milliseconds (typically from Date.now() or requestAnimationFrame)

Object Animation Methods

When an object is enrolled, it receives the following animation methods:

set

Animates object to a new state over a specified duration.
obj.set(options)
options.duration
number
required
Animation duration in milliseconds. If 0, changes apply immediately without animation
options.coords
[lng, lat, altitude]
Target coordinates to animate to
options.rotation
number | {x, y, z}
Target rotation in degrees. Can be a single number or per-axis object
options.scale
number | {x, y, z}
Target scale factor. Can be uniform number or per-axis object
Example:
soldier.set({
  duration: 2000,
  coords: [-122.4194, 37.7749, 50],
  rotation: { x: 0, y: 90, z: 0 },
  scale: 2
})

followPath

Animates object along a path defined by coordinates.
obj.followPath(options, callback)
options.path
Array<[lng, lat, altitude]>
required
Array of coordinates defining the path
options.duration
number
default:"1000"
Animation duration in milliseconds
options.trackHeading
boolean
default:"true"
Whether to automatically rotate object to face direction of travel
callback
function
Function to execute when animation completes
Example:
obj.followPath({
  path: [
    [-122.4194, 37.7749, 0],
    [-122.4184, 37.7759, 10],
    [-122.4174, 37.7769, 0]
  ],
  duration: 5000,
  trackHeading: true
}, () => {
  console.log('Path completed!')
})

playDefault

Plays the default animation from the 3D model file.
obj.playDefault(options)
options.duration
number
required
How long to play the animation in milliseconds
options.speed
number
default:"1"
Playback speed multiplier (e.g., 2 for double speed, 0.5 for half speed)

playAnimation

Plays a specific animation by index from the 3D model.
obj.playAnimation(options)
options.animation
number
Index of animation to play. If omitted, plays default animation
options.duration
number
required
How long to play the animation in milliseconds
options.speed
number
default:"1"
Playback speed multiplier

stop

Stops all animations and clears the animation queue.
obj.stop()

Animation Control Methods

Fine-grained control over animation actions:
obj.pauseAllActions()      // Pause all animations
obj.unPauseAllActions()    // Resume all animations
obj.deactivateAllActions() // Stop all animations
obj.activateAllActions()   // Start all animations
obj.idle()                 // Advance animation by one tick

Properties

isPlaying

Read-only boolean indicating if object is currently playing an animation.
if (obj.isPlaying) {
  console.log('Animation is running')
}
Fires IsPlayingChanged event when state changes.

Events

Animated objects dispatch the following events:

IsPlayingChanged

Fired when animation playback state changes.
obj.addEventListener('IsPlayingChanged', (e) => {
  console.log('Is playing:', e.detail.isPlaying)
}, false)
detail
Object3D
The animated object

ObjectChanged

Fired when object position, rotation, or scale changes during animation.
obj.addEventListener('ObjectChanged', (e) => {
  console.log('Position:', e.detail.action.position)
  console.log('Rotation:', e.detail.action.rotation)
  console.log('Scale:', e.detail.action.scale)
}, false)
detail.object
Object3D
The object that changed
detail.action
object
Object containing position, rotation, and scale values

Usage Example

map.addLayer({
  id: 'custom_layer',
  type: 'custom',
  renderingMode: '3d',
  onAdd: function (map, gl) {
    window.tb = new Threebox(map, gl, { defaultLights: true })

    tb.loadObj({
      obj: '/models/soldier.glb',
      type: 'gltf',
      scale: 1,
      units: 'meters',
      rotation: { x: 90, y: 0, z: 0 }
    }, (model) => {
      let soldier = model.setCoords([-122.4194, 37.7749, 0])
      
      // Listen for animation events
      soldier.addEventListener('IsPlayingChanged', (e) => {
        console.log('Animation state changed:', e.detail.isPlaying)
      })

      // Play built-in animation
      soldier.playDefault({ duration: 3000, speed: 1.5 })

      // Chain animations using callback
      setTimeout(() => {
        soldier.followPath({
          path: [
            [-122.4194, 37.7749, 0],
            [-122.4184, 37.7759, 10],
            [-122.4174, 37.7769, 0]
          ],
          duration: 5000
        }, () => {
          // Animate rotation after path completes
          soldier.set({
            duration: 1000,
            rotation: { x: 90, y: 180, z: 0 }
          })
        })
      }, 3000)

      tb.add(soldier)
    })
  },
  render: function (gl, matrix) {
    tb.update()
  }
})

Notes

  • Animations are queued and executed in order
  • Setting duration: 0 in set() applies changes immediately without animation
  • Built-in model animations require the 3D model to contain animation tracks
  • The trackHeading option in followPath uses quaternion rotation for smooth orientation
  • Animation mixer updates are tied to the object’s internal clock for accurate timing

Build docs developers (and LLMs) love