SVG menyimpan gambar sebagai objek yang bertahan di dalam DOM. Pendekatan kedua bekerja sebaliknya: elemen canvas adalah bidang piksel kosong yang isinya digambar JavaScript melalui perintah program. Hasilnya gambar selesai yang tidak mengingat bentuk asalnya. Chapter ini membahas cara kerja canvas, mode menggambarnya, use case, aksesibilitas, dan contoh lengkapnya.
Kanvas Piksel dan Konteks Gambar #
Elemen canvas sendiri tidak menggambar apa pun; tanpa JavaScript, bidangnya kosong. Pekerjaan menggambar dikerjakan objek konteks dari method getContext("2d"):
const kanvas = document.querySelector("#papan");
const konteks = kanvas.getContext("2d");
konteks.fillRect(10, 10, 80, 40);Output yang Dihasilkan:
Satu kotak biru gelap 80x40 tampil di sudut kiri atas kanvas.Mari kita telaah tiga baris di atas:
- Baris 1: memilih elemen
canvasdi dalam DOM; ukuran bidangnya ditetapkan atributwidth/height. - Baris 2:
getContext("2d")mengembalikan objekCanvasRenderingContext2D, kumpulan method menggambar dua dimensi; semua perintah melewatinya. - Baris 3:
fillRect(x, y, lebar, tinggi)melukis kotak terisi pada piksel kanvas.
Setelah fillRect selesai, tidak ada “objek kotak” yang bisa dipilih di DOM; yang tersisa hanyalah piksel.
Immediate Mode versus Retained Mode #
Perbedaan itu bernama: canvas bekerja dalam immediate mode, SVG dalam retained mode. Pada immediate mode, perintah dieksekusi sekali dan browser hanya menyimpan hasil akhirnya. Pada retained mode, deskripsi setiap bentuk disimpan dan dirender ulang kapan pun sesuatu berubah. Pemetaannya:
| Aspek | Canvas (immediate) | SVG (retained) |
|---|---|---|
| Yang disimpan browser | Piksel hasil gambar | Objek bentuk di DOM |
| Mengubah satu bentuk | Menggambar ulang seluruh kanvas | Mengubah atribut, browser merender ulang |
| Mengakses satu bentuk | Tidak ada; piksel bukan objek | circle dan path bisa dipilih selector |
| Arah penggambar | JavaScript yang memanggil perintah | Markup yang dideklarasikan |
Konsekuensinya: animasi canvas mengosongkan kanvas lalu menggambar ulang tiap frame via requestAnimationFrame; animasi SVG cukup mengubah satu atribut.
Kapan Canvas Tepat Dipakai #
Kekuatan canvas ada pada volume dan kontrol piksel:
- Game 2D dan animasi intensif dengan gambar ulang layar tiap frame;
- Visualisasi dengan puluhan ribu titik data yang berat bila tiap titik menjadi elemen DOM;
- Pengolahan gambar di tingkat piksel: filter dan manipulasi warna;
- Efek visual kustom seperti partikel dan noise.
Sebaliknya, canvas kurang tepat bila konten butuh teks yang dapat diseleksi, indeks mesin pencari, atau aksesibilitas; diagram dan ikon lebih baik diserahkan ke SVG.
Kanvas dan Aksesibilitas #
Elemen canvas tidak aksesibel secara bawaan: assistive technology tidak dapat membaca piksel, sehingga isi gambar perlu pengganti teks yang disiapkan penulis. Pertolongan pertama, fallback content: teks atau elemen yang ditulis di antara tag pembuka dan penutup canvas, yang MDN catat dirender pada browser lama tanpa dukungan canvas maupun saat JavaScript mati; pertolongan kedua, role="img" dengan aria-label memberi nama bagi pembaca layar.
Contoh Lengkap dalam Satu File #
File berikut menggambar pemandangan sederhana untuk halaman warung Siti: langit, tanah, matahari, dan teks; markup HTML memuat fallback content, penggambaran berada di file JavaScript yang dimuat dengan defer:
<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pemandangan Pertama di Canvas</title>
<style>
canvas { border: 1px solid #6b7280; }
</style>
</head>
<body>
<h1>Warung Siti di Kanvas</h1>
<p>Gambar di bawah digambar sepenuhnya oleh JavaScript.</p>
<canvas id="papan" width="240" height="160">
Pemandangan langit biru, tanah hijau, dan matahari kuning untuk halaman warung Siti.
</canvas>
<script src="gambar-kanvas.js" defer></script>
</body>
</html>function gambarPemandangan() {
const kanvas = document.querySelector("#papan");
const konteks = kanvas.getContext("2d");
konteks.fillStyle = "#dbeafe";
konteks.fillRect(0, 0, 240, 120);
konteks.fillStyle = "#1a6b54";
konteks.fillRect(0, 120, 240, 40);
konteks.beginPath();
konteks.arc(190, 40, 24, 0, Math.PI * 2);
konteks.fillStyle = "#fbbf24";
konteks.fill();
konteks.fillStyle = "#1f2937";
konteks.font = "bold 14px sans-serif";
konteks.fillText("Warung Siti", 16, 32);
}
gambarPemandangan();Output yang Dihasilkan:
Jendela browser menampilkan:
- Judul "Warung Siti di Kanvas" dan satu paragraf pengantar
- Bidang 240x160 berbingkai abu berisi:
- Langit biru muda menutup dua pertiga atas
- Tanah hijau menutup bagian bawah
- Matahari kuning bulat di kanan atas
- Teks "Warung Siti" gelap di kiri atasMari kita bedah baris-baris pentingnya:
- Baris 14-16 pada HTML (elemen
canvas):idmenandai kanvas bagi JavaScript,widthdanheightmenetapkan resolusi 240x160; teks di dalamnya menjadi fallback bila JavaScript mati. - Baris 17 pada HTML (
script defer): file gambar-kanvas.js dimuat dengandefersehingga dieksekusi setelah DOM siap, saat elemencanvastelah ada. - Baris 2-3 pada JS (
querySelectordangetContext): kanvas dipilih dari DOM, lalu konteks 2D diambil; keduanya disimpan di konstanta lokal. - Baris 5-8 pada JS (dua
fillRect): langit dan tanah dilukis sebagai dua kotak terisi;fillStylediganti sebelum tiap lukisan. - Baris 9-12 pada JS (
beginPathhinggafill): matahari dilukis sebagaiarclingkaran penuh;beginPathmembuka jalur,arcmenetapkan lingkaran,fillmengisinya. - Baris 13-15 pada JS (
fontdanfillText): teks nama warung ditulis langsung ke piksel kanvas; teks ini bukan elemen DOM, tidak bisa diseleksi pengunjung. - Baris 18 pada JS (
gambarPemandangan()): pemanggilan fungsi sekali saja; tanpa loop, kanvas menampilkan satu frame statis.
Kanvas di atas menampilkan gambar selesai yang tidak menyimpan jejak bentuknya. Kapan kita memakai SVG, kapan canvas? Chapter penutup section ini menyusun perbandingannya.
Referensi resmi untuk pendalaman:
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
contoh-canvas.html
Unduh berkas<!doctype html>
<html lang="id">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pemandangan Pertama di Canvas</title>
<style>
canvas { border: 1px solid #6b7280; }
</style>
</head>
<body>
<h1>Warung Siti di Kanvas</h1>
<p>Gambar di bawah digambar sepenuhnya oleh JavaScript.</p>
<canvas id="papan" width="240" height="160">
Pemandangan langit biru, tanah hijau, dan matahari kuning untuk halaman warung Siti.
</canvas>
<script src="gambar-kanvas.js" defer></script>
</body>
</html>
gambar-kanvas.js
Unduh berkasfunction gambarPemandangan() {
const kanvas = document.querySelector("#papan");
const konteks = kanvas.getContext("2d");
konteks.fillStyle = "#dbeafe";
konteks.fillRect(0, 0, 240, 120);
konteks.fillStyle = "#1a6b54";
konteks.fillRect(0, 120, 240, 40);
konteks.beginPath();
konteks.arc(190, 40, 24, 0, Math.PI * 2);
konteks.fillStyle = "#fbbf24";
konteks.fill();
konteks.fillStyle = "#1f2937";
konteks.font = "bold 14px sans-serif";
konteks.fillText("Warung Siti", 16, 32);
}
gambarPemandangan();