Skip to main content

Phase 5 Exercises: HTML5 APIs 🚀

Mentor's Note: HTML5 APIs unlock powerful browser capabilities. You'll draw graphics with Canvas, store data with localStorage, and create animations — all using nothing but HTML and the built-in browser APIs!

📍 Prerequisites

Before attempting these exercises, complete these lessons:

🎯 Exercise Flow


🔰 Starter Challenge: Canvas House Drawing

Title

Draw a Simple House Using Canvas

Description

Use the HTML Canvas API to draw a house scene. The house should include a rectangular body, a triangular roof, windows, a door, and a chimney. This exercise teaches you the fundamental Canvas 2D drawing methods: fillRect, fillStyle, beginPath, moveTo, lineTo, closePath, and fill.

Learning Objectives

  • Get the 2D rendering context from a <canvas> element
  • Draw rectangles with fillRect and strokeRect
  • Draw polygons using beginPath, moveTo, lineTo, closePath
  • Set fill and stroke colors with fillStyle and strokeStyle
  • Set line width with lineWidth

HTML Starter Code

<!DOCTYPE html>
<html>
<head>
<title>Canvas House</title>
</head>
<body>
<h1>Draw a House with Canvas</h1>

<canvas id="houseCanvas" width="500" height="400" style="border:1px solid #ccc;">
Your browser does not support the canvas element.
</canvas>

<script>
const canvas = document.getElementById('houseCanvas');
const ctx = canvas.getContext('2d');

// Sky background
ctx.fillStyle = '#E8F4FD';
ctx.fillRect(0, 0, 500, 400);

// Sun
ctx.fillStyle = '#FFD93D';
ctx.beginPath();
ctx.arc(430, 50, 35, 0, Math.PI * 2);
ctx.fill();

// House body
ctx.fillStyle = '#A8E6CF';
ctx.fillRect(150, 180, 200, 150);
ctx.strokeStyle = '#333';
ctx.lineWidth = 2;
ctx.strokeRect(150, 180, 200, 150);

// Roof (triangle)
ctx.fillStyle = '#FF8B94';
ctx.beginPath();
ctx.moveTo(130, 180);
ctx.lineTo(250, 90);
ctx.lineTo(370, 180);
ctx.closePath();
ctx.fill();
ctx.stroke();

// Door
ctx.fillStyle = '#6C5CE7';
ctx.fillRect(230, 260, 40, 70);
ctx.strokeStyle = '#333';
ctx.strokeRect(230, 260, 40, 70);

// Left window
ctx.fillStyle = '#FFEAA7';
ctx.fillRect(170, 210, 35, 35);
ctx.strokeStyle = '#333';
ctx.strokeRect(170, 210, 35, 35);

// Right window
ctx.fillStyle = '#FFEAA7';
ctx.fillRect(295, 210, 35, 35);
ctx.strokeStyle = '#333';
ctx.strokeRect(295, 210, 35, 35);

// Chimney
ctx.fillStyle = '#E17055';
ctx.fillRect(280, 100, 25, 50);
ctx.strokeStyle = '#333';
ctx.strokeRect(280, 100, 25, 50);

// Ground
ctx.fillStyle = '#81ECEC';
ctx.fillRect(0, 330, 500, 70);
</script>
</body>
</html>

Expected Output

A browser page showing a canvas drawing of:

  • A light blue sky background with a yellow sun (circle)
  • A green rectangular house body
  • A pink triangular roof
  • A purple door centered on the house
  • Two yellow square windows (one on each side of the door)
  • A brown chimney on the roof
  • A teal ground section

⭐ Medium Challenge: LocalStorage To-Do List

Title

Build a localStorage-Based To-Do List (HTML Structure)

Description

Create the HTML structure for a to-do list application that uses the localStorage API for data persistence. This exercise focuses on building the HTML scaffolding and understanding how localStorage works — you'll write the JavaScript pseudocode/explanation alongside the HTML.

Learning Objectives

  • Understand the localStorage API (setItem, getItem, removeItem)
  • Structure HTML for a dynamic list-based application
  • Design a clear user interface for adding, displaying, and deleting items
  • Write pseudocode that explains the JavaScript logic needed
  • Understand how localStorage persists data across browser sessions

HTML Starter Code

<!DOCTYPE html>
<html>
<head>
<title>My To-Do List</title>
</head>
<body>
<h1>My To-Do List</h1>

<!-- Add Task Section -->
<div>
<label for="taskInput">New Task:</label>
<input type="text" id="taskInput" placeholder="Enter a new task..." maxlength="100">
<button id="addBtn">Add Task</button>
</div>

<!-- Task List -->
<h2>Tasks</h2>
<ul id="taskList">
<!-- Tasks will be displayed here dynamically -->
<!-- Example: <li><span>Buy groceries</span> <button class="delete-btn">✕</button></li> -->
</ul>

<!-- Controls -->
<div>
<button id="clearAllBtn">Clear All Tasks</button>
</div>

<!-- Stats -->
<p id="taskCount">Total tasks: 0</p>

<script>
/*
* JavaScript Logic Needed:
*
* 1. Load tasks from localStorage on page load
* - const tasks = JSON.parse(localStorage.getItem('tasks')) || [];
* - Render each task as an <li> in #taskList
*
* 2. Add a new task
* - On #addBtn click, read #taskInput value
* - Push to tasks array, save to localStorage
* - Re-render the list
*
* 3. Delete a task
* - On .delete-btn click, remove task from array
* - Update localStorage, re-render
*
* 4. Clear all tasks
* - On #clearAllBtn click, empty the array
* - localStorage.removeItem('tasks')
* - Re-render empty list
*
* 5. Update task count
* - After every change, update #taskCount text
*
* Key localStorage methods:
* - localStorage.setItem('tasks', JSON.stringify(tasks))
* - localStorage.getItem('tasks') -> returns string or null
* - localStorage.removeItem('tasks')
*/
console.log('To-do list ready! Add JavaScript logic to make it functional.');
</script>
</body>
</html>

Expected Output

A browser page showing:

  • An input field and "Add Task" button for new tasks
  • An empty unordered list (#taskList) ready to display tasks
  • A "Clear All Tasks" button
  • A task counter display
  • Console message indicating the JavaScript logic is documented
  • JavaScript pseudocode comments explaining each function

🏆 Hard Challenge: Canvas Bouncing Ball Animation

Title

Build a Bouncing Ball Animation with Canvas

Description

Create a canvas animation that shows a ball bouncing off the walls of the canvas. The ball should move in 2D space, reverse direction when hitting any edge, and optionally change color on each bounce. This exercise introduces animation loops using requestAnimationFrame, velocity-based movement, and collision detection.

Learning Objectives

  • Use requestAnimationFrame for smooth 60fps animation
  • Track position (x, y) and velocity (dx, dy) of objects
  • Implement collision detection against canvas boundaries
  • Clear and redraw the canvas each frame
  • Add visual enhancements like color changes on bounce

HTML Starter Code

<!DOCTYPE html>
<html>
<head>
<title>Bouncing Ball Animation</title>
</head>
<body>
<h1>Bouncing Ball</h1>
<p>Watch the ball bounce off the walls!</p>

<canvas id="bounceCanvas" width="500" height="400" style="border:1px solid #333; background: #1a1a2e;">
Your browser does not support the canvas element.
</canvas>

<script>
const canvas = document.getElementById('bounceCanvas');
const ctx = canvas.getContext('2d');

// Ball properties
let x = 250; // Starting X position (center)
let y = 200; // Starting Y position (center)
let dx = 3; // X velocity (pixels per frame)
let dy = 4; // Y velocity (pixels per frame)
const radius = 20;

// Colors
let ballColor = '#FF6B6B';
const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#98D8C8', '#F7DC6F', '#BB8FCE'];

function drawBall() {
// Clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);

// Draw the ball
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fillStyle = ballColor;
ctx.fill();
ctx.strokeStyle = '#fff';
ctx.lineWidth = 2;
ctx.stroke();
ctx.closePath();
}

function updatePosition() {
// Move the ball
x += dx;
y += dy;

// Bounce off walls (collision detection)
if (x + radius > canvas.width || x - radius < 0) {
dx = -dx; // Reverse X direction
ballColor = colors[Math.floor(Math.random() * colors.length)];
}

if (y + radius > canvas.height || y - radius < 0) {
dy = -dy; // Reverse Y direction
ballColor = colors[Math.floor(Math.random() * colors.length)];
}
}

function animate() {
updatePosition();
drawBall();
requestAnimationFrame(animate);
}

// Start the animation
animate();
</script>
</body>
</html>

Expected Output

A browser page showing:

  • A dark background canvas (500×400) with a colored circle
  • The ball moves smoothly across the canvas
  • The ball reverses direction when it hits any edge (bounces)
  • The ball changes to a random color each time it bounces
  • Animation runs at 60fps using requestAnimationFrame

💡 Tips for Success

  • Use requestAnimationFrame instead of setInterval — it's smoother and pauses when the tab is inactive
  • Always call ctx.beginPath() before drawing a new shape to avoid path accumulation
  • Clear the canvas with ctx.clearRect(0, 0, width, height) at the start of each frame
  • For localStorage: always use JSON.stringify when saving arrays/objects
  • Use console.log to debug canvas positions and velocities during development

← Back to HTML Exercises