Animation is what makes a 3D visualization feel alive instead of static. In this lesson you'll understand how the animation loop works and write your own movement code.

La animación hace que una visualización 3D se sienta viva. Aprende cómo funciona el ciclo de animación.

1

The Animation Loop · El Ciclo de Animación

Every Three.js visualization runs an invisible loop that fires ~60 times per second. Each "tick" it:

  1. Calculates how much time has passed (elapsed in seconds)
  2. Updates positions, rotations, scales of objects
  3. Tells Three.js to draw the frame
// In main.js — this runs ~60 times per second
function animate(timestamp) {
  requestAnimationFrame(animate); // schedule next frame

  const elapsed = timestamp / 1000; // convert ms → seconds

  // Call all registered animation callbacks
  for (const cb of callbacks) {
    cb(elapsed);
  }

  renderer.render(scene, camera); // draw the frame!
}
requestAnimationFrame(animate); // start the loop
Frame: 0  |  Elapsed: 0.00s  |  ~60 FPS
2

Adding Animation Callbacks · Agregar Funciones de Animación

The project uses a callback system so different files can each add their own animations without knowing about each other:

// Any file can register an animation callback:
addAnimationCallback((elapsed) => {
  // This runs every frame!
  myObject.rotation.y = elapsed * 0.5; // half turn per second
});

// The rise-in animation (pedestals growing from ground):
addAnimationCallback((elapsed) => {
  const t = elapsed - riseStart;

  for (const target of riseGroups) {
    if (t < target.delay) continue; // not yet
    const progress = Math.min(1, (t - target.delay) / 0.65);
    target.group.scale.y = easeOutBack(progress);
  }
});
3

Live: Rotation & Bounce · Demo en Vivo

Adjust these sliders to see how elapsed creates motion:

canvas 2D — same math as Three.js
1.0
30
// What the sliders generate:
obj.rotation.y = elapsed * 1.0;
obj.position.y = Math.sin(elapsed * Math.PI) * 30;
4

Easing Functions · Funciones de Suavizado

Raw linear animation looks robotic. Easing functions shape the motion to feel natural — like real physics:

linear
easeIn
easeOut
easeOutBack
// The pedestal rise uses easeOutBack — overshoots then settles
function easeOutBack(t) {
  const c1 = 1.70158;
  const c3 = c1 + 1;
  return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
}

// Usage: progress goes 0 → 1 over 0.65 seconds
const progress = Math.min(1, (t - delay) / 0.65);
target.group.scale.y = easeOutBack(progress);
🏀

easeOutBack makes objects overshoot their target slightly, then snap back — like a bouncing ball settling. This is why the pedestals feel "planted" when they rise.

5

Mouse Hover Interaction · Interacción del Mouse

When you move your mouse over the visualization, it uses a Raycaster — an invisible beam that detects what object is under your cursor:

// Every frame, shoot a ray from mouse position into the scene
raycaster.setFromCamera(pointer, camera);

// Check which pedestals the ray hits
const hits = raycaster.intersectObjects(pedestals);

if (hits.length > 0) {
  // Mouse is over a pedestal! Show its label
  const pedestal = hits[0].object;
  pedestal.label.element.classList.add('hovered');
}
🖱

Raycasting is how almost all 3D mouse interaction works — games, 3D editors, product viewers. Learning it here gives you a skill used everywhere in the industry!

🛠 Try It · Inténtalo

Open docs/js/visualization.js. Find the addAnimationCallback for the rise animation. Change 0.65 (the duration) to 0.25 for a snappy rise, or 2.0 for a slow dramatic rise.

Cambia el valor de duración 0.65 para hacer la animación más rápida o más lenta.

← Lesson 5 Lesson 7: Deploy & Share 🚀