सामान्य <canvas> कॉन्टेंट, ब्राउज़र की सुविधाओं के लिए उपलब्ध नहीं होता. जैसे, स्क्रीन रीडर, इंडेक्स करना, अनुवाद करने वाले टूल, सुलभता से जुड़े सहायक टूल, पेज पर ढूंढना, प्रिंट करना वगैरह. HTML in canvas की मदद से, रीयल डीओएम को सीधे कैनवस एलिमेंट में रेंडर किया जा सकता है. <canvas> एचटीएमएल एलिमेंट में content="drawable" एट्रिब्यूट जोड़ने से, उसके डिसेंडेंट एचटीएमएल एलिमेंट लेआउट हो जाते हैं. साथ ही, drawable एट्रिब्यूट उन एलिमेंट को मार्क करता है जिन्हें कैनवस के रेंडरिंग कॉन्टेक्स्ट में रेंडर किया जा सकता है. इसका इस्तेमाल, कैनवस में टेक्स्ट को स्टाइल करने और लेआउट करने के लिए किया जा सकता है. साथ ही, कैनवस के कॉन्टेंट को ब्राउज़र की सुविधाओं (जैसे, सुलभता, अनुवाद या पेज पर ढूंढें) के लिए एक्सपोज़ किया जा सकता है. इसके अलावा, एचटीएमएल पर 2D और 3D इफ़ेक्ट लागू किए जा सकते हैं.
इन्हें कैसे लागू करें
देखें कि ब्राउज़र में HTML-in-Canvas की सुविधा काम करती है या नहीं:
if ('content' in HTMLCanvasElement.prototype) { // Use HTML in Canvas API } else { // Use fallback strategy }<canvas>एचटीएमएल एलिमेंट मेंcontent="drawable"एट्रिब्यूट जोड़ें.अपने एचटीएमएल कॉन्टेंट को
<canvas>एलिमेंट के अंदर रखें. साथ ही, ड्रॉ किए जाने वाले हर एलिमेंट मेंdrawableएट्रिब्यूट जोड़ें.drawableवाला एलिमेंट, अपने सबट्री को कैप्चर करता है. हालांकि, यह नेस्ट किए गए उन डिसेंडेंट को कैप्चर नहीं करता जोdrawableभी हैं.<canvas id="canvas" content="drawable"> <div id="html-content" drawable></div> </canvas>धुंधलेपन से बचने के लिए, अपने कैनवस ग्रिड को डिवाइस के स्केल फ़ैक्टर के हिसाब से स्केल करें:
const observer = new ResizeObserver(([entry]) => { const dpc = entry.devicePixelContentBoxSize; canvas.width = dpc ? dpc[0].inlineSize : Math.round(entry.contentRect.width * window.devicePixelRatio); canvas.height = dpc ? dpc[0].blockSize : Math.round(entry.contentRect.height * window.devicePixelRatio); }); const supportsDevicePixelContentBox = typeof ResizeObserverEntry !== "undefined" && "devicePixelContentBoxSize" in ResizeObserverEntry.prototype; const options = supportsDevicePixelContentBox ? { box: "device-pixel-content-box" } : {}; observer.observe(canvas, options);canvas.onpaintइवेंट हैंडलर में, एचटीएमएल कॉन्टेंट को कैनवस पर रेंडर करें. कैनवस पर पेंट होने के बाद ही किसी एलिमेंट को ड्रॉ किया जा सकता है:paintइवेंट का अनुरोध करने के लिए,canvas.requestPaint()को कॉल करें.
- 2D कॉन्टेक्स्ट में,
drawElementImageवाला तरीका इस्तेमाल करें. यह सीएसएस ट्रांसफ़ॉर्म से पहले, एलिमेंट के बॉर्डर बॉक्स से शुरू होने वालेdrawableएलिमेंट और उसके ड्रॉ किए जा सकने वाले सबट्री का आखिरी स्नैपशॉट ड्रॉ करता है:
canvas.onpaint = () => {
ctx.reset();
// Draw the form element at x:0, y:0
ctx.drawElementImage(form_element, 0, 0);
};
- WebGL और WebGPU कॉन्टेक्स्ट में, एलिमेंट को टेक्सचर में कॉपी किया जाता है.
canvas.captureElementImage(element)से टेक्स्चर का साइज़ तय करें. इसकेwidthऔरheight, कैनवस ग्रिड (बैकिंग स्टोर) पिक्सल में होते हैं. इसलिए, उन्हेंMath.ceil()के साथ राउंड अप करें. अगर एलिमेंट में अब तक कोई पेंट रिकॉर्ड नहीं है, तोcaptureElementImage()गड़बड़ी दिखाता है:requestPaint()को कॉल करें और अगलेpaintइवेंट पर फिर से कोशिश करें.
// Returns the element's size in canvas grid pixels, or null if the element
// has no paint record yet.
function getElementImageSize(canvas, element) {
let elementImage;
try {
elementImage = canvas.captureElementImage(element);
} catch (err) {
canvas.requestPaint(); // No paint record yet: retry on the next paint event.
return null;
}
const width = Math.ceil(elementImage.width);
const height = Math.ceil(elementImage.height);
elementImage.close();
return width > 0 && height > 0 ? { width, height } : null;
}
- WebGL कॉन्टेक्स्ट में,
texImage2Dतरीके का इस्तेमाल करके, पहले से ही टेक्सचर बैकिंग तय करें. इस गाइड में दिए गए स्निपेट, WebGL 2 कॉन्टेक्स्ट (canvas.getContext("webgl2")) का इस्तेमाल करते हैं. पिक्सल डेटा के बजायnullके साथtexImage2D()को कॉल करके, टेक्सचर स्टोरेज तय करें. इससे, बिना कोई पिक्सल अपलोड किए, दिए गए साइज़ और फ़ॉर्मैट की जीपीयू मेमोरी रिज़र्व हो जाती है. इन नियमों का पालन करें:captureElementImage()से टेक्स्चर का साइज़ तय करें, जैसा कि ऊपर दिखाया गया है.- लेवल 0 को सिर्फ़ पहली बार अपलोड करते समय या साइज़ बदलने पर असाइन करें. ऐसा इसलिए, क्योंकि फिर से असाइन करने पर टेक्सचर हट जाता है. म्यूटेबल स्टोरेज का इस्तेमाल करें: एलिमेंट का साइज़ बदलने पर, इम्यूटेबल
texStorage2D()स्टोरेज का साइज़ नहीं बदला जा सकता.
// Binds the texture, and allocates its storage on the first upload, and when
// the element size changes. `state` stores the allocated size.
function allocateElementTexture(gl, texture, state, width, height) {
gl.bindTexture(gl.TEXTURE_2D, texture);
if (state.width === width && state.height === height) return;
gl.texImage2D(
gl.TEXTURE_2D,
0, // Mipmap level
gl.RGBA8, // Internal format: 8 bits per RGBA channel
width, // Size in canvas grid pixels
height,
0, // Border: must be 0
gl.RGBA, // Format and type that match RGBA8
gl.UNSIGNED_BYTE,
null // null reserves GPU memory without uploading pixels
);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
state.width = width;
state.height = height;
}
const texture = gl.createTexture();
const textureState = { width: 0, height: 0 };
- इसके बाद, WebGL कॉन्टेक्स्ट में,
texElementSubImage2Dतरीके का इस्तेमाल करके एचटीएमएल कॉन्टेंट को टेक्सचर में रेंडर करें. इन नियमों का पालन करें:- कॉन्फ़िगरेशन में
{ width, height }पास करें. इससे कॉपी, तय किए गए टेक्सचर को भर देती है. भले ही, कैनवस को किसी भी तरह से स्केल किया गया हो. - अगर साइज़ बदल गया है, तो टेक्सचर को फिर से असाइन करें, जैसा कि ऊपर दिखाया गया है.
- कॉन्फ़िगरेशन में
// Uploads the element into the texture. Returns false if the element has no
// paint record yet. In that case, it's uploaded on the next paint event.
function uploadElementWebGL(gl, canvas, texture, element, state) {
const size = getElementImageSize(canvas, element);
if (!size) return false;
const { width, height } = size;
// Bind the texture, and reallocate it if the size changed (see above).
allocateElementTexture(gl, texture, state, width, height);
gl.texElementSubImage2D(gl.TEXTURE_2D, 0, 0, 0, element, { width, height });
return true;
}
canvas.onpaint = () => {
try {
uploadElementWebGL(gl, canvas, texture, uiElement, textureState);
} catch (err) {
console.error('texElementSubImage2D copy failed:', err);
}
};
- WebGPU के संदर्भ में,
drawElementImageToTextureतरीके का इस्तेमाल करें. इन नियमों का पालन करें:COPY_DSTऔरRENDER_ATTACHMENTके इस्तेमाल से टेक्सचर बनाएं. साथ ही, शेडर में सैंपल करने के लिएTEXTURE_BINDINGजोड़ें. गलत इस्तेमाल को WebGPU की पुष्टि करने से जुड़ी गड़बड़ी के तौर पर रिपोर्ट किया जाता है, न कि अपवाद के तौर पर.- टेक्स्चर का साइज़
sizeके तौर पर पास करें.sizeके बिना, बड़े एलिमेंट को टेक्सचर के हिसाब से क्लिप किया जाता है.sizeकी मदद से, एलिमेंट को स्केल करके फ़िट किया जाता है. - WebGPU टेक्सचर का साइज़ नहीं बदला जा सकता. एलिमेंट का साइज़ बदलने पर, टेक्सचर को फिर से बनाएं. साथ ही, इसे रेफ़रंस के तौर पर इस्तेमाल करने वाले बाइंड ग्रुप को फिर से बनाएं.
// WebGPU textures can't be resized. Create the texture once, and recreate it
// when the element size changes.
function ensureElementTexture(device, state, width, height) {
if (state.texture?.width === width && state.texture?.height === height) {
return state.texture;
}
state.texture?.destroy();
state.texture = device.createTexture({
size: { width, height },
format: "rgba8unorm",
usage:
GPUTextureUsage.TEXTURE_BINDING |
GPUTextureUsage.COPY_DST |
GPUTextureUsage.RENDER_ATTACHMENT,
});
return state.texture; // Recreate the bind groups that used the previous texture.
}
const textureState = { texture: null };
canvas.onpaint = () => {
const size = getElementImageSize(canvas, uiElement);
if (!size) return;
const previousTexture = textureState.texture;
const texture = ensureElementTexture(device, textureState, size.width, size.height);
if (texture !== previousTexture) {
// New texture: create, or rebuild, the bind groups that reference it.
}
try {
device.queue.drawElementImageToTexture({ source: uiElement }, { texture, size });
} catch (err) {
console.error('drawElementImageToTexture copy failed:', err);
}
};
सीन को रेंडर करने के लिए requestAnimationFrame लूप का इस्तेमाल करते समय, लूप में canvas.requestPaint() को कॉल करें. इससे यह पक्का किया जा सकेगा कि एचटीएमएल कॉन्टेंट, कैनवस पर रेंडर हो. event.changedElements उन एलिमेंट की सूची दिखाता है जिनकी रेंडरिंग में बदलाव हुआ है. यह पक्का करें कि अगर डिसेंडेंट एचटीएमएल एलिमेंट में कोई अपडेट हुआ है, तो सिर्फ़ एलिमेंट को फिर से ड्रॉ करें या उसके टेक्सचर को फिर से अपलोड करें:
function render() {
// Request to update the canvas
canvas.requestPaint();
requestAnimationFrame(render);
}
requestAnimationFrame(render);
canvas.onpaint = (event) => {
if (event.changedElements && event.changedElements.length > 0) {
// Redraw the element, or update its texture, as shown above
}
// In WebGL and WebGPU, render the scene, and sync the element geometry as shown in step 6
};
- एलिमेंट की ज्यामिति को सिंक करें.
ब्राउज़र को यह पता होना चाहिए कि एचटीएमएल एलिमेंट कहां बनाया गया है, ताकि उसकी डीओएम पोज़िशन, बनाए गए पिक्सल से मैच हो सके. क्लिक और टेक्स्ट चुनने के लिए हिट टेस्टिंग और सुलभता, इस ज्यामिति का इस्तेमाल करती है: ऐसा drawable एलिमेंट जिसकी ज्यामिति अपडेट नहीं की गई है वह अब भी सुलभता ट्री में दिखता है, लेकिन ज्यामिति की जानकारी के बिना. कैनवस सिर्फ़ उन एलिमेंट का हिट टेस्ट करता है जिन्हें 2D drawElementImage() तरीके से बनाया गया है या updateElementGeometry() के साथ रजिस्टर किया गया है.
2D कॉन्टेक्स्ट के मामले में, ब्राउज़र एलिमेंट को अपने-आप सिंक करता है.
drawElementImage(), डीओएम हिट-टेस्ट की सीमाओं और स्क्रीन रीडर के फ़ोकस रिंग को ड्रॉ किए गए कोऑर्डिनेट के साथ अलाइन करता है. इसलिए, आपकोstyle.transformसेट करने की ज़रूरत नहीं है. ज्यामिति को मैन्युअल तरीके से मैनेज करने के लिए, उदाहरण के लिए, जब एक ही एलिमेंट को एक से ज़्यादा बार ड्रॉ किया जाता है, तो{ preserveElementGeometry: true }कोdrawElementImage()पर पास करें औरcanvas.updateElementGeometry()के साथ ट्रांसफ़ॉर्म लागू करें.WebGL या WebGPU के साथ 3D केस के लिए, कैनवस यह नहीं बता सकता कि एचटीएमएल एलिमेंट कहां बनाया गया है. इसलिए, आपको यह बताना होगा.
DOMMatrixकी गिनती करें, जो एलिमेंट के बॉर्डर बॉक्स को सीएसएस पिक्सल में, कैनवस पर सीएसएस पिक्सल में मैप करता है. ब्राउज़र को व्यूपोर्ट ट्रांसफ़ॉर्म का इस्तेमाल करके, 3D कोऑर्डिनेट स्पेस से सीएसएस कोऑर्डिनेट स्पेस में मैप करना होगा. इसके लिए, यह तरीका अपनाएं:- एचटीएमएल एलिमेंट को सामान्य बनाएं. एचटीएमएल एलिमेंट का साइज़, पिक्सल में तय किया जाता है. उदाहरण के लिए, 200 पिक्सल चौड़ा. हालांकि, WebGL आम तौर पर ऑब्जेक्ट को "यूनिट स्क्वेयर" के तौर पर ट्रीट करता है. उदाहरण के लिए, -0.5 से 0.5 तक. अगर आपने नॉर्मलाइज़ नहीं किया, तो आपका 200 पिक्सल का बटन 200 गुना बड़ा दिखेगा. यह चरण Y-ऐक्सिस को भी फ़्लिप करता है. ऐसा इसलिए, क्योंकि सीएसएस में, डाउन पॉज़िटिव होता है, लेकिन WebGL में, अप पॉज़िटिव होता है.
- WebGL एमवीपी मैट्रिक्स को DOM मैट्रिक्स में बदलें.
- कैनवस व्यूपोर्ट पर मैप करें. यह चरण "री-स्केलिंग" फ़ेज़ है: यह उस यूनिट-स्पेस मैथ को वापस स्ट्रेच करता है, ताकि स्क्रीन पर आपके
<canvas>एलिमेंट के सीएसएस पिक्सल डाइमेंशन से मैच किया जा सके. साथ ही, Y-ऐक्सिस को वापस फ़्लिप करता है. - फ़ाइनल ट्रांसफ़ॉर्म का हिसाब लगाएं. मैट्रिक्स को इस क्रम में गुणा करें: व्यूपोर्ट * एमवीपी * नॉर्मलाइज़ेशन. इन दोनों को एक फ़ाइनल ट्रांसफ़ॉर्म में जोड़ने से एक "मैप" बनता है. इससे ब्राउज़र को पता चलता है कि एचटीएमएल एलिमेंट को कहां रखना है, ताकि वह 3D ड्रॉइंग के साथ अलाइन हो सके. ब्राउज़र, पर्सपेक्टिव डिवाइड की प्रोसेस को पूरा करता है.
// Maps the element's border box (CSS pixels) to the canvas (CSS pixels), for a // quad that spans -0.5 to 0.5 in model space and is drawn with the `mvp` matrix. function computeCanvasTransform(canvas, element, mvp) { const width = element.offsetWidth; const height = element.offsetHeight; // 1. Normalize the HTML element (CSS pixels -> WebGL Model Space) const toGLModel = new DOMMatrix() // Scale pixels to 1 unit, flip Y (as in CSS it points down, and in WebGL it points up) .scale(1 / width, -1 / height, 1 / height) // Center the origin: (0,0) becomes (-width/2, -height/2) before scaling .translate(-width / 2, -height / 2); // 2. Convert WebGL MVP Matrix to DOM Matrix const mvpDOM = new DOMMatrix(Array.from(mvp)); // 3. Map to the canvas viewport, in CSS pixels const clipToCanvasViewport = new DOMMatrix() // Move center (0,0) to center of canvas .translate(canvas.clientWidth / 2, canvas.clientHeight / 2) // Scale normalized clip (-1..1) to viewport size, and flip Y back .scale(canvas.clientWidth / 2, -canvas.clientHeight / 2, canvas.clientHeight / 2); // 4. Multiply: (Clip -> Pixels) * (MVP) * (pixels -> unit square) return clipToCanvasViewport.multiply(mvpDOM).multiply(toGLModel); }
इसके बाद, ट्रांसफ़ॉर्म को canvas.updateElementGeometry() में canvasTransform के तौर पर पास करें. इससे एचटीएमएल एलिमेंट, रेंडर किए गए पिक्सल के ठीक ऊपर आ जाता है. इससे यह पक्का होता है कि जब कोई उपयोगकर्ता किसी बटन पर क्लिक करता है या टेक्स्ट चुनता है, तो वह असल एचटीएमएल एलिमेंट पर ही क्लिक करता है. ब्राउज़र, एलिमेंट की सुलभता सीमाओं के लिए भी ट्रांसफ़ॉर्म का इस्तेमाल करता है. उदाहरण के लिए, स्क्रीन रीडर की फ़ोकस रिंग के लिए:
canvas.updateElementGeometry(targetHTMLElement, {
canvasTransform: computeCanvasTransform(canvas, targetHTMLElement, htmlElementMVP),
});
हिट टेस्टिंग को कंट्रोल करने के लिए, इन विकल्पों का इस्तेमाल करें:
updateElementGeometry()को कॉल करने पर, एलिमेंट हिट-टेस्टिंग ऑर्डर में सबसे ऊपर चला जाता है.{ preserveHitTestOrder: true }को पास करें, ताकि वह अपनी पोज़िशन बनाए रखे.- हिट टेस्टिंग से किसी एलिमेंट को हटाने के लिए,
canvas.clearElementGeometry(element)को कॉल करें. उदाहरण के लिए, जब उसे छिपाया जाता है.
कोड का उदाहरण
2D कैनवस
<canvas id="canvas" content="drawable" style="width: 400px; height: 200px;">
<div id="ui-element" drawable>
<p>
This text is rendered inside the canvas but is present in the DOM tree.
</p>
<input type="email" name="email" placeholder="enter your email" />
<button type="button">Submit</button>
</div>
</canvas>
<script>
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const uiElement = document.getElementById("ui-element");
canvas.onpaint = () => {
ctx.reset();
// Draw the HTML element at x:0, y:0. The browser syncs the DOM location
// with the drawn location.
ctx.drawElementImage(uiElement, 0, 0);
};
// Handle resizing to match device pixels
const observer = new ResizeObserver(([entry]) => {
const dpc = entry.devicePixelContentBoxSize;
canvas.width = dpc
? dpc[0].inlineSize
: Math.round(entry.contentRect.width * window.devicePixelRatio);
canvas.height = dpc
? dpc[0].blockSize
: Math.round(entry.contentRect.height * window.devicePixelRatio);
canvas.requestPaint();
});
const supportsDevicePixelContentBox =
typeof ResizeObserverEntry !== "undefined" &&
"devicePixelContentBoxSize" in ResizeObserverEntry.prototype;
const options = supportsDevicePixelContentBox
? { box: "device-pixel-content-box" }
: {};
observer.observe(canvas, options);
</script>
WebGL कैनवस
<canvas id="canvas" content="drawable" style="width: 400px; height: 400px;">
<div id="ui-element" drawable>
<p>WebGL UI Element</p>
<button>Action</button>
</div>
</canvas>
<script>
const canvas = document.getElementById("canvas");
const gl = canvas.getContext("webgl2");
const uiElement = document.getElementById("ui-element");
// getElementImageSize(), allocateElementTexture(), and uploadElementWebGL()
// are defined in step 5.
// computeCanvasTransform() is defined in step 6.
// Setup WebGL texture...
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
const textureState = { width: 0, height: 0 };
canvas.onpaint = () => {
// 1. Update texture with HTML content
try {
uploadElementWebGL(gl, canvas, texture, uiElement, textureState);
} catch (err) {
console.error('texElementSubImage2D copy failed:', err);
}
// ... Render your 3D scene here, calculating htmlElementMVP matrix ...
// 2. Sync DOM position, hit testing, and accessibility bounds with 3D scene
canvas.updateElementGeometry(uiElement, {
canvasTransform: computeCanvasTransform(canvas, uiElement, htmlElementMVP),
});
};
</script>
WebGPU Canvas
<canvas id="canvas" content="drawable" style="width: 400px; height: 400px;">
<div id="ui-element" drawable>
<p>WebGPU UI Element</p>
</div>
</canvas>
<script>
const canvas = document.getElementById("canvas");
const context = canvas.getContext("webgpu");
const uiElement = document.getElementById("ui-element");
// getElementImageSize() and ensureElementTexture() are defined in step 5.
// computeCanvasTransform() is defined in step 6.
// Setup WebGPU...
// const device = ...
const textureState = { texture: null };
canvas.onpaint = () => {
// 1. Copy HTML content to a texture that matches the element size
const size = getElementImageSize(canvas, uiElement);
if (size) {
const previousTexture = textureState.texture;
const texture = ensureElementTexture(device, textureState, size.width, size.height);
if (texture !== previousTexture) {
// New texture: create, or rebuild, the bind groups that reference it.
}
try {
device.queue.drawElementImageToTexture({ source: uiElement }, { texture, size });
} catch (err) {
console.error('drawElementImageToTexture copy failed:', err);
}
}
// ... Render your 3D scene here, calculating htmlElementMVP matrix ...
// 2. Sync DOM position, hit testing, and accessibility bounds (same matrix math as WebGL)
canvas.updateElementGeometry(uiElement, {
canvasTransform: computeCanvasTransform(canvas, uiElement, htmlElementMVP),
});
};
</script>
सबसे सही तरीके
- ज़रूरी: HTML-in-Canvas API का इस्तेमाल करने से पहले, यह देख लें कि आपका ब्राउज़र इसके साथ काम करता है या नहीं.
- ज़रूरी:
<canvas>एलिमेंट में हमेशाcontent="drawable"एट्रिब्यूट जोड़ें. - ज़रूरी: ड्रॉ किए जाने वाले हर एलिमेंट में
drawableएट्रिब्यूट जोड़ें. इसमें कैनवस के डायरेक्ट चाइल्ड एलिमेंट भी शामिल हैं. - ज़रूरी: कैनवस पर एचटीएमएल कॉन्टेंट रेंडर करने के लिए,
onpaintइवेंट हैंडलर का इस्तेमाल करें. - ज़रूरी: एचटीएमएल कॉन्टेंट को कैनवस पर रेंडर करने के लिए, 2D में
drawElementImageतरीके का इस्तेमाल करें या WebGPU मेंdrawElementImageToTextureका इस्तेमाल करें. - ज़रूरी: WebGL में,
texImage2D()के साथ टेक्सचर बफ़र को पहले से तय करें. ऐसा सिर्फ़ एक बार करें (जब इसे शुरू किया जाए या एलिमेंट का साइज़ बदला जाए). टेक्सचर को सिर्फ़ तब फिर से असाइन करें, जब साइज़ में बदलाव हो. साथ ही,TEXTURE_MIN_FILTERकोLINEARपर सेट करें. - ज़रूरी: WebGL में, एचटीएमएल कॉन्टेंट को टेक्सचर में रेंडर करने के लिए,
texElementSubImage2Dतरीके का इस्तेमाल करें. इसके लिए, पहले से तय किए गएtexImage2D()का इस्तेमाल करें. इसका साइज़captureElementImage()से तय करें. - ज़रूरी: WebGPU में, टेक्सचर का साइज़
captureElementImage()से तय करें. साथ ही, इसे सिर्फ़ तब फिर से बनाएं, जब साइज़ में बदलाव हो.COPY_DSTऔरRENDER_ATTACHMENTके इस्तेमाल से टेक्सचर बनाएं. साथ ही, टेक्सचर का साइज़sizeके तौर पर पास करें. - ज़रूरी: एचटीएमएल एलिमेंट की ज्यामिति को रेंडर किए गए कॉन्टेंट के साथ सिंक करें. 2D में,
drawElementImageयह काम अपने-आप करता है. WebGL और WebGPU में,canvas.updateElementGeometry(element, { canvasTransform })को कॉल करें. - ज़रूरी: स्क्रीन का साइज़ देखने के लिए,
ResizeObserverका इस्तेमाल करें. साथ ही, कैनवस के साइज़ को डिवाइस के पिक्सल के हिसाब से अपडेट करें. - कैनवस में क्रॉस-ऑरिजिन कॉन्टेंट को एंबेड न करें, क्योंकि यह काम नहीं करता.
ResizeObserverकोonpaintइवेंट हैंडलर में शुरू न करें, क्योंकि इससे मेमोरी लीक हो सकती है.
फ़ॉलबैक रणनीतियां
फ़िलहाल, HTML-in-Canvas API सभी मॉडर्न ब्राउज़र के साथ काम नहीं करता. इसलिए, आम तौर पर फ़ॉलबैक रणनीति की ज़रूरत होती है.
हालांकि, इस एपीआई की बेहतर परफ़ॉर्मेंस को देखते हुए, अगर ब्राउज़र पर HTML-in-Canvas काम करता है, तो इसका इस्तेमाल किया जाना चाहिए.
फ़ॉलबैक की रणनीति, इस्तेमाल के उदाहरण पर निर्भर करती है. उदाहरण के लिए, कैनवस में इंटरैक्टिव एचटीएमएल कॉन्टेंट के लिए, अगर HTML-in-Canvas काम नहीं करता है, तो सीएसएस का इस्तेमाल करके एचटीएमएल कॉन्टेंट को कैनवस के सबसे ऊपर रखें.
HTML-in-Canvas polyfills
HTML-in-Canvas API के साथ काम न करने वाले ब्राउज़र में, इस एपीआई की नकल करने के लिए, यहां दी गई polyfill स्क्रिप्ट का इस्तेमाल करें.
लाइब्रेरी को इंस्टॉल या एंबेड करें:
# Install npm install three-html-render# Embed <script src="https://cdn.jsdelivr.net/npm/three-html-render/dist/polyfill.js"></script>HTML-in-Canvas का अनुवाद करने के लिए,
installHtmlInCanvasPolyfill()तरीका इस्तेमाल करें.