Skip to content
Topic 1 of 5
Theory

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, y grows 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.

Red Rectangle

Easy+10 XP

Draw a filled red rectangle on the #game canvas: the top-left corner at the point (50, 40), width 100, height 60. The color is "red".

(50, 40) ┌──────────┐
         │   red    │ 60
         └──────────┘
             100

Connect the connector to solve tasks

Task code runs on your own computer — faster and more reliable than in the browser. This needs the free CodeWithMe connector app. You only connect it once.

Looking for the connector on this computer…

  1. 1
    Download the connector for your system (Windows, macOS or Linux).Download the connectorOn the download page pick the file with your system in its name, e.g. windows-amd64.
  2. 2Run it and choose a folder for your solutions. It will install Python and Node.js there by itself when needed.
  3. 3
    Enter below the 6-digit code shown in the connector window (“Code for CodeWithMe”). If the browser asks about local network access — allow it.

The connector is open source (on GitHub), works only on your computer and runs code only after you enter the pairing code.