← Back to JavaScript Course | Chapter 10: DOM Advanced | Lesson 7 of 8

JS Canvas

The Canvas 2D drawing context is the actual API you use to paint onto a canvas element -- a rich set of methods for drawing rectangles, paths, text, and images, controlling fill and stroke colors, and combining these primitives into any custom shape you can describe with code.

Drawing Basic Rectangles

fillRect(x, y, width, height) draws a filled rectangle, strokeRect() draws just its outline, and clearRect() erases a rectangular area back to transparent -- the three simplest drawing operations, and often the first ones learned.

Note: Use clearRect(0, 0, canvas.width, canvas.height) at the start of each redraw in an animation to wipe the previous frame before drawing the new one.

Warning: fillRect() paints using the current fillStyle color, which stays set until changed -- forgetting to reset it before the next shape can produce unexpectedly colored output.

Example: Drawing Basic Rectangles

javascript
<canvas id="c" width="150" height="100"></canvas>
<script>
  const ctx = document.getElementById("c").getContext("2d");
  ctx.fillRect(10, 10, 50, 30);
  ctx.strokeRect(70, 10, 50, 30);
  ctx.clearRect(20, 15, 10, 10);
</script>

Drawing Custom Paths

beginPath() starts a new shape, moveTo(x, y) moves the drawing "pen" without drawing, lineTo(x, y) draws a straight line from the current position, and closePath() connects back to the starting point -- combined, these build any custom polygon shape point by point.

Note: Always call beginPath() before starting a new, unrelated shape -- forgetting it can connect the new shape's lines to whatever path was drawn previously.

Warning: A path built with moveTo/lineTo produces no visible output until you call fill() or stroke() afterward -- the path itself is invisible.

Example: Drawing Custom Paths

javascript
<canvas id="c" width="150" height="100"></canvas>
<script>
  const ctx = document.getElementById("c").getContext("2d");
  ctx.beginPath();
  ctx.moveTo(10, 10);
  ctx.lineTo(100, 10);
  ctx.lineTo(50, 80);
  ctx.closePath();
  ctx.stroke();
</script>

Drawing Circles and Arcs

arc(x, y, radius, startAngle, endAngle) draws a circular arc -- passing 0 to Math.PI * 2 as the angles draws a complete circle, while other angle ranges draw partial arcs, the basis for pie-slice shapes and rounded visual elements.

Note: Remember that arc() angles are measured in radians, not degrees -- use Math.PI * 2 for a full circle rather than 360.

Warning: arc() alone only defines the curved path -- combine it with fill() or stroke() to actually render it, just like any other path.

Example: Drawing Circles and Arcs

javascript
<canvas id="c" width="150" height="100"></canvas>
<script>
  const ctx = document.getElementById("c").getContext("2d");
  ctx.beginPath();
  ctx.arc(50, 50, 40, 0, Math.PI * 2); // full circle
  ctx.stroke();
</script>

Drawing Text and Images

fillText(text, x, y) draws text directly onto the canvas using the current font setting, and drawImage(imageElement, x, y) draws an already-loaded <img> element (or another canvas) onto the canvas -- letting you combine graphics, photos, and labels together.

Note: Set the font property before calling fillText(), similar to how fillStyle must be set before fill(), since both are read at draw time.

Warning: drawImage() called before the source image has finished loading draws nothing (or a blank frame) -- wait for the image's load event first.

Example: Drawing Text and Images

javascript
<canvas id="c" width="150" height="100"></canvas>
<script>
  const ctx = document.getElementById("c").getContext("2d");
  ctx.font = "20px sans-serif";
  ctx.fillText("Hello Canvas", 10, 50);
</script>

Building a Simple Animation Loop

requestAnimationFrame(callback) schedules a function to run right before the browser's next repaint, smoothly synced to the display's refresh rate -- calling it again inside the callback itself creates a continuous, efficient animation loop.

Note: Always clear the canvas at the start of each animation frame before redrawing, unless a "trailing" visual effect is specifically intended.

Warning: Using setInterval() instead of requestAnimationFrame() for animation can produce a less smooth result and continues running even when the tab is not visible, wasting resources.

Example: Building a Simple Animation Loop

javascript
<canvas id="c" width="150" height="100"></canvas>
<script>
  const ctx = document.getElementById("c").getContext("2d");
  let x = 0;
  function animate() {
    ctx.clearRect(0, 0, 150, 100);
    ctx.fillRect(x, 40, 20, 20);
    x = (x + 1) % 150;
    requestAnimationFrame(animate);
  }
  animate();
</script>
Common Mistakes
  1. Forgetting that path-drawing methods like moveTo() and lineTo() only define a path -- nothing actually renders until you call fill() or stroke() to paint it.
  2. Not clearing the canvas with clearRect() before redrawing a new frame in an animation, causing every frame to draw on top of the last instead of replacing it.
  3. Mixing up fillStyle (used by fill()) with strokeStyle (used by stroke()) and wondering why a color setting seems to have no visible effect.
Chapter Summary
  • getContext("2d") retrieves the drawing context, the object every drawing method is called on.
  • fillRect(), strokeRect(), and clearRect() draw, outline, and erase simple rectangles directly.
  • beginPath(), moveTo(), lineTo(), and closePath() build custom shapes, rendered with a following fill() or stroke() call.
Browser Support

The Canvas 2D API is supported in every modern browser and has been a stable web standard since HTML5.

🔒

Chapter Quiz — Complete all 8 topics to unlock

0/8 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.