- HTML-in-Canvas वेब में
<canvas>तत्व के अंदर HTML तत्व/सामग्री को सीधे रेंडर करने वाली नई स्टैंडर्ड API प्रस्तावित करने वाला एक WICG प्रोजेक्ट है - यह जटिल टेक्स्ट लेआउट, accessibility, अंतरराष्ट्रीयकरण, गुणवत्ता/प्रदर्शन जैसी समस्याओं को हल करने के लिए पेश किया गया है, जिससे चार्ट, UI, गेम मेनू जैसे विविध Canvas उपयोग मामलों में HTML स्टाइलिंग सीधे इस्तेमाल की जा सकती है
drawElement,texElement2D,setHitTestRegionsजैसे नए methods के माध्यम से HTML तत्वों को सीधे Canvas 2D या WebGL context में रेंडर व टेक्सचर किया जा सकता है- इंटरैक्शन क्षेत्र, accessibility सुधार, 3D दृश्य के भीतर 2D UI, CSS/HTML आधारित लेआउट जैसी वास्तविक वेब ऐप डेवलपर्स की जरूरतें इसमें परिलक्षित हैं
- वर्तमान में Chrome Canary (138.0.7175.0+) में एक experimental flag के रूप में सक्षम है, और मुख्य feedback/bug report का स्वागत है
अवलोकन और महत्व
- HTML तत्व को सीधे
<canvas>पर रेंडर करने वाली नई API का प्रस्ताव - पहले जटिल लेआउट, टेक्स्ट और HTML-आधारित सामग्री को
<canvas>में आसानी से render करने का तरीका नहीं था, जिससे accessibility, i18n, performance और quality में सीमाएँ थीं - HTML-in-Canvas इस gap को भरता है, और 2D canvas तथा WebGL में HTML rendering देकर चार्ट टूल, rich-text बॉक्स, गेम UI आदि में लागू करने की क्षमता बढ़ाता है।
उपयोग के उदाहरण
- स्टाइल किया गया टेक्स्ट और लेआउट सामग्री का canvas के अंदर प्रदर्शन
- उदाहरण: चार्ट की legend, axis, rich editor बॉक्स, गेम के इन-गेम मेनू आदि
- accessibility सुधार
- canvas के fallback content और वास्तविक rendered content में mismatch की समस्या का समाधान
- नए API से accessibility जानकारी को sync किया जा सकता है
- HTML और WebGL shader का संयोजन
- CSS filter effects से आगे बढ़कर सामान्य WebGL shaders के साथ HTML के संयोजन की मांग को पूरा करता है
- 3D context के भीतर HTML rendering
- गेम/साइट के 3D क्षेत्र में rich 2D कंटेंट डालना संभव
प्रस्तावित API और मुख्य फीचर
<canvas layoutsubtree>attribute के साथ canvas के child HTML तत्वों का लेआउट सक्षम करना (डिफ़ॉल्ट रूप से केवल visial render, और पेज नेविगेशन जैसी UA algorithms में expose नहीं)- CanvasRenderingContext2D.drawElement(element, x, y, options)
- canvas के child HTML तत्व को निर्दिष्ट स्थान पर render करना
options.allowReadbackसे निजी डेटा लीक रोकने का नियंत्रण (भविष्य में tainting policy लागू होगी)- dwidth/dheight parameters से इच्छित size पर resize संभव
- WebGLRenderingContext.texElement2D(...)
- चुने हुए HTML तत्व को सीधे WebGL texture पर draw करके 3D scene में उपयोग करना
- setHitTestRegions
- किसी क्षेत्र में draw किए गए तत्वों और canvas events (hit test) को लिंक करके mouse/touch events को अपने-आप redirect करना
- fireOnEveryPaint विकल्प (ResizeObserver)
- HTML बदलने/relayout होने पर canvas re-render timing को auto-detect कर redraw trigger करना
व्यवहार और सीमाएँ
- drawElement कॉल के समय canvas transform matrix (CTM) लागू होता है, और image केवल तत्व के border box के अंदर clip होती है
- canvas पर drawn image static है (render के बाद तत्व बदलने पर फिर से drawElement करना पड़ेगा)
- offscreen/DOM में मौजूद न होने वाले canvas के लिए समर्थन नहीं (तकनीकी सीमा)
- इंटरैक्टिव तत्व (button, form आदि) draw किए जा सकते हैं, लेकिन खुद-ब-खुद interactive नहीं होते
- cross-origin iframe, SVG foreignObject आदि समर्थित नहीं हैं
- accessibility और security/privacy (PII) संबंधित मुद्दों पर चर्चा जारी है
डेमो उदाहरण
- complex-text उदाहरण: canvas पर HTML styled टेक्स्ट, बॉक्स आदि complex layout को सीधे drawElement से draw करना
- webGL उदाहरण: texElement2D से HTML content को WebGL texture बनाकर 3D cube पर map करना
- text-input उदाहरण: setHitTestRegions और fireOnEveryPaint का उपयोग कर input form आदि interactive क्षेत्रों की पहचान दिखाना
डेवलपर ट्रायल और सावधानियाँ
- Chrome Canary में
--enable-blink-features=CanvasDrawElementflag से इसे enable किया जा सकता है - canvas content tainted न हो इसलिए privacy/leakage से सावधानी अनिवार्य
- API और व्यवहार लगातार बदल रहे हैं, और अभी बड़े पैमाने पर HTML test cases उपलब्ध नहीं हैं
- feedback स्वागत है: compatibility, render failure cases, accessibility issues आदि GitHub Issue में report करने की सलाह दी जाती है
उपयोगिता और भविष्य
- चार्ट, डेटा visualization, in-canvas UI, 3D गेम के HUD/menus आदि क्षेत्रों में वेब की expressiveness और productivity में वृद्धि संभव
- पहले कठिन रहे HTML→Canvas conversion (styling, layout, localization, accessibility) को standard API के जरिए सीधे handle करना संभव
- वेब-आधारित graphics, gaming और app डेवलपर्स के लिए यह एक powerful नई तकनीक के रूप में उम्मीद जगाती है
1 टिप्पणियां
Hacker News टिप्पणी
Accessibility और abuse को लेकर काफी चिंताएँ हैं, लेकिन इस चर्चा का दूसरा पहलू भी देखना होगा अभी हाल ही में एक दिलचस्प Twitter thread में पढ़ा कि web के विकास में हो सकने वाली 90% अच्छी चीज़ें शायद इसलिए नहीं हो पा रही हैं क्योंकि JS से font rendering और metrics एक्सेस नहीं किए जा सकते web अपने टेक्स्ट रिप्रेजेंट करने के लिए डिजाइन किया गया platform है, पर इसमें text को detail में handle करने वाली capabilities की कमी है; tldraw में text measurement को जबरन लागू करने जैसी हालत पर कई प्रतिक्रियाएँ थीं (ट्वीटर थ्रेड: https://x.com/_chenglou/status/1951481453046538493) web एक application development platform है, इसलिए इसे आसान और powerful बनाना सबके लिए बेहतर है मेरे हिसाब से web API को थोड़ा और low-level जाना चाहिए; अगर canvas के लिए font/text metrics API होता तो बहुत अच्छा होता साथ ही, web engines का text layout बेहद performant है, इसलिए अगर यही capability canvas के अंदर भी use हो सके तो अच्छा फीचर बनेगा मैं कई सालों से एक ही उदाहरण दोहराता रहा हूँ: ‘pagination किया हुआ rich text editing’; सिर्फ contenteditable से product-level implementation संभव नहीं होने के कारण Google Docs को अपना layout engine खुद बनाना पड़ा अगर यह proposal लागू होता है, तो contenteditable की ताकत और page/print layout control दोनों मिल जाएँगे उम्मीद है कि यह browser में adopt हो
“वेब में होने वाली अधिकांश अच्छी चीजें इसलिए नहीं बन पातीं क्योंकि font rendering और metrics उपलब्ध नहीं हैं” वाले दावे पर मुझे थोड़ा doubt है वास्तविक तौर पर कोई बड़ी उदाहरण वाली innovation क्या है, यह देखना चाहूँगा अभी भी JS में font और metrics data काफी हद तक उपलब्ध है, और ज़रूरी चीजें अक्सर बिना किसी गंभीर perf penalty के workaround की जा सकती हैं और HTML-in-Canvas में मिलने वाली सुविधा भी इस area में कोई मौलिक बदलाव नहीं लाती
मैं भी Nutrient में Google Docs की तरह Harfbuzz और अपना layout engine WASM के साथ चला रहा हूँ डेमो: https://document-authoring-demo.nutrient.io/ अगर ऐसा API प्लेटफॉर्म-लेवल पर official हो जाए तो development बहुत आसान हो जाएगा WASM की वजह से सच में कोई dead end नहीं है सुनने में आया है कि ElectricSQL में sync का काम चल रहा है, so Oleksii को भी salam दे देना
“इस feature को browser में लागू करो” वाली बात में, मुझे समझ नहीं आता कि दुनिया का शायद सबसे inefficient layout/UI engine को canvas तक क्यों extend करना चाहिए इससे वर्तमान issue सिर्फ यह हो जाएगा कि अच्छा API access न होने की समस्या और permanent हो जाएगी Figma ने DOM की सीमा से निकलने के लिए browser के अंदर दूसरा browser बनाने जैसा approach लिया है (संदर्भ: https://www.figma.com/blog/building-a-professional-design-tool-on-the-web/) अगर सिर्फ contenteditable के भरोसे product-level काम संभव नहीं था और इसलिए Google Docs ने अपना engine बनाया, तो नया proposal वास्तविक rich-text layout में ज्यादा मदद करेगा, यह कठिन लगता है
यह फीचर उपयोगी है, पर HTML के अंदर Canvas के अंदर HTML डालने वाली पूरी संरचना मुझे थोड़ा odd और अनफ़िट लगती है मेरी समझ से canvas को browser में एक independent first-class format बनना चाहिए ताकि इसे सही तरीके से handle किया जा सके तब HTML-centric page में Canvas डालना या उसके उलट Canvas-centric में HTML elements होना दोनों ही natural लगेंगे हाँ, यह सिर्फ मेरी राय है
इसमें अजीब कोई बात नहीं है वैसे भी, पहले से HTML को SVG में, फिर HTML में डालना संभव है अगर page का top-level element canvas हो, तो page title कहाँ रखा जाएगा? अंततः tag का उपयोग करना पड़ता, उदाहरण के लिए
practically अगर canvas tag के अंदर सीधे content डालने की सुविधा हो तो यह बड़ा आसान हो सकता है
canvas-first वेबसाइट में कई असुविधाएँ हैं सिस्टम सेवाएँ (autocomplete, accessibility आदि) पूरी नहीं मिलतीं और privacy issues भी आते हैं उदाहरण के लिए, सिस्टम की spell-check/correction का इस्तेमाल कठिन होता है और native accessibility उपलब्ध नहीं होने से प्रत्येक app में अलग UI accessibility खुद से बनानी पड़ती है
तुम्हारे बताए मॉडल में Flash को फिर से invent करने जैसा लगता है लेकिन Flash को web पर लाना भी पहले भारी दर्द वाला काम था
HTML page में Canvas रखकर उसके अंदर के टेक्स्ट पर layout या styling चाहिए होता है, ऐसे cases मौजूद हैं इसके लिए पूरी page layout model बदलना ज्यादा complex और unnecessary काम है
पहले भी लोगों को WASM-based DOM access पसंद नहीं था इसलिए ऐसी दिशा में आगे बढ़ना शायद unavoidable है
अब हम लगभग उस जगह पहुँच गए हैं कि पूरा browser WASM में compile करके, इस browser को main browser के canvas element के अंदर चला सकें
पूरी OS के साथ IE को भी web पर run करना संभव है (example: https://copy.sh/v86/?profile=windows2000)
Famous talk “The Birth & Death of JavaScript” के premise जैसा ही लगता है संदर्भ: https://www.destroyallsoftware.com/talks/the-birth-and-death-of-javascript
https://www.chromium.org/blink/blink-in-js/ में भी ऐसे प्रयास हैं
‘sandboxing और security’ issues के कारण शायद ऐसा architecture भविष्य में अनिवार्य भी हो सकता है
संदर्भ के लिए https://trevorlinton.github.io पर सीधे ऐसा ही environment देख सकते हैं
https://github.com/WICG/html-in-canvas/blob/main/security-privacy-questionnaire.md में देखा जा सकता है कि ‘fingerprinting risk’ को लेकर और चीजें add करनी बाकी हैं, ऐसा एक TODO मौजूद है
SVG के
foreignObjecttag का use करें तो HTML-in-Canvas जैसा outcome पहले से possible लगता है जैसे https://github.com/zumerlab/snapdom में देखा, जहाँ DOM को inlined style के साथ copy करके SVG के foreignObject में डालते हैं और उसे canvas पर render करते हैंशायद मैं गलत हो सकता हूँ, पर pure JS से ही canvas पर HTML render करना पर्याप्त संभव लगता है canvas का उपयोग वही चीज़ करने के लिए है जो HTML नहीं कर सकता, और यह DOM को replace करने के लिए नहीं बना
वर्तमान में उदाहरण के लिए
यदि HTML elements हमेशा canvas के ऊपर रहें तो ठीक है; नहीं तो HTML के ऊपर दूसरा canvas रखना पड़ेगा और z-layer हर बार दोबारा सेट करना होगा इस बदलाव से शायद browser का उल्टा पड़ा हुआ rendering layer stack ठीक किया जा सकता है मेरी राय में सभी browser rendering को universal canvas API पर stack होना चाहिए
जल्द ही शायद HTML-in-Canvas के अंदर फिर से Canvas rendering की ज़रूरत महसूस होगी
“Pimp My Ride” meme याद आ रहा है जैसे कोई कहे: “भाई, तू HTML पसंद करता है न, इसलिए मैंने canvas में HTML डाल दिया और उस HTML में भी फिर से canvas डाल दिया” वाला feel
body element को ऐसे flag देने का idea है शायद
अगर ऐसा हो, तो पूरी page एक canvas जैसा drawing surface बन जाएगी और normal तरीके से DOM elements render कर पाएँगे अंदरूनी तौर पर DOM rendering और canvas rendering बराबर के layers बन जाएँगे उदाहरण के लिए, page पर लाइन draw करने की action DOM element reflow को trigger करने या ignore करने के लिए भी control की जा सकती है
तुरंत ऐसा लगता है कि स्क्रीनरीडर एक साथ चिल्ला उठेंगे
इस approach से canvas का auto-resize संभव हो सकता है; अगर सच में ऐसा हुआ, तो यह HTML compositing का नया युग होगा iframe से आगे निकल सकते हैं
थोड़ा awkward है, लेकिन मैं इस proposal के पक्ष में हूँ जब भी कुछ draw करना होता है, कभी-कभी existing HTML elements को reuse करना पड़ता है पहले हम उसे offscreen में bitmap render करके canvas में copy करते थे या z-index/position absolute से adjust करने की कोशिश करते थे, लेकिन canvas हमेशा visual रूप से ऊपर होकर बाकी को ढक देता था (हाल के वक्त में इसमें काफी सुधार है) यह तरीका शायद पूर्ण समाधान नहीं, मगर पुराने workarounds से कहीं बेहतर है ठीक html2canvas की तरह, जब सच में यही करना पड़े तो यह एक workable workaround है