- HTML-in-Canvas adalah proyek WICG yang mengusulkan API standar baru yang memungkinkan menggambar langsung elemen/konten HTML ke dalam elemen
<canvas>di web - Muncul untuk mengatasi tata letak teks kompleks, aksesibilitas, internasionalisasi, serta masalah kualitas/kinerja, dan memungkinkan penggunaan styling HTML secara langsung pada berbagai kasus penggunaan Canvas seperti chart, UI, dan menu game
- Melalui metode baru seperti
drawElement,texElement2D,setHitTestRegions, elemen HTML dapat dirender dan ditextur langsung ke konteks Canvas 2D atau WebGL - Mencakup kebutuhan nyata pengembang web app seperti area interaksi, perbaikan aksesibilitas, UI 2D dalam adegan 3D, serta tata letak berbasis CSS/HTML
- Saat ini dapat diaktifkan sebagai flag eksperimental di Chrome Canary (mulai 138.0.7175.0), dan umpan balik utama/ laporan bug sangat disambut
Ikhtisar dan signifikansi
- Mengusulkan API baru untuk menggambar elemen HTML langsung ke
<canvas> - Sebelumnya tidak ada cara yang mudah untuk merender tata letak kompleks, teks, dan konten berbasis HTML ke
<canvas>, sehingga ada keterbatasan dari sisi aksesibilitas, internasionalisasi, performa, dan kualitas - HTML-in-Canvas hadir sebagai pelengkap ini, mendukung rendering HTML di Canvas 2D dan WebGL, dan meningkatkan kelayakan penggunaan pada alat chart, kotak rich text, UI game, dan area lain
Kasus penggunaan
- Representasi konten teks dan tata letak berstyling di dalam canvas
- Contoh: legenda chart, sumbu, kotak rich editor, menu dalam game, dan lain-lain
- Peningkatan aksesibilitas
- Mengatasi ketidaksesuaian antara konten alternatif canvas yang lama dan isi yang benar-benar dirender
- Sinkronisasi informasi aksesibilitas dimungkinkan melalui API baru
- Kombinasi HTML dan shader WebGL
- Menjawab kebutuhan integrasi HTML dan shader WebGL standar, melampaui efek filter CSS
- Rendering HTML dalam konteks 3D
- Memungkinkan penyisipan konten 2D kaya di area 3D game/situs
API yang diusulkan dan fitur utama
- Mengaktifkan tata letak elemen HTML anak canvas melalui atribut
<canvas layoutsubtree>(secara default hanya dirender secara visual, tidak diekspos ke algoritme penjelajahan halaman UA) - CanvasRenderingContext2D.drawElement(element, x, y, options)
- Merender elemen HTML anak canvas pada posisi yang ditentukan
- Mengontrol pencegahan kebocoran data pribadi lewat
options.allowReadback(kebijakan tainting akan diterapkan di kemudian hari) - Dapat di-resize ke ukuran yang diinginkan lewat parameter dwidth/dheight
- WebGLRenderingContext.texElement2D(...)
- Menggambar elemen HTML tertentu langsung sebagai tekstur WebGL untuk dipakai di adegan 3D
- setHitTestRegions
- Mengaitkan elemen yang digambar di area tertentu dengan event canvas (hit test), lalu mengarahkan ulang event mouse/sentuh secara otomatis
- fireOnEveryPaint option (ResizeObserver)
- Mendeteksi otomatis timing rerender saat perubahan/penataan ulang HTML agar memicu penggambaran ulang canvas
Perilaku dan keterbatasan
- Saat memanggil drawElement, matriks transformasi canvas (CTM) diterapkan, kliping gambar hanya di dalam border box elemen
- Gambar yang dirender di canvas bersifat statis (jika elemen berubah setelah render, drawElement perlu dipanggil lagi)
- Tidak didukung untuk canvas offscreen atau canvas yang tidak ada di DOM (batasan teknis)
- Elemen interaktif (tombol, form, dll.) dapat digambar, tetapi tidak otomatis interaktif
- Iframe lintas-origin, SVG foreignObject, dan sejenisnya belum didukung
- Isu aksesibilitas serta keamanan/privasi (PII) masih terus didiskusikan
Contoh demo
- Contoh complex-text: menggambar langsung kompleksitas seperti teks dan box bergaya HTML di atas canvas menggunakan drawElement
- Contoh webGL: membuat konten HTML menjadi tekstur WebGL dengan texElement2D lalu memetakan ke kubus 3D
- Contoh text-input: menandai area interaktif seperti form input menggunakan setHitTestRegions, fireOnEveryPaint
Uji coba untuk pengembang dan perhatian
- Aktifkan dengan flag
--enable-blink-features=CanvasDrawElementdi Chrome Canary - Karena isi canvas tidak ter-taint, wajib waspada terhadap potensi kebocoran data pribadi
- API dan perilaku terus berubah, dan kasus uji HTML skala besar masih terbatas
- Feedback dipersilakan: disarankan melaporkan isu kompatibilitas, kegagalan render, masalah aksesibilitas, dan lain-lain lewat GitHub Issue
Nilai guna dan prospek
- Pada chart, visualisasi data, UI di dalam canvas, serta HUD/menu dalam game 3D dan area lain, potensi peningkatan ekspresivitas dan produktivitas web cukup besar
- Konversi HTML→Canvas yang sebelumnya rumit (styling, tata letak, dukungan multibahasa, aksesibilitas) dapat diproses langsung melalui API standar
- Diharapkan menjadi teknologi kuat bagi pengembang grafis, game, dan aplikasi berbasis web
1 komentar
Komentar Hacker News
Banyak kekhawatiran terkait aksesibilitas dan penyalahgunaan, tapi kita juga perlu melihat sisi lain dari diskusi ini Aku baru-baru ini lihat thread menarik di Twitter yang bilang banyak hal baik di web tidak terjadi karena rendering font dan metrik tidak bisa diakses dari JS Ada beragam tanggapan, termasuk poin bahwa web adalah platform yang dirancang untuk menampilkan teks tetapi tak punya fitur untuk menangani teks secara detail, plus rasa keprihatinan karena pengukuran teks di tldraw harus dipaksakan Sebagai platform pengembangan aplikasi, web harus memudahkan orang untuk membuat sesuatu dengan mudah dan kuat, itu akan menguntungkan semua orang Menurutku, API web perlu turun ke level yang lebih rendah; akan sangat bagus kalau ada API metrik font/teks khusus untuk canvas Tapi mesin layout teks web sangat performant, jadi kalau fitur seperti ini juga bisa dipakai di dalam canvas, tentu bisa memunculkan fitur yang sangat bagus Contoh kasus yang aku pikirkan selama beberapa tahun adalah ‘rich text editing dengan pagination’; karena contenteditable saja tidak bisa membuat implementasi setingkat produk, Google Docs akhirnya membuat mesin layout sendiri Kalau usulan ini diterapkan, kita bisa mengambil yang bagus dari contenteditable sekaligus kontrol atas layout halaman/print Aku berharap fitur ini diterapkan di browser
“Web tidak bisa melakukan banyak hal hebat karena font rendering dan akses metrik tidak tersedia di JS” adalah klaim yang aku ragukan Aku ingin tahu apa saja contoh inovasi paling nyata Saat ini JavaScript sudah menyediakan cukup banyak informasi font dan metrik, dan sebagian besar kebutuhan bisa diatasi tanpa menimbulkan hambatan performa besar Di samping itu, fitur HTML-in-Canvas juga tidak membawa perubahan mendasar di area itu
Aku juga sedang memakai Harfbuzz dan mesin layout sendiri berbasis WASM di Nutrient Demo: https://document-authoring-demo.nutrient.io/ Kalau API seperti ini resmi disediakan platform, pengembangan akan jauh lebih mudah Dengan WASM, ini bukan jalan buntu sama sekali Aku dengar dia sedang mengerjakan sinkronisasi di ElectricSQL, jadi sampaikan salamku juga ke Oleksii
Terhadap pernyataan “aku berharap fitur ini diterapkan di browser”, aku tidak mengerti mengapa kita ingin memperluas layout/UI engine paling tidak efisien di dunia ke dalam canvas Ini hanya akan mengunci masalah keterbatasan akses API saat ini Figma menyiasatinya dengan membuat browser lain di dalam browser (lihat: https://www.figma.com/blog/building-a-professional-design-tool-on-the-web/) Kalau contenteditable tidak cukup untuk implementasi kelas produk hingga Google Docs membuat mesin sendiri, maka usulan baru ini memang sulit memberikan dampak nyata untuk layout rich text
Aku pikir fitur ini sangat berguna, tapi strukturnya—HTML di dalam Canvas di dalam HTML—terasa aneh dan tidak pas Menurutku, canvas perlu menjadi format utama yang independen di browser supaya bisa diperlakukan dengan baik Maka memasukkan Canvas ke halaman berbasis HTML, atau sebaliknya menempatkan elemen HTML di dalam platform yang berpusat pada Canvas, akan terasa natural Tentu saja, itu hanya pendapatku
Aku tidak melihatnya aneh dari apa yang kamu bilang Sebagai catatan, HTML sudah bisa dimasukkan ke dalam SVG, lalu kembali lagi ke HTML Kalau canvas adalah elemen tertinggi di halaman, lalu lokasi menyimpan title halaman di mana? Akhirnya harus memakai tag , misalnya
Secara praktis, kalau konten bisa dimasukkan langsung ke dalam tag canvas, ini bisa jadi solusi sederhana
Situs berbasis canvas tetap merepotkan Seluruh layanan sistem (autocompletion, aksesibilitas, dan lain-lain) tak bisa dipakai, dan isu privasi juga muncul Contohnya, sulit menggunakan fitur koreksi ejaan dari sistem, dan aksesibilitas sistem pun tak tersedia sehingga tiap aplikasi harus membuat implementasi aksesibilitas UI yang berbeda total
Struktur yang kau usulkan itu seperti menemukan Flash lagi Cuma, memasukkan Flash ke web dulu juga butuh usaha besar
Ada kalanya kita mau menaruh canvas di halaman HTML lalu memberi layout dan styling pada teks di dalamnya Mengubah cara layout seluruh halaman karena itu adalah pekerjaan yang terlalu rumit
Ada penolakan terhadap akses DOM oleh WASM sebelumnya Jadi menurutku, perkembangan ke arah ini memang tak terelakkan
Kita sekarang sudah sampai fase di mana seluruh browser dikompilasi ke WASM, lalu browser itu dijalankan di dalam elemen canvas browser utama
Bisa sampai menjalankan OS lengkap termasuk IE di web juga (contoh: https://copy.sh/v86/?profile=windows2000)
Mirip dengan asumsi dari presentasi terkenal "The Birth & Death of JavaScript" Referensi: https://www.destroyallsoftware.com/talks/the-birth-and-death-of-javascript
Ada juga percobaan seperti: https://www.chromium.org/blink/blink-in-js/
Karena isu sandboxing dan keamanan, masa depan juga bisa membuat struktur seperti ini menjadi keharusan
Kalau mau melihat contoh seperti itu, bisa cek https://trevorlinton.github.io
Di https://github.com/WICG/html-in-canvas/blob/main/security-privacy-questionnaire.md tertulis bahwa risiko “fingerprinting” perlu ditambahkan pada daftar TODO
Aku punya pandangan bahwa hasil serupa dengan HTML-in-Canvas sebenarnya bisa didapat dengan memakai tag
foreignObjectdi SVG Contohnya proyek seperti https://github.com/zumerlab/snapdom yang menyalin DOM dengan inline style ke dalamforeignObjectSVG lalu merendernya ke canvasforeignObjectke canvas Selain itu, juga mendukung fitur baru seperti otomatis update canvas saat konten berubah dan interaktivitasAku tidak yakin aku salah, tapi menurutku merender HTML di atas canvas itu sudah sepenuhnya mungkin hanya dengan JS murni Canvas dipakai untuk menggambar hal-hal yang tidak bisa dilakukan oleh HTML, jadi desainnya bukan untuk menggantikan DOM
Saat ini, contohnya:
Kalau elemen HTML memang selalu di depan segala sesuatu di canvas, itu oke. Tapi kalau tidak, kita harus menumpuk canvas lain di atas HTML, dan ini berulang di setiap layer z Dengan perubahan ini aku rasa akhirnya bisa memperbaiki “stack rendering layer yang terbalik” di browser Aku percaya semua rendering browser harus ditumpuk di atas API universal canvas
Sepertinya nanti kita akan butuh lagi merender canvas di dalam HTML-in-Canvas
Meme “Pimp My Ride” langsung teringat “Bro, karena kamu suka HTML, aku masukkan HTML ke dalam canvas, dan memasukkan lagi canvas ke dalam HTML”
Aku sempat mikir, bagaimana kalau kita kasih satu flag di elemen body:
Dengan begitu, seluruh halaman jadi area gambar yang sama seperti canvas, dan kamu bisa merender elemen DOM seperti biasa Akan lebih baik kalau proses rasterize sampai DOM dibuka Secara arsitektur, rendering DOM dan rendering canvas menjadi layer yang benar-benar setara Misalnya, aksi menggambar garis di halaman bisa mengatur apakah memicu reflow DOM atau tidak
Terbayang semua screen reader berteriak serentak
Dengan cara ini canvas juga bisa otomatis mengatur ukuran; kalau sampai kejadian itu, kita memasuki era komposisi HTML baru Bisa melampaui iframe
Meski terasa canggung, aku cenderung setuju dengan proposal ini Saat ada sesuatu yang perlu digambar, seringkali kita perlu memanfaatkan elemen HTML yang sudah ada Dulu orang biasa merendernya menjadi bitmap offscreen lalu menyalinnya ke canvas, atau mencoba mengatur z-index dan position absolute, tetapi canvas tetap menutupnya secara visual (akhir-akhir ini lumayan membaik) Cara ini mungkin bukan solusi sempurna, tapi lebih baik daripada trik-trik sebelumnya Mirip dengan html2canvas: jika memang harus, ini tetap solusi yang berguna