Please enable JavaScript to use CodeHS

Animate 3D Objects with Three.js

In this tutorial, you'll create an animated 3D model with the Three.js library. You'll use geometric shapes, an orbit control system, and an animation function to develop a rotating 3D object that users can explore.

By Matt Arnold

Curriculum Developer

Let’s Get Moving

In this tutorial you’ll use JavaScript and the Three.js library to create a basic 3D cube that users can orbit or move around. You’ll also set up the WebGL scene, add lighting to the scene, and incorporate object materials to add some realism.

Create 3D Objects First

If you haven’t already completed the Create 3D Objects with Three.js tutorial, please review it before adding animation to a Three.js scene. That tutorial will introduce you to the Three.js library and walk you through the process of creating models of 3D geometric shapes using JavaScript and the library.

Let’s start this tutorial with a basic cube 3D model created using the Three.js library. Running the program, you’ll see that the cube doesn’t move and you can’t interact with it in the 3D world. For that, we’ll need to add an update() function and an orbit control system to handle user input.

Import Orbit Controls

In addition to importing the entire Three.js library, you’ll import a special orbit controller. This is a second import declaration that’s added just below the primary Three.js import at the top of the program.

// Import Orbit Controls
import {OrbitControls} from 'https://cdn.jsdelivr.net/npm/three@0.121.1/examples/jsm/controls/OrbitControls.js';
JavaScript

It’s syntax is slightly different because we’re not importing an entire library, but rather a control system. This collection of functions will allow our users to orbit, pan, and zoom around our 3D geometric object using their computer mouse or trackpad.

Set Up Orbit Controls

To use the orbit control system, you’ll need to define a global constant variable. For this tutorial, you’ll only need to assign the variable to call on the Three.js OrbitControls function and pass to it the values for camera and renderer.domElement. This will let your users orbit, pan, and zoom in/out around your 3D model at any time while the program runs.

// Global Variable - orbit controls
const controls = new OrbitControls(camera, renderer.domElement);
JavaScript

Add the import declaration and global variable to the cube program above and run it. Can you zoom in and out in the 3D scene with the scroll wheel on a mouse? Can you right-click and drag within the 3D scene to pan? Can you left-click and drag to orbit around the cube in the scene?

Not yet! That’s because this program’s main() function only initializes the scene. It doesn’t update the scene when you interact with it. Let’s add an update() function now that will update the scene and render each frame.

Update Function

Add a new function after the main() function called update(). To start, you’ll only add two lines of code.

// Update or animation function
function update() {
    // call the update() function every frame - creates a loop
    requestAnimationFrame(update);

    // render the updated scene and camera
    renderer.render(scene, camera);
};
JavaScript
  • Line 4: This line will call the update() function each frame, using the Three.js requestAnimationFrame() function. This is crucial to creating a looping function that can update your 3D object’s position, user input like orbiting, and any other changes to the 3D scene.

  • Line 7: Once the updates are complete, you’ll want the function to render the scene again to the WebGL element on the page. Think of it as redrawing the scene every frame as updates are made to it.

Code Clean Up

Now that you’ve added an update() function to the program, you’ll need to make a change to the main() function. The renderer.render(scene, camera); command is now located in the update() function in order to loop the rendering. So now you no longer need it in the main() function.

Replace the renderer.render(scene, camera); command in the main() function with a call to the update() function. You’ll want your program to call the looping update() function once the scene is initialized in the main() function.

Your final program should look like the one below. Give it a try! Now can you zoom with your mouse scroll wheel, pan with a right-click and drag, and orbit your cube with a left-click and drag?

Rotations

You may have noticed some additional, commented lines of code in the update() function in the program above.

cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
cube.rotation.z += 0;
JavaScript

These lines of code increment or add rotation to the x, y, and z axis values of the cube. Since these are located inside the update() function, they’ll continually add (or subtract) from the cube’s rotation along each axis, giving the 3D model continuous rotation.

Try removing the comments // from each line to try them out. Change the values or replace a += with a -=. What happens when you run the program? How do these impact the look of the cube? Can you still interact with the cube using your mouse while it’s rotating?

Challenge: Torus Knot

Can you rework the animated cube program above to incorporate a torus knot 3D object? Use what you know about the update() function to make the torus knot rotate on all three axes. Here’s some code to help you out.

// Global Constant Variables
const geometry = new THREE.TorusKnotGeometry(10, 3, 100, 16);
const material = new THREE.MeshPhongMaterial({color: '#3498eb'});
const torusKnot = new THREE.Mesh(geometry, material);

// Add to the main() function
scene.add(torusKnot);
JavaScript

Hint: To best see the torus knot, you may need to move the camera back by increasing the z-axis position from 5 to something like 30.

Three.js Docs

Keep playing around with the Three.js JavaScript library and build your own interactive 3D scenes with multiple objects. Be sure to check out the full Three.js library documentation for additional functions, objects, and examples.