Table of Contents
- Setting Up the Canvas Element
- Understanding the Drawing Context
- Basic Shapes and Paths
- Colors, Gradients, and Patterns
- Text Rendering
- Working with Images
- Creating Animations with Canvas
- Advanced Techniques
- Best Practices
- Conclusion
- References
1. Setting Up the Canvas Element
The <canvas> element is the foundation for drawing with Canvas. It acts as a bitmap container where pixels are manipulated via JavaScript.
Basic Canvas HTML Structure
To use Canvas, start by adding the <canvas> tag to your HTML. You’ll need to define its width and height attributes (in pixels) to set the drawing area. Avoid resizing the canvas with CSS, as this stretches or compresses the pixels, leading to blurry graphics.
<canvas id="myCanvas" width="800" height="600">
<!-- Fallback content for browsers that don't support Canvas -->
Your browser does not support HTML5 Canvas.
</canvas>
- The
widthandheightattributes define the coordinate system of the canvas (default: 300x150 pixels). - The fallback content inside the
<canvas>tag is displayed if the browser doesn’t support Canvas (e.g., older browsers).
2. Understanding the Drawing Context
The Canvas element itself is just a container. To draw on it, you need the drawing context—an object that provides methods and properties for rendering graphics. The most common context is 2d, which supports 2D drawing (3D is handled by WebGL, a separate API).
Accessing the 2D Context
Use JavaScript to get the context from the Canvas element:
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d'); // '2d' is the only 2D context; returns null if unsupported
Now ctx (short for “context”) is your drawing tool, with hundreds of methods for shapes, colors, text, and more.
3. Basic Shapes and Paths
Canvas provides built-in methods for simple shapes, but most complex graphics are created using paths—sequences of lines, arcs, and curves.
Rectangles
The easiest shapes to draw are rectangles, with three core methods:
fillRect(x, y, width, height): Draws a filled rectangle.strokeRect(x, y, width, height): Draws a rectangular outline.clearRect(x, y, width, height): Erases a rectangular area (useful for animations).
Example:
// Filled blue rectangle
ctx.fillStyle = 'blue';
ctx.fillRect(50, 50, 150, 100);
// Stroked red rectangle (outline)
ctx.strokeStyle = 'red';
ctx.lineWidth = 5; // Set border thickness
ctx.strokeRect(250, 50, 150, 100);
// Clear a hole in the filled rectangle
ctx.clearRect(80, 80, 70, 40);
Paths
Paths are versatile for drawing lines, polygons, circles, and custom shapes. Use these steps to create a path:
beginPath(): Starts a new path (resets the current path).- Define subpaths with
moveTo(x, y)(moves the “pen” without drawing),lineTo(x, y)(draws a line),arc(), etc. closePath(): Connects the end of the path back to the start (optional for closed shapes).fill()orstroke(): Renders the path (filled or outlined).
Example: Triangle and Circle
// Triangle (path with lines)
ctx.beginPath();
ctx.moveTo(50, 250); // Start at bottom-left
ctx.lineTo(150, 150); // Line to top-middle
ctx.lineTo(250, 250); // Line to bottom-right
ctx.closePath(); // Close the triangle
ctx.fillStyle = 'green';
ctx.fill(); // Fill the triangle
// Circle (arc path)
ctx.beginPath();
// arc(x, y, radius, startAngle, endAngle, anticlockwise)
ctx.arc(400, 200, 80, 0, Math.PI * 2, false); // Full circle (0 to 2π radians)
ctx.strokeStyle = 'purple';
ctx.lineWidth = 3;
ctx.stroke(); // Outline the circle
arc()uses radians for angles (useMath.PIfor 180°,Math.PI * 2for 360°).anticlockwise: falsedraws the arc clockwise (default).
4. Colors, Gradients, and Patterns
Canvas supports solid colors, gradients, and repeating patterns for fills and strokes.
Solid Colors
Use fillStyle and strokeStyle to set colors. Values can be hex codes, RGB/RGBA, HSL/HSLA, or color names:
ctx.fillStyle = '#ff0000'; // Red (hex)
ctx.strokeStyle = 'rgba(0, 255, 0, 0.5)'; // Semi-transparent green
Gradients
Gradients smoothly transition between colors. There are two types:
Linear Gradients
createLinearGradient(x0, y0, x1, y1): Defines a gradient along a line from (x0, y0) to (x1, y1). Add color stops with addColorStop(position, color) (position: 0 = start, 1 = end).
Example:
const linearGradient = ctx.createLinearGradient(50, 350, 250, 350); // Horizontal gradient
linearGradient.addColorStop(0, 'yellow');
linearGradient.addColorStop(0.5, 'orange');
linearGradient.addColorStop(1, 'red');
ctx.fillStyle = linearGradient;
ctx.fillRect(50, 350, 200, 100); // Fill rectangle with gradient
Radial Gradients
createRadialGradient(x0, y0, r0, x1, y1, r1): Defines a gradient from a circle at (x0, y0) with radius r0 to a circle at (x1, y1) with radius r1.
Example:
const radialGradient = ctx.createRadialGradient(400, 400, 10, 400, 400, 80);
radialGradient.addColorStop(0, 'white');
radialGradient.addColorStop(1, 'blue');
ctx.fillStyle = radialGradient;
ctx.beginPath();
ctx.arc(400, 400, 80, 0, Math.PI * 2);
ctx.fill(); // Gradient circle
Patterns
createPattern(image, repetition): Repeats an image in the specified pattern (repeat, repeat-x, repeat-y, or no-repeat).
Example:
const img = new Image();
img.src = 'pattern.png'; // Load an image (ensure CORS compliance for external images)
img.onload = () => {
const pattern = ctx.createPattern(img, 'repeat'); // Tile the image
ctx.fillStyle = pattern;
ctx.fillRect(550, 350, 200, 100); // Pattern-filled rectangle
};
5. Text Rendering
Draw text with fillText(text, x, y) (filled) or strokeText(text, x, y) (outlined). Customize fonts, alignment, and size with context properties.
Basic Text
ctx.font = '30px Arial'; // Font syntax: [style] [variant] [weight] size family
ctx.fillStyle = 'black';
ctx.fillText('Hello Canvas!', 50, 500); // (text, x, y)
// Outlined text
ctx.font = 'bold 40px "Times New Roman"';
ctx.strokeStyle = 'purple';
ctx.strokeText('Outlined Text', 300, 500);
Text Alignment
Use textAlign (left, right, center, start, end) and textBaseline (top, bottom, middle, etc.) to position text:
ctx.font = '24px sans-serif';
ctx.textAlign = 'center'; // Align text horizontally to (x, y)
ctx.textBaseline = 'middle'; // Align text vertically to (x, y)
ctx.fillText('Centered Text', canvas.width / 2, 550); // Center of canvas
6. Working with Images
Draw images onto the canvas using drawImage(), which has multiple overloads for positioning, scaling, and cropping.
Basic Image Drawing
First, load an image (use onload to ensure it’s loaded before drawing):
const img = new Image();
img.src = 'cat.jpg'; // Local or remote image
img.onload = () => {
// Draw image at (x=50, y=600), with original size
ctx.drawImage(img, 50, 600);
// Draw scaled image: (x=300, y=600), width=200, height=150
ctx.drawImage(img, 300, 600, 200, 150);
// Crop and draw: (source x, source y, source width, source height, dest x, dest y, dest width, dest height)
ctx.drawImage(img, 50, 50, 100, 100, 550, 600, 100, 100); // Crop 100x100 from (50,50) and draw at (550,600)
};
Note: For external images, the server must send CORS headers, or the image will taint the canvas (blocking pixel manipulation).
7. Creating Animations with Canvas
Animations on Canvas involve redrawing the canvas repeatedly with updated positions. The best way to do this is with the animation loop, powered by requestAnimationFrame.
The Animation Loop
requestAnimationFrame(callback) tells the browser to run callback before the next repaint, syncing with the display’s refresh rate (typically 60 FPS). This is more efficient than setInterval because it pauses when the tab is inactive.
Example: Bouncing Ball
Let’s create a ball that bounces off the canvas edges. Steps:
- Initialize ball properties (position, velocity, radius).
- Clear the canvas each frame.
- Update the ball’s position (add velocity).
- Check for collisions with canvas boundaries (reverse velocity if hit).
- Redraw the ball.
Code:
// Ball properties
let x = 100; // X position
let y = 100; // Y position
let vx = 5; // X velocity (pixels per frame)
let vy = 3; // Y velocity
const radius = 30;
function animate() {
// 1. Clear canvas (entire area)
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 2. Update position
x += vx;
y += vy;
// 3. Collision detection with canvas edges
if (x + radius > canvas.width || x - radius < 0) vx = -vx; // Left/right walls
if (y + radius > canvas.height || y - radius < 0) vy = -vy; // Top/bottom walls
// 4. Draw ball
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fillStyle = 'red';
ctx.fill();
// Repeat animation
requestAnimationFrame(animate);
}
// Start the loop
animate();
This creates a smooth, bouncing ball animation. Adjust vx/vy for speed, or add gravity by increasing vy over time.
8. Advanced Techniques
Transformations
Use translate(), rotate(), and scale() to transform the coordinate system, making it easier to draw rotated or scaled objects.
Example: Rotating Square
ctx.save(); // Save current state (before transformation)
ctx.translate(400, 200); // Move origin to (400, 200)
ctx.rotate(Math.PI / 4); // Rotate 45° (π/4 radians) around origin
ctx.fillStyle = 'blue';
ctx.fillRect(-50, -50, 100, 100); // Draw square centered at (400, 200)
ctx.restore(); // Restore original state (undo transformation)
save()/restore()preserve the context state (avoids affecting other drawings).
Shadows
Add shadows to shapes with shadowColor, shadowBlur, shadowOffsetX, and shadowOffsetY:
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.fillStyle = 'yellow';
ctx.fillRect(500, 100, 150, 100); // Shadowed rectangle
Pixel Manipulation
Use getImageData(x, y, width, height) to read pixel data (an array of RGBA values), modify it, and putImageData(data, x, y) to write it back.
Example: Invert Colors
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
data[i] = 255 - data[i]; // Red
data[i + 1] = 255 - data[i + 1]; // Green
data[i + 2] = 255 - data[i + 2]; // Blue
// Alpha (data[i+3]) remains unchanged
}
ctx.putImageData(imageData, 0, 0);
9. Best Practices
Performance
- Minimize canvas size: Larger canvases require more memory and processing.
- Avoid unnecessary redraws: Only redraw changed areas (use
clearRectfor small regions instead of the whole canvas). - Use offscreen canvases: Pre-render static elements on an offscreen canvas and draw them once.
- Simplify paths: Complex paths with many points slow down rendering.
Accessibility
Canvas is a bitmap, so screen readers can’t interpret its content. Always provide fallback content inside the <canvas> tag (e.g., text descriptions or links to alternative content).
Cross-Browser Support
Canvas is supported in all modern browsers, but older browsers (e.g., IE8) lack support. Use feature detection:
if (!canvas.getContext) {
alert('Canvas is not supported in your browser.');
}
10. Conclusion
HTML Canvas is a versatile tool for creating dynamic graphics and animations directly in the browser. From simple shapes to complex games, its 2D API offers endless creative possibilities. By mastering paths, colors, animations, and transformations, you can build interactive experiences that engage users.
The key to mastering Canvas is practice—experiment with different shapes, animations, and techniques. Explore the references below to dive deeper!