Skillversitas

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

  1. Use requestAnimationFrame: For smooth animations
  2. Save state: Use save() and restore()
  3. Optimize redraws: Don't redraw all elements
  4. Responsive: Size the canvas to fit the screen
  5. 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.