Skip to main content
CodeSpeedTest
Languages
Start TypingJump into a test — pick any languageAdaptive TrainingUnlock chars as you master themPractice DrillsFocused sessions targeting weak spotsDaily ChallengesNew coding challenges every dayRace ModeCompete against others in real timeAI OpponentRace against an AI at your WPM levelTournamentsLive coding speed tournamentsArcade GamesZType, Overkill Survival, Glyphica & moreGamificationXP, coins, badges & quests
LeaderboardGlobal rankings for every languageCertificatesEarn verifiable Bronze / Silver / Gold certsActivityDaily streaks & historical analyticsProfileYour stats, badges & achievements
Browse Languages500+ languages with real code examplesBlogTips, guides & deep divesFree ToolsWPM calculator, typing speed report & moreFAQCommon questions answeredGetting StartedNew to CodeSpeedTest?AboutOur story & missionSupportGet help — Pro users get priorityContactGet in touch with the team
Pricing
  1. Home
  2. /
  3. Learn
  4. /
  5. Threejs-animation

Learn Threejs-animation - 8 Code Examples & CST Typing Practice Test

Three.js Animation System is a powerful, flexible framework for keyframe-based animations of 3D objects, cameras, materials, and morph targets. It uses AnimationMixer, AnimationClips, and KeyframeTracks to animate properties over time with smooth interpolation and precise timeline control.

View all 8 Threejs-animation code examples →
Simple Rotating CubeBouncing SphereRotating TorusColor Changing CubeMultiple Spinning CubesRotating ConePulsing SphereOrbiting Cube

Learn THREEJS-ANIMATION with Real Code Examples

Updated Nov 26, 2025

Explain

Three.js uses AnimationMixer to manage playback of animations on 3D objects.

AnimationClips contain reusable timeline data for objects, materials, cameras, and skeletons.

KeyframeTracks define value changes across time with interpolation.

Supports skeletal animation, morph targets, camera motion, and custom property animation.

Animation system integrates with GLTF loaders for production-friendly workflows.

Core Features

KeyframeTrack variants (Vector, Quaternion, Boolean, Color, Number)

AnimationAction for clip playback

Action warping, looping, clamping

Cross-fading and blending

Morph target & skeletal animation support

Basic Concepts Overview

AnimationMixer - animation controller

AnimationClip - collection of tracks

KeyframeTracks - property/value timeline

AnimationAction - controls playback

Interpolants - blend between keyframes

Project Structure

scene/ - base Three.js setup

animations/ - imported clips or custom tracks

models/ - GLTF or FBX assets

controls/ - user input & camera logic

render/loop.js - mixer.update & rendering

Building Workflow

Create/Load AnimationClip

Bind clip to mixer via clipAction

Configure play/loop/fade

Update mixer in render loop

Blend/transition actions when needed

Difficulty Use Cases

Beginner: rotate cube with keyframes

Intermediate: animate camera paths

Advanced: GLTF skeletal mix/blend

Expert: multi-character orchestrated action blending

Architect: full cinematic timeline sequencing

Comparisons

Three.js Animation vs GSAP -> GSAP is timeline-based, Three.js is property-based

Three.js vs Reanimated -> Web 3D vs mobile UI

Three.js vs Unity WebGL -> Unity is heavier with built-in animation tools

Three.js vs Babylon.js -> Babylon has a stronger integrated animation editor

Three.js Keyframes vs skeletal -> skeletal is best for characters

Versioning Timeline

2014 - Initial Animation system introduced

2016 - Mixer & Clip system standardized

2018 - GLTFLoader animation improvements

2020 - Better blending & interpolation

2023-2025 - WebGPU pipeline, major animation fixes

Glossary

AnimationClip - reusable timeline

KeyframeTrack - time/value list

AnimationAction - playback controller

Mixer - global animation manager

Interpolant - calculates smooth transitions

Installation Setup

Install: npm install three

Import core modules including AnimationMixer

Load GLTF animations via GLTFLoader

Initialize mixer for animated objects

Call mixer.update(deltaTime) inside render loop

Environment Setup

Ensure correct rendering loop

Use Clock for delta time

Confirm GLTFLoader version matches Three.js

Check browser WebGL support

Use light scenes for mobile

Config Files

vite.config.js - bundling

three.config.js - optional scene config

model-export-settings.json - GLTF export prefs

package.json - dependencies

tsconfig.json - TypeScript support

Cli Commands

npm install three

npm run dev

npx vite build

npm run preview

npx gltfjsx model.gltf (for R3F)

Internationalization

Text independent from animations

Cameras may follow different UI layouts

Cinematic pacing may need local adjustments

3D assets localized via GLTF metadata

Animations remain universally consistent

Accessibility

Provide alt text for 3D elements

Allow pause/skip controls

Avoid essential content behind fast motion

Use reduced motion when required

Ensure keyboard input does not disrupt animations

Ui Styling

Sync UI transitions with animations

Update DOM overlays via GSAP

Blend camera animations with user input

Use easing in tracks for smooth motion

Match lighting changes with animations

State Management

Actions store animation state

Mixer manages active clips

Blend weights combine animations

Track values update object properties

External UI triggers change animation state

Data Management

Store clips in reusable arrays

Keep animation lengths consistent

Use baked GLTF animations

Avoid too many keyframes

Prefer compressed GLTF (Draco/KTX2)

Architecture

AnimationMixer controls actions

AnimationClips hold timeline data

Tracks define timed keyframes

Interpolants compute in-between values

Render loop updates mixer.tick to animate

Rendering Model

Mixer updates animation values

Interpolants compute transition values

Renderer draws updated transforms

GLTF animations baked for GPU efficiency

Animation independent of render cycle

Architectural Patterns

Clip-based animation pipelines

Modular track architecture

Mixer as central playback hub

GLTF-first animation workflows

Timeline + property binding model

Real World Architectures

Interactive 3D product configurators

Real-time online character viewers

Architectural flythrough animations

Three.js cinematic web landing pages

3D brand storytelling experiences

Design Principles

Flexible timeline architecture

Reusable clip-based system

Separation of animation data & playback

Interpolation-first design

Lightweight runtime overhead

Scalability Guide

Limit active mixers

Use clip caching

Reduce bone counts

Compress animations via GLTF

Profile animation cost in devtools

Migration Guide

Move from manual JS animations to AnimationMixer

Replace FBX with GLTF

Use mixers instead of per-frame manual updates

Adopt GLTF tracks for consistent interpolation

Use action.crossFade for transitions

Performance Notes

Use baked animations where possible

Reduce keyframe count for heavy scenes

Limit number of active mixers

Disable blending when not needed

Use GPU-friendly GLTF animations

Security Notes

Animation system handles harmless numeric data

No script execution or unsafe operations

Safe for embedding in web apps

All animations run client-side

Imported GLTF files contain no executable code

Monitoring Analytics

Track FPS drops during animation playback

Measure mixer update time

Monitor CPU load

Track GPU frame-time spikes

Analyze animation memory usage

Code Quality

Avoid mixing manual transforms with animations

Keep clip lengths consistent

Use helper functions for sequenced animations

Document animation actions

Organize clips in modules

Practical Examples

Rotating object animation

Morph target facial animation

Character walk/idle/run blending

Camera dolly and path animation

Full GLTF character action system

Troubleshooting

Ensure mixer.update(delta) is called every frame

Check root object is compatible with animation

GLTF animations must be inside model.animations[]

QuaternionTrack rotation mismatch issues

Incorrect keyframe lengths cause jitter

Testing Guide

Validate clip lengths

Confirm keyframe values animate correctly

Test blending between tracks

Unit-test animation triggers

Test mixer.tick accuracy

Deployment Options

Standard Web deployment

Static hosting (Vercel/Netlify)

Parcel/Vite/Webpack bundlers

NPM package bundling

SSR disabled for animation-heavy scenes

Tools Ecosystem

GLTFLoader + GLTF animation tools

Blender for GLTF animation authoring

Mixamo for rigged characters

GSAP for timeline control

three-std/three-stdlib utilities

Integrations

GSAP timeline control

React Three Fiber (R3F) animation hooks

Three.js + Cannon.js physics sync

WebGPU (upcoming Three.js renderer)

WebXR for VR/AR animation

Productivity Tips

Use gsap.to for hybrid timelines

Bake animations in Blender for accuracy

Leverage GLTF morph targets

Cache mixers and clips

Use animation helpers (SkeletonHelper)

Challenges

Managing multiple mixers

Synchronizing animations with input

Maintaining correct quaternion rotations

Reducing asset size for web performance

Complex timeline sequencing without an editor

Learning Path

Basics of KeyframeTracks

Understanding AnimationMixer

Using GLTF animations

Advanced blending techniques

Camera/morph/skeletal animation mastery

Skill Improvement Plan

Week 1: KeyframeTrack and Clip basics

Week 2: Character animation imports

Week 3: Blending and transitions

Week 4: Camera path animation

Week 5: Full scene cinematic sequencing

Interview Questions

Difference between AnimationClip and AnimationAction?

How does AnimationMixer.update work?

What Track types does Three.js support?

How do you blend GLTF animations?

Explain interpolation in Three.js animations.

Cheat Sheet

const mixer = new AnimationMixer(object);

const action = mixer.clipAction(clip);

action.play();

mixer.update(deltaTime);

Use tracks: VectorKeyframeTrack, QuaternionKeyframeTrack, NumberKeyframeTrack

Books

Discover Three.js - Animation chapters

Three.js Cookbook

WebGL Programming Guide

3D Graphics on the Web

Three.js Essentials

Tutorials

Three.js animation basics

GLTF animation pipelines

Character animation blending

Camera path animation tutorials

Three.js + GSAP timelines

Official Docs

https://threejs.org/docs/index.html#api/en/animation

https://threejs.org/docs/#examples/en/loaders/GLTFLoader

Community Links

Three.js Discord

Three.js GitHub

R3F community

StackOverflow

Three.js subreddit

Community Support

Three.js GitHub

Three.js Discord

StackOverflow three.js tag

R3F community

Three.js subreddit

Monetization

Premium animated 3D product demos

High-end interactive marketing sites

3D e-commerce configurators

Animated brand identity pages

Licensable animation-driven 3D components

Future Roadmap

Native WebGPU animation optimizations

Better GLTF animation compression

Built-in timeline sequencing utilities

More interpolation types

More flexible animation events API

When Not To Use

Simple CSS/web animations

Non-3D websites

2D sprite-based animations

Projects needing editor-based timelines (use GSAP)

Games requiring advanced state machines (use Godot/Unity)

Final Summary

Three.js Animation System provides a flexible and powerful keyframe-based animation engine.

Ideal for 3D object, camera, morph, and skeletal animations.

Supports blending, looping, warping, and GLTF pipelines.

Great for interactive 3D scenes and cinematic motion.

Lightweight, efficient, and production-ready for the web.

Faq

Can Three.js animate cameras? -> Yes, any property.

Does it support skeletal animation? -> Fully supported.

Can I use GLTF animations? -> Yes, recommended.

Can I blend actions? -> Yes, with crossFade.

Do I need GSAP? -> No, but useful for sequencing.

Code Sample Descriptions

1

Simple Rotating Cube

# threejs/demo/RotatingCube.html
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/three@0.150.1/build/three.min.js"></script>
  </head>
  <body>
    <script>
        const scene = new THREE.Scene()
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)
        const renderer = new THREE.WebGLRenderer()
        renderer.setSize(window.innerWidth, window.innerHeight)
        document.body.appendChild(renderer.domElement)

        const geometry = new THREE.BoxGeometry()
        const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
        const cube = new THREE.Mesh(geometry, material)
        scene.add(cube)

        camera.position.z = 5

        function animate() {
        requestAnimationFrame(animate)
        cube.rotation.x += 0.01
        cube.rotation.y += 0.01
        renderer.render(scene, camera)
        }
        animate()
    </script>
  </body>
</html>

A basic Three.js example animating a rotating cube.

Let’s Try →
2

Bouncing Sphere

# threejs/demo/BouncingSphere.html
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/three@0.150.1/build/three.min.js"></script>
  </head>
  <body>
    <script>
        const scene = new THREE.Scene()
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)
        const renderer = new THREE.WebGLRenderer()
        renderer.setSize(window.innerWidth, window.innerHeight)
        document.body.appendChild(renderer.domElement)

        const geometry = new THREE.SphereGeometry(1, 32, 32)
        const material = new THREE.MeshBasicMaterial({ color: 0xff0000 })
        const sphere = new THREE.Mesh(geometry, material)
        scene.add(sphere)

        camera.position.z = 5
        let t = 0

        function animate() {
        requestAnimationFrame(animate)
        t += 0.05
        sphere.position.y = Math.sin(t) * 2
        renderer.render(scene, camera)
        }
        animate()
    </script>
  </body>
</html>

Animates a sphere bouncing up and down using sine wave.

Let’s Try →
3

Rotating Torus

# threejs/demo/RotatingTorus.html
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/three@0.150.1/build/three.min.js"></script>
  </head>
  <body>
    <script>
        const scene = new THREE.Scene()
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)
        const renderer = new THREE.WebGLRenderer()
        renderer.setSize(window.innerWidth, window.innerHeight)
        document.body.appendChild(renderer.domElement)

        const geometry = new THREE.TorusGeometry(1, 0.4, 16, 100)
        const material = new THREE.MeshBasicMaterial({ color: 0x0000ff, wireframe: true })
        const torus = new THREE.Mesh(geometry, material)
        scene.add(torus)

        camera.position.z = 5

        function animate() {
        requestAnimationFrame(animate)
        torus.rotation.x += 0.01
        torus.rotation.y += 0.01
        renderer.render(scene, camera)
        }
        animate()
    </script>
  </body>
</html>

A torus rotating along X and Y axes.

Let’s Try →
4

Color Changing Cube

# threejs/demo/ColorCube.html
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/three@0.150.1/build/three.min.js"></script>
  </head>
  <body>
    <script>
        const scene = new THREE.Scene()
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)
        const renderer = new THREE.WebGLRenderer()
        renderer.setSize(window.innerWidth, window.innerHeight)
        document.body.appendChild(renderer.domElement)

        const geometry = new THREE.BoxGeometry()
        const material = new THREE.MeshBasicMaterial({ color: 0xffffff })
        const cube = new THREE.Mesh(geometry, material)
        scene.add(cube)

        camera.position.z = 5
        let hue = 0

        function animate() {
        requestAnimationFrame(animate)
        hue += 0.5
        cube.material.color.setHSL((hue%360)/360, 1, 0.5)
        cube.rotation.x += 0.01
        cube.rotation.y += 0.01
        renderer.render(scene, camera)
        }
        animate()
    </script>
  </body>
</html>

Cube changes its color over time using HSL.

Let’s Try →
5

Multiple Spinning Cubes

# threejs/demo/MultipleCubes.html
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/three@0.150.1/build/three.min.js"></script>
  </head>
  <body>
    <script>
        const scene = new THREE.Scene()
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)
        const renderer = new THREE.WebGLRenderer()
        renderer.setSize(window.innerWidth, window.innerHeight)
        document.body.appendChild(renderer.domElement)

        const cubes = []
        for(let i=0; i<5; i++){
        const geometry = new THREE.BoxGeometry()
        const material = new THREE.MeshBasicMaterial({ color: Math.random()*0xffffff })
        const cube = new THREE.Mesh(geometry, material)
        cube.position.x = i*2 - 4
        scene.add(cube)
        cubes.push(cube)
        }

        camera.position.z = 5

        function animate() {
        requestAnimationFrame(animate)
        cubes.forEach(c => { c.rotation.x += 0.01; c.rotation.y += 0.01 })
        renderer.render(scene, camera)
        }
        animate()
    </script>
  </body>
</html>

Spawns multiple cubes spinning independently.

Let’s Try →
6

Rotating Cone

# threejs/demo/RotatingCone.html
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/three@0.150.1/build/three.min.js"></script>
  </head>
  <body>
    <script>
        const scene = new THREE.Scene()
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)
        const renderer = new THREE.WebGLRenderer()
        renderer.setSize(window.innerWidth, window.innerHeight)
        document.body.appendChild(renderer.domElement)

        const geometry = new THREE.ConeGeometry(1, 2, 32)
        const material = new THREE.MeshBasicMaterial({ color: 0xff00ff })
        const cone = new THREE.Mesh(geometry, material)
        scene.add(cone)

        camera.position.z = 5

        function animate() {
        requestAnimationFrame(animate)
        cone.rotation.x += 0.02
        cone.rotation.y += 0.02
        renderer.render(scene, camera)
        }
        animate()
    </script>
  </body>
</html>

A simple cone rotating in 3D.

Let’s Try →
7

Pulsing Sphere

# threejs/demo/PulsingSphere.html
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/three@0.150.1/build/three.min.js"></script>
  </head>
  <body>
    <script>
        const scene = new THREE.Scene()
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)
        const renderer = new THREE.WebGLRenderer()
        renderer.setSize(window.innerWidth, window.innerHeight)
        document.body.appendChild(renderer.domElement)

        const geometry = new THREE.SphereGeometry(1, 32, 32)
        const material = new THREE.MeshBasicMaterial({ color: 0x00ffff })
        const sphere = new THREE.Mesh(geometry, material)
        scene.add(sphere)

        camera.position.z = 5
        let t = 0

        function animate() {
        requestAnimationFrame(animate)
        t += 0.05
        sphere.scale.set(1 + Math.sin(t), 1 + Math.sin(t), 1 + Math.sin(t))
        renderer.render(scene, camera)
        }
        animate()
    </script>
  </body>
</html>

Sphere pulses by changing scale periodically.

Let’s Try →
8

Orbiting Cube

# threejs/demo/OrbitCube.html
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/three@0.150.1/build/three.min.js"></script>
  </head>
  <body>
    <script>
        const scene = new THREE.Scene()
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000)
        const renderer = new THREE.WebGLRenderer()
        renderer.setSize(window.innerWidth, window.innerHeight)
        document.body.appendChild(renderer.domElement)

        const geometry = new THREE.BoxGeometry()
        const material = new THREE.MeshBasicMaterial({ color: 0xffff00 })
        const cube = new THREE.Mesh(geometry, material)
        scene.add(cube)

        camera.position.z = 10
        let angle = 0

        function animate() {
        requestAnimationFrame(animate)
        angle += 0.02
        cube.position.x = 5 * Math.cos(angle)
        cube.position.y = 5 * Math.sin(angle)
        renderer.render(scene, camera)
        }
        animate()
    </script>
  </body>
</html>

Cube orbits around the scene center using circular motion.

Let’s Try →

Frequently Asked Questions about Threejs-animation

What is Threejs-animation?

Three.js Animation System is a powerful, flexible framework for keyframe-based animations of 3D objects, cameras, materials, and morph targets. It uses AnimationMixer, AnimationClips, and KeyframeTracks to animate properties over time with smooth interpolation and precise timeline control.

What are the primary use cases for Threejs-animation?

Object and camera animations. GLTF character and skeletal animations. Morph target and facial animations. Scene transitions and cinematic sequences. 3D product demos and interactive experiences

What are the strengths of Threejs-animation?

Highly flexible keyframe-based system. Works seamlessly with GLTF pipelines. Supports blending multiple animations smoothly. Great for complex interactive scenes. Lightweight and efficient for WebGL

What are the limitations of Threejs-animation?

No node-based timeline editor built-in. Requires manual sequencing for complex animations. Interpolation may require fine-tuning. Large animation data increases file size. Not an all-in-one motion engine like GSAP

How can I practice Threejs-animation typing speed?

CodeSpeedTest offers 8+ real Threejs-animation code examples for typing practice. You can measure your WPM, track accuracy, and improve your coding speed with guided exercises.

Learn Other Programming Languages

CReactPythonC++RustTypeScriptKotlinPHPJavaC#RubyMqlCqlN1qlCypherGremlinPartiqlHaskellElixirFsharpView all languages →
CodeSpeedTest

Improve your coding speed, code accuracy, and programming syntax WPM with practice sessions across 500+ programming languages.

Quick Links

HomeAboutFeaturesGetting StartedLanguages

Legal & Support

Pro ⚡ PricingContactPrivacy PolicyTerms of Service

Connect

CodeSpeedTest on GitHubCodeSpeedTest on TwitterEmail CodeSpeedTest

© 2026 CodeSpeedTest. All rights reserved.