HTML5 Canvas
Canvas is an HTML5 element for drawing graphics dynamically using JavaScript.
Canvas Basics
Creating a Canvas
<canvas id="myCanvas" width="400" height="300">
Your browser does not support canvas.
</canvas>
Drawing with JavaScript
<canvas id="myCanvas" width="400" height="300"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// Draw a rectangle
ctx.fillStyle = '#3498db';
ctx.fillRect(10, 10, 100, 50);
// Draw a circle
ctx.beginPath();
ctx.arc(200, 150, 50, 0, Math.PI * 2);
ctx.fillStyle = '#e74c3c';
ctx.fill();
// Draw a line
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(400, 300);
ctx.strokeStyle = '#2ecc71';
ctx.lineWidth = 2;
ctx.stroke();
</script>
Canvas Features
Text
<canvas id="textCanvas" width="400" height="100"></canvas>
<script>
const canvas = document.getElementById('textCanvas');
const ctx = canvas.getContext('2d');
ctx.font = 'bold 24px Arial';
ctx.fillStyle = '#333';
ctx.fillText('Hello, Canvas!', 10, 50);
ctx.strokeText('Stroke Text', 10, 80);
</script>
Gradients
<canvas id="gradientCanvas" width="400" height="200"></canvas>
<script>
const canvas = document.getElementById('gradientCanvas');
const ctx = canvas.getContext('2d');
// Linear gradient
const linearGradient = ctx.createLinearGradient(0, 0, 400, 0);
linearGradient.addColorStop(0, '#3498db');
linearGradient.addColorStop(1, '#e74c3c');
ctx.fillStyle = linearGradient;
ctx.fillRect(0, 0, 400, 100);
// Radial gradient
const radialGradient = ctx.createRadialGradient(200, 150, 10, 200, 150, 100);
radialGradient.addColorStop(0, '#2ecc71');
radialGradient.addColorStop(1, '#9b59b6');
ctx.fillStyle = radialGradient;
ctx.beginPath();
ctx.arc(200, 150, 80, 0, Math.PI * 2);
ctx.fill();
</script>
Shadows
<canvas id="shadowCanvas" width="400" height="200"></canvas>
<script>
const canvas = document.getElementById('shadowCanvas');
const ctx = canvas.getContext('2d');
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.fillStyle = '#3498db';
ctx.fillRect(50, 50, 150, 80);
</script>
Case Study: Campus System Chart Dashboard
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Campus Chart Dashboard</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', sans-serif;
background: #f0f2f5;
padding: 2rem;
}
.dashboard {
max-width: 1200px;
margin: 0 auto;
}
h1 {
color: #1e3a5f;
margin-bottom: 2rem;
}
.charts {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 2rem;
}
.chart-card {
background: white;
padding: 1.5rem;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.chart-card h2 {
color: #333;
font-size: 1.2rem;
margin-bottom: 1rem;
}
canvas {
width: 100%;
height: auto;
}
</style>
</head>
<body>
<div class="dashboard">
<h1>Campus Statistics Dashboard</h1>
<div class="charts">
<div class="chart-card">
<h2>Number of Students per Department</h2>
<canvas id="barChart" width="500" height="300"></canvas>
</div>
<div class="chart-card">
<h2>Major Distribution</h2>
<canvas id="pieChart" width="500" height="300"></canvas>
</div>
</div>
</div>
<script>
// Bar Chart - Students per Faculty
const barCanvas = document.getElementById('barChart');
const barCtx = barCanvas.getContext('2d');
const data = [
{ label: 'Teknik', value: 1500, color: '#3498db' },
{ label: 'Economics', value: 1200, color: '#e74c3c' },
{ label: 'Hukum', value: 800, color: '#2ecc71' },
{ label: 'Kedokteran', value: 600, color: '#9b59b6' },
{ label: 'Sastra', value: 400, color: '#f39c12' }
];
const maxValue = Math.max(...data.map(d => d.value));
const barWidth = 60;
const spacing = 30;
const startX = 50;
const chartHeight = 200;
// Draw the axis
barCtx.strokeStyle = '#333';
barCtx.lineWidth = 2;
barCtx.beginPath();
barCtx.moveTo(startX, 250);
barCtx.lineTo(startX + data.length * (barWidth + spacing), 250);
barCtx.stroke();
// Draw the bars
data.forEach((item, index) => {
const barHeight = (item.value / maxValue) * chartHeight;
const x = startX + index * (barWidth + spacing);
const y = 250 - barHeight;
barCtx.fillStyle = item.color;
barCtx.fillRect(x, y, barWidth, barHeight);
// Label
barCtx.fillStyle = '#333';
barCtx.font = '12px Arial';
barCtx.textAlign = 'center';
barCtx.fillText(item.label, x + barWidth / 2, 270);
barCtx.fillText(item.value, x + barWidth / 2, y - 10);
});
// Pie Chart - Study Program Distribution
const pieCanvas = document.getElementById('pieChart');
const pieCtx = pieCanvas.getContext('2d');
const pieData = [
{ label: 'Computer Science', value: 30, color: '#3498db' },
{ label: 'Management', value: 25, color: '#e74c3c' },
{ label: 'Hukum', value: 20, color: '#2ecc71' },
{ label: 'Kedokteran', value: 15, color: '#9b59b6' },
{ label: 'Other', value: 10, color: '#f39c12' }
];
const total = pieData.reduce((sum, item) => sum + item.value, 0);
let currentAngle = -Math.PI / 2;
pieData.forEach((item) => {
const sliceAngle = (item.value / total) * Math.PI * 2;
pieCtx.beginPath();
pieCtx.moveTo(200, 150);
pieCtx.arc(200, 150, 120, currentAngle, currentAngle + sliceAngle);
pieCtx.fillStyle = item.color;
pieCtx.fill();
// Label
const labelAngle = currentAngle + sliceAngle / 2;
const labelX = 200 + Math.cos(labelAngle) * 80;
const labelY = 150 + Math.sin(labelAngle) * 80;
pieCtx.fillStyle = 'white';
pieCtx.font = 'bold 12px Arial';
pieCtx.textAlign = 'center';
pieCtx.fillText(item.value + '%', labelX, labelY);
currentAngle += sliceAngle;
});
// Legend
pieData.forEach((item, index) => {
pieCtx.fillStyle = item.color;
pieCtx.fillRect(350, 50 + index * 25, 15, 15);
pieCtx.fillStyle = '#333';
pieCtx.font = '12px Arial';
pieCtx.textAlign = 'left';
pieCtx.fillText(item.label, 370, 62 + index * 25);
});
</script>
</body>
</html>
Everyday Case Study
Case: A developer needs to create a simple chart for a dashboard.
<canvas id="simpleChart" width="300" height="200"></canvas>
<script>
const canvas = document.getElementById('simpleChart');
const ctx = canvas.getContext('2d');
// Sales data
const sales = [80, 120, 95, 150, 110, 140];
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'];
// Draw the line
ctx.beginPath();
ctx.moveTo(30, 180);
sales.forEach((value, index) => {
const x = 30 + index * 50;
const y = 180 - (value / 150) * 150;
ctx.lineTo(x, y);
});
ctx.strokeStyle = '#3498db';
ctx.lineWidth = 2;
ctx.stroke();
// Data points
sales.forEach((value, index) => {
const x = 30 + index * 50;
const y = 180 - (value / 150) * 150;
ctx.beginPath();
ctx.arc(x, y, 4, 0, Math.PI * 2);
ctx.fillStyle = '#3498db';
ctx.fill();
// Label
ctx.fillStyle = '#333';
ctx.font = '10px Arial';
ctx.textAlign = 'center';
ctx.fillText(months[index], x, 195);
});
</script>
Best Practices
- Use requestAnimationFrame: For smooth animations
- Save state: Use save() and restore()
- Optimize redraws: Don't redraw all elements
- Responsive: Size the canvas to fit the screen
- Fallback: Provide a message for older browsers
Summary
Canvas allows dynamic 2D drawing with JavaScript. It's well suited for data visualization, games, and visual effects.