Canvas and Shapes
A canvas is a picture made of pixels
For games in the browser there is the <canvas> element — a rectangle of pixels that you draw on from
JavaScript. Unlike ordinary page elements, there are no "objects" on a canvas: you drew a
rectangle — and it's just colored pixels. To move something, the frame is erased and drawn
again. That's exactly how almost all 2D games work.
<canvas id="game" width="400" height="300"></canvas>
The canvas size is set with the width and height attributes — this is the size in pixels. (If you stretch the canvas
with CSS, the picture is simply scaled and becomes blurry.)
The drawing context
You don't draw on the element itself, but through its context — an object with all the drawing commands:
const canvas = document.querySelector("#game");
const ctx = canvas.getContext("2d");
ctx is a short, commonly used name. From now on all commands are called on it.
Coordinates
The origin (0, 0) is the top-left corner of the canvas. x grows to the right, y grows down (not
up, as in school math!). The bottom-right pixel of a 400×300 canvas is (399, 299).
(0,0) ──────────► x
│
│ • (100, 50)
▼
y
Rectangles and color
ctx.fillStyle = "orange"; // fill color for the next shapes
ctx.fillRect(20, 30, 120, 80); // x, y, width, height — filled
ctx.strokeStyle = "#1e88e5"; // line color
ctx.lineWidth = 4; // line thickness
ctx.strokeRect(200, 30, 120, 80); // only the outline
ctx.clearRect(0, 0, canvas.width, canvas.height); // erase everything (transparent pixels)
A color can be given just like in CSS: a name "red", "#ff0000", "rgb(255, 0, 0)", with transparency
"rgba(0, 0, 0, 0.5)". fillStyle applies to all following shapes until it's changed — forget
to change the color, and everything is drawn with the old one.
Lines and paths
Complex shapes are drawn with a path: you begin a path, move the "pen", and then stroke or fill it:
ctx.beginPath();
ctx.moveTo(50, 250); // put the pen down without drawing
ctx.lineTo(150, 150); // draw a line
ctx.lineTo(250, 250);
ctx.closePath(); // close back to the start — we get a triangle
ctx.fillStyle = "green";
ctx.fill(); // fill
ctx.stroke(); // and stroke
beginPath() matters: without it the new shape "sticks" to the old path, and fill() will recolor
everything at once.
Circles
A circle is an arc arc(x, y, radius, startAngle, endAngle). Angles are in radians: a full circle is
Math.PI * 2.
ctx.beginPath();
ctx.arc(300, 200, 40, 0, Math.PI * 2);
ctx.fillStyle = "gold";
ctx.fill();
For a circle x, y is the center, while for a rectangle it's the top-left corner. This is a common source of confusion in
collisions; we'll come back to it later.
Text
ctx.font = "24px sans-serif";
ctx.fillStyle = "black";
ctx.fillText("Score: 120", 10, 30); // x, y — the left end of the text baseline
ctx.textAlign = "center"; // now x is the middle of the text
ctx.fillText("GAME OVER", canvas.width / 2, 150);
Order matters
A canvas is like paper: what's drawn later covers what was drawn earlier. That's why every frame of a game is drawn from far to near: background → objects → interface (score, lives).
Checking a pixel's color
You can find out a pixel's color with getImageData: it returns an array [red, green, blue, alpha], each from 0 to 255. This is how the tasks in this course are checked:
const [r, g, b, a] = ctx.getImageData(100, 70, 1, 1).data;
console.log(r, g, b, a); // 255 0 0 255 — opaque red
A transparent (not yet painted) pixel is 0 0 0 0.
Summary
canvas.getContext("2d")— the context with drawing commands.(0, 0)is the top-left corner,ygrows downward.fillStyle+fillRect,strokeStyle+strokeRect,clearRect— erase.- Paths:
beginPath→moveTo/lineTo/arc→fill/stroke. - What's drawn later lies on top; a game frame means erasing and drawing everything again.