Drawing & Movement

Learn the Canvas coordinate system, draw a few shapes, then move a rectangle by changing its position each frame. Keyboard control comes in the next input lesson.

The Canvas Coordinate System

Unlike traditional math class, the Canvas coordinate system has its origin (0, 0) at the top-left corner:

Canvas Coordinates

(0,0) ────────────────→ X (800)
  │
  │
  │    (100, 100) = 100px right, 100px down
  │
  ↓
  Y (600)

Drawing Basic Shapes

The Canvas 2D API provides methods for drawing various shapes. Here are the most useful ones:

Rectangles

// Filled rectangle
ctx.fillStyle = '#4ade80';  // Set fill color
ctx.fillRect(x, y, width, height);

// Stroked rectangle (outline only)
ctx.strokeStyle = '#ff00ff';
ctx.lineWidth = 3;
ctx.strokeRect(x, y, width, height);

// Clear a rectangular area
ctx.clearRect(x, y, width, height);

Circles (using arcs)

ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
ctx.fillStyle = '#00ffff';
ctx.fill();
ctx.closePath();

Lines

ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.strokeStyle = '#ffffff';
ctx.lineWidth = 2;
ctx.stroke();

Try it on this page

The green box is a rectangle. The cyan mark is a circle. Use the slider to move both without a keyboard yet.

Making Things Move

Movement in games is just changing the position over time. Remember our game loop? Each frame, we:

  1. Update — Change the position (e.g., x += speed)
  2. Clear — Wipe the canvas
  3. Draw — Render at the new position
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

// Player state
let player = {
    x: 50,
    y: 200,
    width: 40,
    height: 40,
    speed: 3
};

function gameLoop() {
    // UPDATE: Move right
    player.x += player.speed;

    // Wrap around screen
    if (player.x > canvas.width) {
        player.x = -player.width;
    }

    // CLEAR
    ctx.fillStyle = '#111';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // DRAW
    ctx.fillStyle = '#4ade80';
    ctx.fillRect(player.x, player.y, player.width, player.height);

    requestAnimationFrame(gameLoop);
}

gameLoop();

See the loop draw

Open the Game Loop template in the Playground and change the rectangle color or speed. Keyboard steering is the next lesson, not this one.

Open in Playground

Keeping Objects on Screen

Prevent objects from leaving the canvas with boundary checks:

function clampToCanvas(obj) {
    // Left boundary
    if (obj.x < 0) obj.x = 0;
    // Right boundary
    if (obj.x + obj.width > canvas.width) {
        obj.x = canvas.width - obj.width;
    }
    // Top boundary
    if (obj.y < 0) obj.y = 0;
    // Bottom boundary
    if (obj.y + obj.height > canvas.height) {
        obj.y = canvas.height - obj.height;
    }
}

You can now draw shapes and move them by changing position each frame. Next, give that movement a heartbeat with the game loop, then add keyboard and touch input.

Continue learning: The game loop · Input controls · Try the playground

Before you continue

Direct answer: Canvas draws pixels through a 2D context; movement comes from changing a position over time and redrawing the frame.

What you need first

Finish setup and understand x/y coordinates.

After this lesson

You can explain the idea, change the supplied example, and choose the next related lesson.

When to use it

Use Canvas for sprites, shapes, and effects. Do not use it for text that must remain searchable or selectable.

Common mistake

Forgetting to clear the previous frame, which leaves trails behind moving objects.

Try it and check it

This lesson includes its runnable example or code experiment above. Change one value, run it again, and confirm the visible result changes before moving on.

Real game connection

Compare the idea with the moving pieces in Snake.

Compatibility: Test in a current Chrome, Firefox, Safari, or Edge browser. Canvas and standard input work broadly in current browsers; audio still needs a user action.

Source and update

Reviewed against MDN Web Docs. Updated 2026-07-14. This page does not claim performance results beyond the local example check.