- HTML-in-Canvas, webde
<canvas>elemanının içinde HTML öğesi/içeriğini doğrudan çizebilen yeni bir standart API öneren bir WICG projesidir - Karmaşık metin yerleşimi, erişilebilirlik, uluslararasılaştırma ve kalite/perfomans sorunlarını çözmek için ortaya çıktı ve grafik, UI, oyun menüsü gibi farklı Canvas kullanım senaryolarında HTML stilini doğrudan kullanmayı mümkün kılıyor
drawElement,texElement2D,setHitTestRegionsgibi yeni yöntemler sayesinde HTML öğeleri doğrudan Canvas 2D veya WebGL bağlamında render edilip dokuya dönüştürülebiliyor- Etkileşim bölgesi, erişilebilirlik geliştirmeleri, 3B sahne içindeki 2B UI, CSS/HTML tabanlı düzenler gibi pratik web uygulaması ihtiyaçları yansıtılıyor
- Şu anda Chrome Canary (138.0.7175.0 ve üstü) üzerinde deneysel bir bayrakla etkinleştirilebilir ve ana geri bildirim/hata raporları bekleniyor
Genel Bakış ve Önemi
- HTML öğelerinin doğrudan
<canvas>içine çizilebildiği yeni bir API öneriliyor - Önceden karmaşık düzen, metin ve HTML tabanlı içerikleri
<canvas>içinde kolayca render etmenin bir yolu olmadığından erişilebilirlik, uluslararasılaştırma, performans ve kalite açısından sınırlamalar vardı - HTML-in-Canvas, bu eksikliklere karşı bir tamamlayıcı olarak 2B canvas ve WebGL içinde HTML render etme desteği sunarak grafik çizelgesi araçları, zengin metin kutuları, oyun arayüzleri gibi geniş alanlarda uygulanabilirliği artırıyor.
Kullanım Örnekleri
- Stilleştirilmiş metin ve düzen içeriğinin canvas içinde gösterimi
- Örn: Grafiklerin lejantları, eksenleri, zengin metin düzenleyici kutuları, oyun içi menüler vb.
- Erişilebilirlik geliştirmesi
- Mevcut canvaslarda yedek içerikle gerçekten render edilen içerik arasındaki tutarsızlık giderilir
- Yeni API ile erişilebilirlik verilerinin senkronizasyonu sağlanır
- HTML ile WebGL shader birleştirme
- CSS filtre etkilerinin ötesinde, genel WebGL shader’larıyla HTML birleşimi ihtiyacını karşılar
- 3B bağlam içinde HTML render etme
- Oyun/sitenin 3B alanlarına zengin 2B içerik yerleştirilebilir
Önerilen API ve Temel Özellikler
<canvas layoutsubtree>özniteliğiyle canvas altındaki HTML öğelerinin düzeni etkinleştirilir (yalnızca görsel olarak render edilir, varsayılan olarak sayfa gezintisi gibi UA algoritmalarında görünmez)- CanvasRenderingContext2D.drawElement(element, x, y, options)
- canvas’ın çocuk HTML öğesini belirtilen konuma render eder
options.allowReadbackile gizli bilgi sızmasını engelleme kontrolü yapılır (ileride tainting politikası uygulanacak)dwidth/dheightparametreleriyle istenen boyuta yeniden boyutlandırma yapılabilir
- WebGLRenderingContext.texElement2D(...)
- Belirli bir HTML öğesi doğrudan WebGL dokusuna çizilerek 3B sahnede kullanılabilir
- setHitTestRegions
- Belirli bir alana çizilen öğe ile canvas hit test’i bağlanarak fare/dokunma olayları otomatik yönlendirilir
- fireOnEveryPaint seçeneği (ResizeObserver)
- HTML’deki değişikliklerde/göreli taşımada canvas yeniden render zamanını otomatik algılayıp yeniden çizimi tetikler
Davranış ve Sınırlamalar
- drawElement çağrısında canvas dönüştürme matrisi (CTM) yansıtılır, içerik yalnızca öğenin border box’ı içinde kırpılır
- Canvas’a çizilen görüntü statiktir (renderdan sonra öğe değişirse tekrar
drawElementçağrılması gerekir) - Offscreen/DOM’da olmayan canvaslarda desteklenmez (teknik kısıt)
- Etkileşimli öğeler (buton, form vb.) çizilebilir ama otomatik olarak etkileşimli olmaz
- Cross-origin iframe’ler ve SVG
foreignObjectdesteklenmez - Erişilebilirlik, güvenlik ve gizlilik (PII) konularındaki meseleler hâlâ tartışılıyor
Demo Örnekleri
- complex-text örneği:
drawElementile canvas üzerindeki HTML stilindeki metin, kutu vb. karmaşık düzenleri doğrudan çizme - webGL örneği:
texElement2Dile HTML içeriğini WebGL dokusuna dönüştürüp 3B küpe eşleme - text-input örneği:
setHitTestRegionsvefireOnEveryPaintile giriş formları gibi etkileşimli alanları işaretleme
Geliştirici Denemesi ve Dikkat Edilecek Noktalar
- Chrome Canary’da
--enable-blink-features=CanvasDrawElementbayrağıyla etkinleştirilir - Canvas içeriği
taintedolmazsa bile kişisel verilerin sızmasına karşı dikkat şart - API ve davranışlar hızla evriliyor; büyük ölçekli HTML test senaryoları henüz sınırlı
- Geri bildirim davetlidir: uyumluluk, render hatası örnekleri, erişilebilirlik sorunları gibi konular için GitHub Issue ile rapor önerilir
Kullanım Değeri ve Görünüm
- Grafikler, veri görselleştirme, in-canvas UI, 3B oyun içi HUD/menü gibi alanlarda web’in ifade gücü ve üretkenliğinin artacağı öngörülüyor
- Daha önce zor olan HTML→Canvas dönüşümü (stil, düzen, çoklu dil desteği, erişilebilirlik) artık standart API ile doğrudan işlenebiliyor
- Web tabanlı grafik, oyun ve uygulama geliştiricilerine güçlü bir yenilik olarak bekleniyor
1 yorum
Hacker News yorumları
Erişilebilirlik ve kötüye kullanım konusunda çok kaygı var ama bu tartışmanın başka bir yüzünü de görmemiz lazım Geçenlerde ilginç bir Twitter dizisi gördüm; webin gelişimi için font render ve metriklerine JS’den erişilememesi nedeniyle iyi şeylerin %90’ının yapılamadığı söylenmiş Webin metin göstermek için tasarlanmış bir platform olduğu ve metni detaylı işleyebilmek için yeterli özelliklerin bulunmaması, tldraw’de metin ölçümünü zorla kendin üretmeye çalışmasının üzücü olması gibi pek çok yanıta rastladım (Twitter dizisi: https://x.com/_chenglou/status/1951481453046538493) Web, bir uygulama geliştirme platformu olduğu için hem kolay hem güçlü olursa herkesin işine yarar Bence web API’leri biraz daha düşük seviyeye inmeliydi; canvas için bir font/metin metrik API’si olsa çok iyi olur Ama aynı zamanda web motorunun metin yerleşimi inanılmaz hızlı; böyle bir özellik canvas içinde de kullanılabilse gerçekten güçlü bir araç olur Yıllardır tekrar tekrar savunduğum örneklerden biri “sayfalı zengin metin düzenleme”; contenteditable ile ürün seviyesinde uygulanamadığı için Google Docs’un kendi layout motorunu yaptığı örnek Bu öneri devreye girerse contenteditable’ın gücüyle sayfa/baskı düzenini kontrol etme olanağı da elde edilebilir Bu özelliğin tarayıcıya uygulanmasını umarım
“Webde gerçekleşebilecek çoğu iyi şeyin font render ve metriklere erişilememe yüzünden mümkün olmadığını” iddiasına biraz şüpheyle bakıyorum Gerçekten hangi somut yenilikçi örneği gördüğünüzü merak ediyorum Şu an JS’de font ve metrik bilgisi epeyce var ve gereken işlevler çoğunlukla ciddi bir performans engeli olmadan aşılabiliyor Ayrıca HTML-in-Canvas’te verilen şeyler bu alanlarda köklü bir değişim de getirmiyor
Ben de Google Docs gibi Nutrient’te Harfbuzz ve kendi layout motorunu WASM tabanlı kullanıyorum Demo: https://document-authoring-demo.nutrient.io/ Böyle bir API platformda resmi olarak sağlansaydı geliştirme çok daha kolay olurdu WASM sayesinde gerçekten çıkışsız bir yol yok ElectricSQL’de senkronizasyon çalışmasıyla ilgili haber aldım, bu yüzden Oleksii’ye de selam
“Bu özelliğin tarayıcıda uygulanmasını bekliyorum” sözlerinin, dünyanın en verimsiz layout/UI motorunu canvas’a kadar genişletmek istemekle eşanlamlı olmasını anlamıyorum Bu sadece bugün de olan iyi API erişimi eksikliğini daha da dondurur Figma, DOM sınırlamalarını aşmak için tarayıcının içinde ikinci bir tarayıcı inşa eden bir yolla çalışıyor (bkz: https://www.figma.com/blog/building-a-professional-design-tool-on-the-web/) contenteditable ile ürün seviyesinde yapılmamışsa ve Google Docs da kendi motorunu kurduysa, yeni önerinin zengin metin layout’una pratikte yardımcı olması zor
Bu fonksiyonun faydası büyük olsa da, HTML içinde canvas içinde HTML barındıran yapı kulağa garip ve uyumsuz geliyor Bence canvas, tarayıcıda bağımsız bir birinci sınıf format olursa daha doğal şekilde ele alınabilir Böylece HTML merkezli sayfaya canvas eklemek ya da tersine canvas merkezli bir yapıya HTML elemanı yerleştirmek doğal olur Bu yalnızca benim düşüncem
Söylediklerinde bir gariplik yok Ayrıca zaten HTML’i SVG içine, sonra tekrar HTML içine gibi gömebiliyoruz Eğer canvas sayfanın en üst seviyesi olursa sayfa başlığı nerede durur? Sonuçta etiketini kullanmak gerekir, örneğin
Aslında canvas etiketinin içinde içerik alanı açılmasıyla bu çok basit çözülebilir
Canvas merkezli web siteleri kullanımı zor Sistem hizmetlerinin (otomatik tamamlama, erişilebilirlik vb.) tamamını kullanamazsın ve gizlilik de sorun olur Örneğin sistemin yazım denetimini kullanmak zor, ayrıca sistem erişilebilirliği sunulamaz; bu yüzden her uygulama için tümde farklı bir UI erişilebilirliğini baştan yapmak gerekir
Bu yapıyla adeta Flash’ı yeniden icat etmiş olursun Ama Flash’ı web’e yerleştirmek de çok acı bir işti
HTML sayfasında canvas tutup, bunun metnine layout veya stil eklemek istediğimiz anlar olur O nedenle tüm sayfanın layout yaklaşımını değiştirmek gereksiz derecede karmaşık olur
Daha önce de WASM ile DOM erişimine karşı çıkanlar oldu Bu yüzden bu yöne giden adımlar kaçınılmaz görünüyor
Şimdi neredeyse tüm tarayıcıyı WASM’e derleyip, bu tarayıcıyı ana tarayıcının canvas öğesinin içinde çalıştırabilecek noktaya geldik
OS’nin tamamını, IE dahil, webde çalıştırmak da mümkün (örnek: https://copy.sh/v86/?profile=windows2000)
The Birth & Death of JavaScript’in ünlü sunumunda olduğu gibi bir varsayım Bkz: https://www.destroyallsoftware.com/talks/the-birth-and-death-of-javascript
https://www.chromium.org/blink/blink-in-js/ de böyle bir girişim var
“Sandboxing ve güvenlik” meseleleri nedeniyle böyle bir mimari gelecekte zorunlu hale gelebilir
Aynı yapıyı doğrudan görebileceğiniz bir yer: https://trevorlinton.github.io
https://github.com/WICG/html-in-canvas/blob/main/security-privacy-questionnaire.md dosyasında “parmak izi toplama (fingerprinting) riskleri” konusunda eklenmesi gereken bir TODO var
SVG’nin
foreignObjectetiketi ile zaten HTML-in-Canvas’a benzeyen sonuçlar alınabileceğini düşünüyorum Örneğin https://github.com/zumerlab/snapdom gibi projeler, DOM’u inline style ile kopyalayıp SVG’deki foreignObject içine koyup bunu canvas’a render ediyorBelki de yanlışım ama saf JS ile canvas üstüne HTML render etmek bence gayet mümkün Canvas, HTML’den yapılamayan şeyleri çizer; DOM’u değiştirmek için tasarlanmış bir yapı değil
Şu an için örnek olarak
HTML elemanları canvas’ın üstünde her şeyden önde ise sorun yok; değilse HTML’ın üstüne tekrar canvas koymak gerekiyor ve her z katmanı için aynı işi tekrarlarsınız Bu gelişme sayesinde tarayıcının “ters çizim katmanı yığını” eninde sonunda düzelebilir Bence tüm tarayıcı render’ı, evrensel bir canvas API üzerine inşa edilmeli
Yakın zamanda HTML-in-Canvas içinde yine canvas render ihtiyacı duymaya başlamayacak mıyız diye düşünüyorum
“Pimp My Ride” memesini hatırlatıyor “Abi, HTML’i sevdiğini söylemiştin; o yüzden canvas içine HTML, sonra da HTML içine canvas yaptım” gibi bir şey
Belki body elementine şöyle bir flag verseydik iyi olurdu diye düşünüyorum
Bu sayede sayfanın tamamı canvas ile aynı çizim yüzeyi olur ve normalde yaptığımız gibi DOM elemanlarını render edebiliriz Dahası, içeride DOM’u rasterize etme adımını açmaları daha iyi olurdu Mimari olarak DOM rendering ile canvas rendering eşit seviyede katman olur Örneğin sayfaya çizgi çekme eylemi, DOM elemanının reflow’a zorlanmasını ya da bundan kaçınmasını kontrol edebilir
Birden çok ekran okuyucunun aynı anda bağırdığı bir durum düşünülebilir
Bu yöntemle canvas’ın otomatik boyutlandırma yapabilmesi de mümkün olur; eğer olursa HTML kombinasyonlarının yeni bir dönemini başlatır iframe’in ötesine geçilebilir
Garip bulsam da bu teklifi destekleyen taraftayım Bir şeyler çizerken çoğu zaman var olan HTML elemanlarını tekrar kullanma ihtiyacı doğuyor Eskiden bunu offscreen’de bitmap olarak render edip canvas’a kopyalamaya, veya z-index/position absolute ile ayarlamaya çalışsa da canvas görsel olarak daima üst üste bürüyordu (son zamanlarda epey iyi ilerledi) Bu yöntem mükemmel bir çözüm olmayabilir ama önceki hilelerden çok daha iyi Tam olarak html2canvas gibi, böyle bir zorunluluk varsa kullanılabilecek bir çözüm