JS Canvas
In this page:
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
<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
<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
<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
<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
<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>
- 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.
- 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.
- Mixing up fillStyle (used by fill()) with strokeStyle (used by stroke()) and wondering why a color setting seems to have no visible effect.
- 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.
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: