HTML 27 💻 canvas element
The <canvas> element is a powerful HTML element used to draw graphics dynamically using JavaScript. It’s ideal for creating animations, games, data visualizations, image editing, and more.
What is the Canvas Element?
The <canvas> element provides a drawing surface that you can control with JavaScript. Unlike SVG, which is declarative, canvas uses imperative programming — you give step-by-step instructions to draw shapes, text, and images.
Key Characteristics:
- Requires JavaScript for drawing
- Immediate mode — draws pixels, not objects
- Great for animations and games
- Resolution-dependent — use
width/heightattributes for sizing - Transparent by default
Basic Syntax:
<canvas id="thecanvas" width="400" height="200"></canvas>
<script>
const cnv = document.getElementById('thecanvas');
const ctx = cnv.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 50, 40);
</script>
Canvas Attributes
| Attribute | Purpose | Example |
|---|---|---|
id | Unique identifier for JavaScript | id="myCanvas" |
width | Width of the drawing area (in pixels) | width="400" |
height | Height of the drawing area (in pixels) | height="200" |
Important: Use the width and height attributes on the <canvas> element itself — not CSS — to set the canvas size. Using CSS will stretch the canvas instead of resizing the drawing surface.
Getting the Canvas Context
To draw on a canvas, you need to get the rendering context:
const canvas = document.getElementById('thecanvas');
const ctx = canvas.getContext('2d'); // For 2D graphics
For 3D graphics, you can use:
const gl = canvas.getContext('webgl'); // For WebGL
Canvas Drawing Basics
Filling a Rectangle:
ctx.fillStyle = 'red';
ctx.fillRect(10, 10, 50, 40);
Stroking a Rectangle:
ctx.strokeStyle = 'blue';
ctx.strokeRect(100, 10, 50, 40);
Clearing a Rectangle:
ctx.clearRect(0, 0, canvas.width, canvas.height);
Complete Example
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas Element</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
max-width: 1200px;
margin: 0 auto;
padding: 20px;
background: #f8f9fa;
line-height: 1.6;
}
h1 {
color: #007bff;
border-bottom: 3px solid #007bff;
padding-bottom: 10px;
}
h2 {
color: #28a745;
margin-top: 30px;
border-left: 4px solid #28a745;
padding-left: 15px;
}
.canvas-container {
background: white;
padding: 25px;
border-radius: 8px;
box-shadow: 0 2px 15px rgba(0,0,0,0.1);
margin: 20px 0;
}
canvas {
border: 2px solid #ddd;
border-radius: 8px;
background: white;
display: block;
max-width: 100%;
}
.example-box {
background: #e9ecef;
padding: 15px;
border-radius: 6px;
margin: 10px 0;
border-left: 4px solid #007bff;
}
.code-block {
background: #1e1e1e;
color: #d4d4d4;
padding: 15px;
border-radius: 8px;
overflow-x: auto;
font-family: 'Courier New', monospace;
font-size: 0.95em;
line-height: 1.8;
margin: 10px 0;
}
.btn-group {
margin: 15px 0;
display: flex;
flex-wrap: wrap;
gap: 10px;
}
button {
background: #007bff;
color: white;
padding: 10px 25px;
border: none;
border-radius: 6px;
font-size: 1em;
cursor: pointer;
transition: background 0.3s;
}
button:hover {
background: #0056b3;
}
button.reset {
background: #6c757d;
}
button.reset:hover {
background: #545b62;
}
button.green {
background: #28a745;
}
button.green:hover {
background: #1e7e34;
}
.reference-table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
.reference-table th,
.reference-table td {
padding: 12px;
border: 1px solid #ddd;
text-align: left;
}
.reference-table th {
background: #007bff;
color: white;
}
.reference-table tr:nth-child(even) {
background: #f8f9fa;
}
code {
background: #f4f4f4;
padding: 2px 6px;
border-radius: 4px;
font-family: 'Courier New', monospace;
font-size: 0.95em;
color: #dc3545;
}
.grid-2 {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
}
</style>
</head>
<body>
<h1>Canvas Element</h1>
<!-- ====== SECTION 1: BASIC CANVAS ====== -->
<h2>1. Basic Canvas</h2>
<div class="canvas-container">
<canvas id="basicCanvas" width="400" height="150"></canvas>
<div class="example-box">
<h4>🔍 Code:</h4>
<div class="code-block">
<span style="color: #569cd6;"><canvas</span> <span style="color: #9cdcfe;">id</span>=<span style="color: #ce9178;">"basicCanvas"</span> <span style="color: #9cdcfe;">width</span>=<span style="color: #ce9178;">"400"</span> <span style="color: #9cdcfe;">height</span>=<span style="color: #ce9178;">"150"</span><span style="color: #569cd6;">></canvas></span>
<span style="color: #6a9955;">// JavaScript</span>
<span style="color: #569cd6;">const</span> canvas = document.<span style="color: #dcdcaa;">getElementById</span>(<span style="color: #ce9178;">'basicCanvas'</span>);
<span style="color: #569cd6;">const</span> ctx = canvas.<span style="color: #dcdcaa;">getContext</span>(<span style="color: #ce9178;">'2d'</span>);
ctx.<span style="color: #dcdcaa;">fillStyle</span> = <span style="color: #ce9178;">'red'</span>;
ctx.<span style="color: #dcdcaa;">fillRect</span>(<span style="color: #b5cea8;">10</span>, <span style="color: #b5cea8;">10</span>, <span style="color: #b5cea8;">50</span>, <span style="color: #b5cea8;">40</span>);
</div>
</div>
</div>
<!-- ====== SECTION 2: DRAWING SHAPES ====== -->
<h2>2. Drawing Shapes</h2>
<div class="canvas-container">
<canvas id="shapesCanvas" width="500" height="200"></canvas>
<div class="example-box">
<h4>🔍 Shapes Drawn:</h4>
<ul>
<li>🔴 Red filled rectangle</li>
<li>🔵 Blue stroked rectangle</li>
<li>🟢 Green filled circle</li>
<li>🟠 Orange stroked circle</li>
<li>🟣 Purple filled triangle (path)</li>
</ul>
</div>
</div>
<!-- ====== SECTION 3: DRAWING PATHS ====== -->
<h2>3. Drawing Paths</h2>
<div class="canvas-container">
<canvas id="pathsCanvas" width="500" height="200"></canvas>
<div class="example-box">
<h4>🔍 Paths Drawn:</h4>
<ul>
<li>🔷 Star shape (filled)</li>
<li>🔶 Triangle (stroked)</li>
<li>💬 Heart shape (filled)</li>
</ul>
</div>
</div>
<!-- ====== SECTION 4: ANIMATION ====== -->
<h2>4. Animation</h2>
<div class="canvas-container">
<canvas id="animationCanvas" width="500" height="250"></canvas>
<div class="btn-group">
<button id="startAnimation">▶ Start Animation</button>
<button id="stopAnimation" class="reset">⏹ Stop</button>
<button id="resetAnimation" class="reset">🔄 Reset</button>
</div>
<div class="example-box">
<h4>🔍 How it works:</h4>
<ul>
<li>A circle moves across the canvas</li>
<li>Uses <code>requestAnimationFrame()</code> for smooth animation</li>
<li>The canvas is cleared and redrawn each frame</li>
</ul>
</div>
</div>
<!-- ====== SECTION 5: DRAWING TEXT ====== -->
<h2>5. Drawing Text</h2>
<div class="canvas-container">
<canvas id="textCanvas" width="500" height="150"></canvas>
<div class="example-box">
<h4>🔍 Text Examples:</h4>
<ul>
<li>📝 Styled text with custom font</li>
<li>🎨 Filled and stroked text</li>
<li>📏 Text alignment (center, right, left)</li>
</ul>
</div>
</div>
<!-- ====== SECTION 6: GRADIENTS ====== -->
<h2>6. Gradients</h2>
<div class="canvas-container">
<canvas id="gradientCanvas" width="500" height="200"></canvas>
<div class="example-box">
<h4>🔍 Gradient Types:</h4>
<ul>
<li>🌈 Linear gradient (blue to purple)</li>
<li>🔵 Radial gradient (center to edge)</li>
<li>🎨 Gradient used on shapes and rectangles</li>
</ul>
</div>
</div>
<!-- ====== SECTION 7: IMAGE ====== -->
<h2>7. Drawing Images</h2>
<div class="canvas-container">
<canvas id="imageCanvas" width="400" height="150"></canvas>
<div class="example-box">
<h4>🔍 Image Drawing:</h4>
<ul>
<li>🖼️ Draws an image onto the canvas</li>
<li>📐 Scales the image to fit</li>
<li>🎨 Images can be manipulated pixel by pixel</li>
</ul>
</div>
</div>
<!-- ====== SECTION 8: REFERENCE TABLE ====== -->
<h2>8. Canvas API Reference</h2>
<h3>Common Methods</h3>
<table class="reference-table">
<thead>
<tr>
<th>Method</th>
<th>Description</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>fillRect(x, y, w, h)</code></td>
<td>Draws a filled rectangle</td>
<td><code>ctx.fillRect(10, 10, 50, 40)</code></td>
</tr>
<tr>
<td><code>strokeRect(x, y, w, h)</code></td>
<td>Draws a stroked rectangle</td>
<td><code>ctx.strokeRect(70, 10, 50, 40)</code></td>
</tr>
<tr>
<td><code>clearRect(x, y, w, h)</code></td>
<td>Clears a rectangle area</td>
<td><code>ctx.clearRect(0, 0, 400, 200)</code></td>
</tr>
<tr>
<td><code>beginPath()</code></td>
<td>Starts a new path</td>
<td><code>ctx.beginPath()</code></td>
</tr>
<tr>
<td><code>arc(x, y, r, s, e)</code></td>
<td>Draws an arc (circle)</td>
<td><code>ctx.arc(100, 100, 40, 0, Math.PI * 2)</code></td>
</tr>
<tr>
<td><code>fill()</code></td>
<td>Fills the current path</td>
<td><code>ctx.fill()</code></td>
</tr>
<tr>
<td><code>stroke()</code></td>
<td>Strokes the current path</td>
<td><code>ctx.stroke()</code></td>
</tr>
</tbody>
</table>
<h3>Common Properties</h3>
<table class="reference-table">
<thead>
<tr>
<th>Property</th>
<th>Description</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>fillStyle</code></td>
<td>Fill color or gradient</td>
<td><code>ctx.fillStyle = 'red'</code></td>
</tr>
<tr>
<td><code>strokeStyle</code></td>
<td>Stroke color or gradient</td>
<td><code>ctx.strokeStyle = 'blue'</code></td>
</tr>
<tr>
<td><code>lineWidth</code></td>
<td>Line thickness</td>
<td><code>ctx.lineWidth = 3</code></td>
</tr>
<tr>
<td><code>font</code></td>
<td>Font for text</td>
<td><code>ctx.font = '20px Arial'</code></td>
</tr>
<tr>
<td><code>textAlign</code></td>
<td>Text alignment</td>
<td><code>ctx.textAlign = 'center'</code></td>
</tr>
</tbody>
</table>
<!-- ====== SECTION 9: BEST PRACTICES ====== -->
<h2>9. Best Practices</h2>
<div style="background: #d4edda; padding: 20px; border-radius: 8px; border-left: 4px solid #28a745;">
<h3 style="margin-top: 0; color: #155724;">✅ Do This:</h3>
<ul>
<li>Set <code>width</code> and <code>height</code> as <strong>HTML attributes</strong>, not CSS</li>
<li>Use <code>requestAnimationFrame()</code> for <strong>smooth animations</strong></li>
<li>Save canvas state with <code>save()</code> and restore with <code>restore()</code></li>
<li>Use <strong>off-screen canvases</strong> for complex pre-rendering</li>
<li>For high-DPI displays, <strong>scale the canvas</strong> using <code>devicePixelRatio</code></li>
<li>Always provide a <strong>fallback message</strong> inside the canvas tag</li>
</ul>
</div>
<div style="background: #f8d7da; padding: 20px; border-radius: 8px; border-left: 4px solid #dc3545; margin-top: 15px;">
<h3 style="margin-top: 0; color: #721c24;">❌ Don't Do This:</h3>
<ul>
<li>Don't use CSS to set canvas <strong>width/height</strong> (use HTML attributes)</li>
<li>Don't forget to <code>beginPath()</code> before drawing a new shape</li>
<li>Don't use canvas for <strong>simple static graphics</strong> (use SVG or CSS)</li>
<li>Don't draw in the canvas <strong>before the page loads</strong></li>
<li>Don't forget to clear the canvas when <strong>animating</strong></li>
</ul>
</div>
</body>
</html>
<script>
// ============================================================
// 1. BASIC CANVAS
// ============================================================
const basicCanvas = document.getElementById('basicCanvas');
const basicCtx = basicCanvas.getContext('2d');
basicCtx.fillStyle = 'red';
basicCtx.fillRect(10, 10, 50, 40);
basicCtx.fillStyle = 'blue';
basicCtx.fillRect(80, 10, 50, 40);
basicCtx.fillStyle = 'green';
basicCtx.fillRect(150, 10, 50, 40);
basicCtx.fillStyle = 'orange';
basicCtx.fillRect(220, 10, 50, 40);
basicCtx.fillStyle = 'purple';
basicCtx.fillRect(290, 10, 50, 40);
// ============================================================
// 2. DRAWING SHAPES
// ============================================================
const shapesCanvas = document.getElementById('shapesCanvas');
const shapesCtx = shapesCanvas.getContext('2d');
// Filled rectangle
shapesCtx.fillStyle = 'red';
shapesCtx.fillRect(10, 20, 60, 40);
// Stroked rectangle
shapesCtx.strokeStyle = 'blue';
shapesCtx.lineWidth = 3;
shapesCtx.strokeRect(90, 20, 60, 40);
// Filled circle
shapesCtx.beginPath();
shapesCtx.fillStyle = 'green';
shapesCtx.arc(190, 50, 30, 0, Math.PI * 2);
shapesCtx.fill();
// Stroked circle
shapesCtx.beginPath();
shapesCtx.strokeStyle = 'orange';
shapesCtx.lineWidth = 4;
shapesCtx.arc(270, 50, 30, 0, Math.PI * 2);
shapesCtx.stroke();
// Filled triangle (path)
shapesCtx.beginPath();
shapesCtx.fillStyle = 'purple';
shapesCtx.moveTo(360, 20);
shapesCtx.lineTo(330, 70);
shapesCtx.lineTo(390, 70);
shapesCtx.closePath();
shapesCtx.fill();
// Stroked triangle
shapesCtx.beginPath();
shapesCtx.strokeStyle = 'magenta';
shapesCtx.lineWidth = 3;
shapesCtx.moveTo(440, 20);
shapesCtx.lineTo(410, 70);
shapesCtx.lineTo(470, 70);
shapesCtx.closePath();
shapesCtx.stroke();
// ============================================================
// 3. DRAWING PATHS
// ============================================================
const pathsCanvas = document.getElementById('pathsCanvas');
const pathsCtx = pathsCanvas.getContext('2d');
// Star
pathsCtx.beginPath();
const cx = 80, cy = 80;
const outerR = 60, innerR = 25;
const points = 5;
for (let i = 0; i < points * 2; i++) {
const radius = i % 2 === 0 ? outerR : innerR;
const angle = (i / (points * 2)) * Math.PI * 2 - Math.PI / 2;
const x = cx + radius * Math.cos(angle);
const y = cy + radius * Math.sin(angle);
if (i === 0) pathsCtx.moveTo(x, y);
else pathsCtx.lineTo(x, y);
}
pathsCtx.closePath();
pathsCtx.fillStyle = '#ffc107';
pathsCtx.strokeStyle = '#007bff';
pathsCtx.lineWidth = 3;
pathsCtx.fill();
pathsCtx.stroke();
// Triangle
pathsCtx.beginPath();
pathsCtx.moveTo(220, 20);
pathsCtx.lineTo(180, 80);
pathsCtx.lineTo(260, 80);
pathsCtx.closePath();
pathsCtx.strokeStyle = '#dc3545';
pathsCtx.lineWidth = 4;
pathsCtx.stroke();
// Heart
pathsCtx.beginPath();
pathsCtx.moveTo(360, 40);
pathsCtx.bezierCurveTo(330, 10, 290, 30, 360, 70);
pathsCtx.moveTo(360, 40);
pathsCtx.bezierCurveTo(390, 10, 430, 30, 360, 70);
pathsCtx.fillStyle = '#dc3545';
pathsCtx.fill();
// ============================================================
// 4. ANIMATION
// ============================================================
const animCanvas = document.getElementById('animationCanvas');
const animCtx = animCanvas.getContext('2d');
let animX = 50;
let animY = 100;
let animDx = 2;
let animId = null;
function drawAnimation() {
// Clear canvas
animCtx.clearRect(0, 0, animCanvas.width, animCanvas.height);
// Draw background
animCtx.fillStyle = '#f0f0f0';
animCtx.fillRect(0, 0, animCanvas.width, animCanvas.height);
// Draw circle
const gradient = animCtx.createRadialGradient(animX, animY, 10, animX, animY, 40);
gradient.addColorStop(0, '#ff6b6b');
gradient.addColorStop(1, '#c92a2a');
animCtx.beginPath();
animCtx.arc(animX, animY, 35, 0, Math.PI * 2);
animCtx.fillStyle = gradient;
animCtx.fill();
animCtx.strokeStyle = '#333';
animCtx.lineWidth = 2;
animCtx.stroke();
// Update position
animX += animDx;
if (animX > animCanvas.width - 35 || animX < 35) {
animDx = -animDx;
}
animId = requestAnimationFrame(drawAnimation);
}
let animationRunning = false;
document.getElementById('startAnimation').addEventListener('click', function() {
if (!animationRunning) {
animationRunning = true;
drawAnimation();
}
});
document.getElementById('stopAnimation').addEventListener('click', function() {
if (animationRunning) {
animationRunning = false;
cancelAnimationFrame(animId);
}
});
document.getElementById('resetAnimation').addEventListener('click', function() {
if (animationRunning) {
animationRunning = false;
cancelAnimationFrame(animId);
}
animX = 50;
animId = null;
animCtx.clearRect(0, 0, animCanvas.width, animCanvas.height);
animCtx.fillStyle = '#f0f0f0';
animCtx.fillRect(0, 0, animCanvas.width, animCanvas.height);
animCtx.beginPath();
animCtx.arc(animX, animY, 35, 0, Math.PI * 2);
animCtx.fillStyle = '#ff6b6b';
animCtx.fill();
animCtx.strokeStyle = '#333';
animCtx.lineWidth = 2;
animCtx.stroke();
});
// Initial draw
animCtx.fillStyle = '#f0f0f0';
animCtx.fillRect(0, 0, animCanvas.width, animCanvas.height);
animCtx.beginPath();
animCtx.arc(animX, animY, 35, 0, Math.PI * 2);
animCtx.fillStyle = '#ff6b6b';
animCtx.fill();
animCtx.strokeStyle = '#333';
animCtx.lineWidth = 2;
animCtx.stroke();
// ============================================================
// 5. DRAWING TEXT
// ============================================================
const textCanvas = document.getElementById('textCanvas');
const textCtx = textCanvas.getContext('2d');
// Filled text
textCtx.font = 'bold 24px Arial';
textCtx.fillStyle = '#007bff';
textCtx.fillText('Hello, Canvas!', 20, 50);
// Stroked text
textCtx.font = '24px Arial';
textCtx.strokeStyle = '#dc3545';
textCtx.lineWidth = 1;
textCtx.strokeText('Hello, Canvas!', 20, 90);
// Centered text
textCtx.font = '18px Arial';
textCtx.textAlign = 'center';
textCtx.fillStyle = '#28a745';
textCtx.fillText('Centered Text', 350, 50);
// Right-aligned text
textCtx.textAlign = 'right';
textCtx.fillStyle = '#6c5ce7';
textCtx.fillText('Right Aligned', 480, 90);
// Shadow text
textCtx.shadowColor = 'rgba(0,0,0,0.3)';
textCtx.shadowBlur = 5;
textCtx.shadowOffsetX = 3;
textCtx.shadowOffsetY = 3;
textCtx.font = 'bold 20px Arial';
textCtx.fillStyle = '#ffc107';
textCtx.fillText('Shadow Text', 20, 130);
textCtx.shadowColor = 'transparent';
// ============================================================
// 6. GRADIENTS
// ============================================================
const gradCanvas = document.getElementById('gradientCanvas');
const gradCtx = gradCanvas.getContext('2d');
// Linear gradient
const linearGrad = gradCtx.createLinearGradient(0, 0, 200, 0);
linearGrad.addColorStop(0, '#007bff');
linearGrad.addColorStop(0.5, '#6c5ce7');
linearGrad.addColorStop(1, '#dc3545');
gradCtx.fillStyle = linearGrad;
gradCtx.fillRect(10, 20, 180, 60);
// Horizontal text with gradient
gradCtx.font = 'bold 24px Arial';
gradCtx.fillStyle = linearGrad;
gradCtx.fillText('Gradient Text', 210, 65);
// Radial gradient
const radialGrad = gradCtx.createRadialGradient(400, 50, 10, 400, 50, 50);
radialGrad.addColorStop(0, '#ffc107');
radialGrad.addColorStop(1, '#dc3545');
gradCtx.fillStyle = radialGrad;
gradCtx.beginPath();
gradCtx.arc(400, 50, 45, 0, Math.PI * 2);
gradCtx.fill();
// Rectangle with gradient
const rectGrad = gradCtx.createLinearGradient(10, 100, 200, 150);
rectGrad.addColorStop(0, '#28a745');
rectGrad.addColorStop(0.5, '#ffc107');
rectGrad.addColorStop(1, '#dc3545');
gradCtx.fillStyle = rectGrad;
gradCtx.fillRect(10, 100, 200, 50);
// ============================================================
// 7. IMAGE
// ============================================================
const imgCanvas = document.getElementById('imageCanvas');
const imgCtx = imgCanvas.getContext('2d');
// Create an image
const img = new Image();
img.src = 'https://via.placeholder.com/200x100/007bff/ffffff?text=Canvas+Image';
img.onload = function() {
imgCtx.drawImage(img, 10, 20, 180, 80);
// Add text overlay
imgCtx.font = 'bold 14px Arial';
imgCtx.fillStyle = 'white';
imgCtx.textAlign = 'center';
imgCtx.fillText('Image on Canvas', 100, 70);
};
</script>
Canvas vs SVG Comparison
| Feature | Canvas | SVG |
|---|---|---|
| Rendering | Immediate (pixel-based) | Retained (DOM-based) |
| Performance | Better for complex animations | Better for static graphics |
| Scalability | Pixelated when scaled | Scalable without quality loss |
| Interactivity | Requires JavaScript | Supports CSS and JS events |
| Accessibility | Poor (no semantic content) | Good (accessible DOM) |
| Best For | Games, animations, pixel effects | Icons, logos, data visualizations |
Common Canvas Use Cases
| Use Case | Description |
|---|---|
| Games | Real-time graphics rendering |
| Animations | Smooth, frame-based animations |
| Data Visualization | Charts, graphs, diagrams |
| Image Editing | Filters, cropping, manipulation |
| Pixel Art | Drawing at the pixel level |
| Interactive Graphics | Drawing apps, whiteboards |
Pro Tip: The canvas element is perfect for dynamic, interactive, and animated graphics. Use requestAnimationFrame() for smooth animations, and always clear the canvas before redrawing each frame. For static graphics that need to be scalable, prefer SVG instead!
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!