Skip to Content
Course content

96: Drawing Shapes and Animations with Canvas

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I want to start today with a snippet of code that I've seen a dozen learners struggle with. You've got your canvas set up, you're using requestAnimationFrame, and you're trying to move a simple circle across the screen. But instead of a ball moving, you get... a giant, growing smear of paint.

const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
let x = 50;

function animate() {
  ctx.beginPath();
  ctx.arc(x, 100, 20, 0, Math.PI * 2);
  ctx.fill();
  
  x += 2;
  requestAnimationFrame(animate);
}
animate();

The Endless Smear

If you run this, you'll notice the circle doesn't actually move; it just grows into a long, solid pill shape. This is the most common "gotcha" in Canvas. The reason is that the HTML5 Canvas is essentially a piece of digital paper. When you call ctx.fill(), you aren't creating an "object" that you can move around later. You are painting pixels onto a surface.

In the code above, we're painting a circle at 50px, then 52px, then 54px. But we never told the browser to erase the previous frame. The old circles are still there, and we're just layering new ones on top of them. It's like trying to animate a flipbook but refusing to turn the page.

Wiping the Slate Clean

To fix this, we need to clear the canvas at the start of every single frame. We do this using clearRect(). This method takes the x, y coordinates and the width and height of the area you want to erase.

function animate() {
  // Clear the entire canvas before drawing the next frame
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  ctx.beginPath();
  ctx.arc(x, 100, 20, 0, Math.PI * 2);
  ctx.fill();
  
  x += 2;
  requestAnimationFrame(animate);
}

Now, the loop becomes: Clear $\rightarrow$ Update State $\rightarrow$ Draw $\rightarrow$ Repeat. This happens so fast (usually 60 times per second) that the human eye perceives it as smooth motion rather than a series of deletions and redraws.

Managing Your Path State

Another thing that trips people up is the "Ghost Line" bug. You try to draw three separate circles, but for some reason, there are weird lines connecting them. This happens because the Canvas context is a state machine. When you call beginPath(), you're telling the canvas, "Start a new shape here."

If you forget beginPath() inside a loop or when switching shapes, the canvas assumes you're still working on the previous path. It will try to connect the end of your last shape to the start of your next one. I always tell my students: if you're drawing something new, start with beginPath(). No exceptions.

The Animation Heartbeat

You might be tempted to use setInterval for animations, but don't. requestAnimationFrame is the professional standard for a few reasons. First, it syncs with the browser's refresh rate. Second, it's smart—if the user switches tabs, the browser pauses the animation, saving the user's CPU and battery.

When building a complex animation, I find it helpful to separate the logic from the rendering. Create an update() function to handle the math (velocity, collisions, gravity) and a draw() function to handle the colors and shapes. This keeps your code from turning into a giant, unreadable mess as your project grows.




📋 Practical Task

Exercise: Create a Bouncing Neon Ball with Wall Collisions

Your goal is to build an animation where a neon-colored ball bounces realistically around the edges of the canvas.

  • The Setup: Create a canvas that fills a good portion of the screen.
  • The Movement: Give the ball an x and y position, and an vx (velocity X) and vy (velocity Y).
  • The Collision: Write logic to detect when the ball's edge touches the canvas boundary. When it hits a wall, reverse the velocity for that axis (e.g., vx = -vx) to make it bounce.
  • The Visuals: Use ctx.shadowBlur and ctx.shadowColor to give the ball a "neon glow" effect.
  • The Loop: Ensure the canvas is cleared every frame so there is no trailing smear.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.