By the end of this guide, you’ll have a working animated bouncing ball running in your browser, built entirely with HTML and JavaScript. No libraries, no installs, just a text editor and the browser you already have open.
What Is the HTML5 Canvas Element?
The HTML5 Canvas element is a blank drawing surface built into every modern browser that JavaScript can paint on. Think of it like a whiteboard sitting inside your webpage. By default it’s invisible and empty. JavaScript is the marker you use to draw on it.
Canvas is used for browser-based games, data visualizations, drawing tools, and animations. You’ve probably seen canvas at work without knowing it. Those interactive charts, particle effects, and mini-games embedded in websites? Many of them run on the Canvas API, a set of JavaScript drawing tools the browser gives you for free.
This article covers 2D canvas only. There’s a separate technology called WebGL for 3D graphics, which is a much bigger topic. We’re keeping things focused and practical here.
How to Set Up the HTML5 Canvas Element
You only need one HTML file to get started. Open your text editor and create a file called canvas.html. Paste this boilerplate in:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Canvas</title>
</head>
<body>
<canvas id="myCanvas" width="600" height="400" style="border:1px solid #ccc;"></canvas>
<script src="sketch.js"></script>
</body>
</html>
The width and height attributes set the actual pixel dimensions of the drawing surface. Don’t set these with CSS alone. CSS resizes the visual display but not the internal coordinate grid, which causes blurry or distorted drawings. Always set width and height directly on the canvas tag.
Open the file in your browser. You should see a light grey bordered rectangle. That’s your canvas. Now create sketch.js in the same folder.
Connecting JavaScript to the Canvas
Add this to your sketch.js file:
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
The first line finds your canvas element in the HTML by its ID. The second line calls getContext('2d'), which gives you the CanvasRenderingContext2D, a collection of drawing tools JavaScript makes available for 2D graphics. We store it in a variable called ctx. Every drawing command you write goes through ctx. If you forget this line, nothing will draw and you won’t get an obvious error, which is one of the most common beginner mistakes.
Understanding the Canvas Coordinate System
Before you draw anything, you need to know where things go. The top-left corner of your canvas is position (0, 0). Moving right increases the X value. Moving down increases the Y value.
This trips up a lot of beginners because it’s the opposite of math class, where Y increases as you go up. On canvas, Y increases as you go down. Picture a grid of graph paper where the origin is pinned to the top-left corner instead of the center. Once that clicks, placing shapes gets much easier.
So on a 600×400 canvas, the center is roughly at (300, 200), and the bottom-right corner is at (600, 400).
Drawing Your First Shapes on Canvas
How to Draw a Rectangle
fillRect draws a filled rectangle. It takes four arguments: x position, y position, width, and height. Before you call it, set fillStyle to choose a color.
ctx.fillStyle = 'steelblue';
ctx.fillRect(50, 50, 200, 100);
This draws a blue rectangle starting 50 pixels from the left and 50 pixels from the top, with a width of 200 and height of 100. Try changing those numbers. Experimenting with the values is the fastest way to get comfortable with the coordinate system.
How to Draw a Circle
Circles use the arc method, which draws a curved path. You need beginPath to start a new path, arc to define the circle, and fill to paint it in.
ctx.beginPath();
ctx.arc(300, 200, 50, 0, Math.PI * 2);
ctx.fillStyle = 'tomato';
ctx.fill();
The arc arguments are: center X, center Y, radius, start angle, end angle. Using Math.PI * 2 as the end angle draws a complete circle. A common mistake here is using degrees instead of radians. Canvas always expects radians, so a full circle is Math.PI * 2, not 360.
How to Draw a Line
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(200, 150);
ctx.strokeStyle = 'green';
ctx.lineWidth = 3;
ctx.stroke();
moveTo lifts the pen to a starting point. lineTo draws the path to an end point. stroke actually renders the line. Without calling stroke, nothing appears.
Clearing the Canvas Between Frames
Animation works by drawing, erasing, and redrawing very quickly. Without erasing, each new frame stacks on top of the old one, creating a smear trail. The clearRect method wipes the canvas clean.
ctx.clearRect(0, 0, canvas.width, canvas.height);
This clears the entire canvas from corner to corner. You’ll call this at the start of every animation frame, before drawing the updated scene.
How to Create an Animation Loop With requestAnimationFrame
requestAnimationFrame is a browser built-in that calls your drawing function roughly 60 times per second, creating smooth animation. It’s preferred over setInterval because it syncs with the browser’s own repaint cycle, which means smoother visuals and better performance. setInterval fires on a fixed timer regardless of what the browser is doing, which can cause jitter.
The animation loop pattern looks like this:
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// draw your scene here
requestAnimationFrame(animate);
}
animate();
The function calls itself at the end. This might look strange at first, and that’s completely normal. The function isn’t running infinitely on its own. It’s telling the browser: “When you’re ready to paint the next frame, call me again.” The browser controls the timing, which is what keeps things smooth.
Build It: A Bouncing Ball Animation
Now we put it all together. Here’s the complete working code for a bouncing ball. Create a fresh sketch.js and paste this in:
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Ball properties
let x = canvas.width / 2;
let y = canvas.height / 2;
const radius = 20;
let speedX = 4;
let speedY = 3;
function draw() {
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Draw the ball
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fillStyle = 'tomato';
ctx.fill();
ctx.closePath();
// Move the ball
x += speedX;
y += speedY;
// Bounce off left and right walls
if (x + radius > canvas.width || x - radius < 0) {
speedX = -speedX;
}
// Bounce off top and bottom walls
if (y + radius > canvas.height || y - radius < 0) {
speedY = -speedY;
}
requestAnimationFrame(draw);
}
draw();
Open your HTML file in a browser. You'll see a red ball bouncing around the canvas, reversing direction each time it hits a wall.
The boundary detection checks whether the ball's edge (center plus or minus radius) has reached any wall. When it does, the speed value flips to negative, reversing direction. That's the whole trick. Try changing speedX, speedY, radius, or fillStyle to make it your own.
Now that you've built a bouncing ball from scratch, you've already crossed into game development territory — and that's no small thing. Games are one of the most effective ways to sharpen your JavaScript skills because they force you to think about logic, timing, and user interaction all at once. There's a reason so many developers swear by this approach: the connection between game-building and JavaScript fluency is real, and the next few projects on this list are designed to push you further down that path.
Three Common Beginner Mistakes to Avoid
- Forgetting
getContext('2d'): Without this line,ctxis undefined and nothing draws. You won't always get a clear error, so check this first if your canvas is blank. - Using degrees instead of radians in
arc: Canvas uses radians. A full circle isMath.PI * 2. If your circle looks like a pie slice, this is likely why. - Setting canvas size with CSS only: This stretches the drawing surface and blurs your graphics. Always set
widthandheightas attributes on the canvas tag itself.
What to Build Next With HTML5 Canvas
You just built a live animation from scratch. That's a real result. Three good next projects to try: a simple drawing app where mouse movement leaves a trail, a color-changing animation that cycles through hues each frame, or a basic Pong-style game that adds a paddle controlled by keyboard input.
MDN Web Docs has a full Canvas API reference that lists every available drawing method. Bookmark it. You'll return to it often as you build more complex things.
Every canvas project you build from here, whether it's a particle system, a game, or an interactive chart, uses exactly the same foundation: get the context, draw shapes, clear between frames, and loop with requestAnimationFrame. You've got the foundation. Keep building.
Frequently Asked Questions About HTML5 Canvas
How do I draw a circle on an HTML5 canvas?
Call ctx.beginPath(), then ctx.arc(x, y, radius, 0, Math.PI * 2), then ctx.fill(). The arc method takes center coordinates, a radius, and start and end angles in radians.
What is requestAnimationFrame used for?
It schedules your drawing function to run before the browser's next repaint, roughly 60 times per second. This creates smooth animation and is more efficient than using setInterval for canvas loops.
Can I animate without a library in JavaScript?
Yes. The HTML5 Canvas API and requestAnimationFrame are built into every modern browser. You don't need React, Three.js, or any other library to build animations from scratch.
Why is my canvas element not showing anything?
Check three things: make sure you called getContext('2d'), confirm your canvas has explicit width and height attributes, and verify your JavaScript file is linked correctly in your HTML before the closing body tag.

Brian Taylor is a JavaScript developer and educator, dedicated to demystifying programming for newcomers. With a career spanning over a decade in web development, Brian has a deep understanding of JavaScript and its ecosystem. He is passionate about teaching and has helped countless beginners grasp the fundamentals of JavaScript, enabling them to build their own web applications.



