🖼️ Lesson 7: Drawing on a Canvas

A blank rectangle, and code that paints on it

← Back to Web Coding

🖼️ A rectangle you can paint on

A <canvas> is a blank patch of page. HTML gives you the patch; it cannot draw a single thing on it. Everything you see on a canvas was put there by JavaScript — which means every picture is a program.

Two steps to get started, and they are the same two every time:

<canvas id="board" width="300" height="160"></canvas> <script> const canvas = document.getElementById("board"); const ctx = canvas.getContext("2d"); ctx.fillStyle = "crimson"; ctx.fillRect(20, 20, 120, 80); </script> Try it — this is live
  • getElementById finds the canvas — same as Lesson 6.
  • getContext("2d") hands you the brush. Everybody calls it ctx.

┈ About that dashed line

A canvas has no edge of its own — it is completely invisible until you draw. The faint dashed grey line round every canvas in these lessons is put there by the page, just so you can see where the edges are. It is not part of the picture and you never have to draw it.

On a page of your own you would add a real one yourself with CSS: <canvas style="border:2px solid #333">.

📏 Set the size in the HTML, not the CSS

width="300" height="160" as attributes sets how many pixels the canvas has. Setting it in CSS instead stretches those pixels like a blown-up photo, and everything goes blurry.

🧭 Where is (0, 0)?

Top-left. And y grows downwards — this trips up everyone who did coordinates in maths class.

const ctx = document.getElementById("board").getContext("2d"); ctx.fillStyle = "#1a5490"; ctx.fillRect(0, 0, 40, 40); ctx.fillStyle = "seagreen"; ctx.fillRect(120, 0, 40, 40); ctx.fillStyle = "darkorange"; ctx.fillRect(0, 100, 40, 40); ctx.fillStyle = "#111"; ctx.font = "13px monospace"; ctx.fillText("(0,0) is up here", 50, 25); ctx.fillText("bigger y = further DOWN", 50, 125); Try it — this is live

🔢 Every measurement is in pixels

No centimetres, no percentages. (120, 40) means 120 pixels across from the left edge and 40 pixels down from the top.

🟦 Rectangles

Three commands, and all four numbers mean the same thing every time: x, y, width, height.

const ctx = document.getElementById("board").getContext("2d"); ctx.fillStyle = "#4a90d9"; ctx.fillRect(20, 20, 90, 60); ctx.strokeStyle = "crimson"; ctx.lineWidth = 4; ctx.strokeRect(130, 20, 90, 60); ctx.fillStyle = "gold"; ctx.fillRect(20, 110, 200, 60); ctx.clearRect(60, 130, 60, 30); Try it — this is live
CommandWhat it does
ctx.fillRect(x, y, w, h)a solid rectangle
ctx.strokeRect(x, y, w, h)just the outline
ctx.clearRect(x, y, w, h)rubs that patch out
ctx.fillStyle = "…"the colour fills use
ctx.strokeStyle = "…"the colour outlines use
ctx.lineWidth = 4how thick outlines are

Notice the pattern: fillStyle and lineWidth are settings you change, and they stay changed until you change them again. fillRect is an action. Set the paint, then paint.

📏 Lines and paths

A line is not one command — it is a little journey. Start a path, move the pen, draw to somewhere, then say what to do with it.

const ctx = document.getElementById("board").getContext("2d"); ctx.strokeStyle = "#1a5490"; ctx.lineWidth = 5; ctx.beginPath(); ctx.moveTo(30, 30); ctx.lineTo(270, 30); ctx.stroke(); ctx.beginPath(); ctx.moveTo(30, 70); ctx.lineTo(150, 200); ctx.lineTo(270, 70); ctx.closePath(); ctx.stroke(); Try it — this is live
  • beginPath() — forget the last shape, start fresh
  • moveTo(x, y) — lift the pen and put it here
  • lineTo(x, y) — draw from where the pen is to here
  • closePath() — draw back to where the path started
  • stroke() — actually ink it. Or fill() to colour it in.

😖 Forgetting beginPath

Leave it out and the new shape joins on to the old one — and every stroke() redraws everything in the path, so old lines get thicker and change colour. If your drawing is mysteriously all one colour, this is why.

✍️ Writing on the canvas

const ctx = document.getElementById("board").getContext("2d"); ctx.fillStyle = "#1a5490"; ctx.font = "bold 30px sans-serif"; ctx.fillText("Hello!", 20, 50); ctx.font = "16px monospace"; ctx.fillStyle = "seagreen"; ctx.fillText("small and green", 20, 90); ctx.strokeStyle = "crimson"; ctx.lineWidth = 1; ctx.strokeText("outlined", 20, 130); Try it — this is live

📐 Text sits ON the y line

The y you give fillText is the baseline — the line the letters stand on, not their top. Ask for y = 0 and the text is above the canvas where nobody can see it.

✅ What you learned

  • <canvas width height> makes the patch; JavaScript does all the drawing.
  • const ctx = canvas.getContext("2d") — every drawing starts here.
  • (0, 0) is top-left and y grows downwards.
  • Rectangles take x, y, width, height.
  • Settings (fillStyle) stay set; actions (fillRect) happen once.
  • Lines need beginPathmoveTolineTostroke.
← Lesson 6: Making the Page Do Things Lesson 8: Circles, Loops & Art →