JavaScript Academy · Lesson

Animation with requestAnimationFrame

Create smooth canvas animations.

Lesson 4 of 413 steps

Animation with requestAnimationFrame is a free JavaScript Academy lesson on CoddyKit. This is lesson 4 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the JavaScript Academy learning path, and your progress syncs across the web and the CoddyKit app. The JavaScript Academy course includes 4 lessons in total.

Why requestAnimationFrame?

requestAnimationFrame(callback) schedules your draw function to run before the next screen repaint — typically 60 times per second. It pauses in background tabs, saving CPU and battery, unlike setInterval.

function frame() {
  // draw one frame
  requestAnimationFrame(frame);
}
requestAnimationFrame(frame);

The Basic Loop

An animation loop clears the canvas, updates state, draws, then re-schedules itself.

let x = 0;
function loop() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillRect(x, 50, 30, 30);
  x += 2;
  requestAnimationFrame(loop);
}
requestAnimationFrame(loop);

Clearing Each Frame

Without clearRect the previous frame stays painted and you get trails. Clear the whole buffer at the top of every frame for a clean redraw.

ctx.clearRect(0, 0, canvas.width, canvas.height);

The Timestamp Argument

The callback receives a high-resolution timestamp (milliseconds). Use it to compute elapsed time between frames.

let last = 0;
function loop(now) {
  const dt = now - last;
  last = now;
  // dt = ms since previous frame
  requestAnimationFrame(loop);
}
requestAnimationFrame(loop);

Frame-Rate Independent Motion

Multiply velocity by delta time so movement speed is consistent regardless of frame rate.

let x = 0;
const speed = 0.1; // px per ms
function loop(now) {
  const dt = now - (loop.last || now);
  loop.last = now;
  x += speed * dt;
  requestAnimationFrame(loop);
}

Bouncing a Ball

Reverse velocity when the object hits an edge to make it bounce.

let x = 50, vx = 3;
function loop() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  x += vx;
  if (x < 0 || x > canvas.width) vx = -vx;
  ctx.beginPath();
  ctx.arc(x, 75, 15, 0, Math.PI * 2);
  ctx.fill();
  requestAnimationFrame(loop);
}
loop();

Stopping the Loop

requestAnimationFrame returns an id. Pass it to cancelAnimationFrame to stop animating.

let id;
function loop() {
  id = requestAnimationFrame(loop);
}
id = requestAnimationFrame(loop);
// later:
cancelAnimationFrame(id);

Pausing and Resuming

Track a running flag. To resume, request a new frame; to pause, simply stop requesting (or cancel the pending one).

let running = true;
function loop() {
  if (!running) return;
  // draw...
  requestAnimationFrame(loop);
}
function pause() { running = false; }
function resume() { running = true; requestAnimationFrame(loop); }

Animating Multiple Objects

Store objects in an array and update each one inside the loop.

const balls = [{ x: 10, vx: 2 }, { x: 80, vx: -3 }];
function loop() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  for (const b of balls) {
    b.x += b.vx;
    ctx.fillRect(b.x, 60, 20, 20);
  }
  requestAnimationFrame(loop);
}
loop();

Easing for Smooth Motion

Interpolate toward a target with easing for natural deceleration.

let x = 0;
const target = 200;
function loop() {
  x += (target - x) * 0.1; // ease out
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillRect(x, 50, 30, 30);
  if (Math.abs(target - x) > 0.5) requestAnimationFrame(loop);
}
loop();

Performance Tips

Avoid allocating objects inside the loop, batch draw calls, and only redraw what changed when possible. Keep per-frame work small to stay under the ~16ms budget for 60fps.

Quick Check

Test your animation knowledge.

Recap: Animation

You built animation loops with requestAnimationFrame, cleared each frame with clearRect, used the timestamp for frame-rate independence, animated bouncing balls and multiple objects, applied easing, and learned to stop/pause with cancelAnimationFrame.

Free to start

Learn JavaScript with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
59
Lessons
200

Frequently Asked Questions

Is the “Animation with requestAnimationFrame” lesson free?

Yes — any 3 lessons of the JavaScript Academy learning path, including “Animation with requestAnimationFrame”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The JavaScript Academy course includes 4 lessons in total.

What will I learn in “Animation with requestAnimationFrame”?

Create smooth canvas animations. You practise JavaScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start JavaScript Academy?

No prior experience is required. JavaScript Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.

How long does the “Animation with requestAnimationFrame” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this JavaScript Academy lesson?

Yes. Every JavaScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Setting Up the Canvas Context
  2. Drawing Shapes and Paths
  3. Working with Images and Text
  4. Animation with requestAnimationFrame
← Back to JavaScript Academy