How to Parse JSON to Three.js AnimationClip

This article explains how to convert raw JSON animation data into a playable AnimationClip in Three.js. You will learn the required JSON structure, how to use the built-in parsing method, and how to play the resulting animation on a 3D object using the AnimationMixer.

1. Understanding the JSON Animation Structure

Three.js expects JSON animation data to follow a specific schema that represents keyframe tracks. A standard animation JSON contains a name, a duration, and an array of tracks (such as position, rotation, or scale changes over time).

Below is an example of a valid JSON object representing a simple position animation:

{
  "name": "MoveRight",
  "duration": 2.0,
  "tracks": [
    {
      "name": ".position",
      "type": "vector",
      "times": [0, 1, 2],
      "values": [0, 0, 0, 5, 0, 0, 0, 0, 0]
    }
  ]
}

In this structure: * name: The identifier for the animation clip. * duration: The total length of the animation in seconds (use -1 to automatically calculate it based on the last keyframe). * tracks: An array of keyframe tracks. Each track requires a target property (name), a data type (e.g., "vector", "quaternion", "color"), an array of keyframe times, and an array of corresponding values.

2. Parsing the JSON in Three.js

To convert this JSON data into a usable AnimationClip, use the static THREE.AnimationClip.parse() method. This method takes the raw JSON object and deserializes it into an instance of THREE.AnimationClip.

import * as THREE from 'three';

// Sample JSON data
const animationData = {
  "name": "MoveRight",
  "duration": 2.0,
  "tracks": [
    {
      "name": ".position",
      "type": "vector",
      "times": [0, 1, 2],
      "values": [0, 0, 0, 5, 0, 0, 0, 0, 0]
    }
  ]
};

// Parse the JSON data into an AnimationClip
const clip = THREE.AnimationClip.parse(animationData);

3. Playing the Parsed Animation

Once you have parsed the AnimationClip, you must associate it with a 3D object (like a Mesh) using an AnimationMixer.

// Create a mesh to animate
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// Create the AnimationMixer for the target object
const mixer = new THREE.AnimationMixer(cube);

// Create an AnimationAction for the parsed clip
const action = mixer.clipAction(clip);

// Play the animation
action.play();

4. Updating the Animation Loop

To render the animation, you must update the AnimationMixer inside your application’s animation loop using a clock to get the delta time.

const clock = new THREE.Clock();

function animate() {
  requestAnimationFrame(animate);

  const delta = clock.getDelta();
  
  // Update the mixer to progress the animation
  if (mixer) {
    mixer.update(delta);
  }

  renderer.render(scene, camera);
}

animate();