एचटीएमएल को 2D कैनवस में रेंडर करना

HTML-in-Canvas API की मदद से, इंटरैक्टिव और सुलभ डीओएम सबट्री को सीधे 2D कैनवस कॉन्टेक्स्ट में रेंडर किया जा सकता है. एपीआई और इसके फ़ायदों के बारे में ज़्यादा जानने के लिए, HTML-in-Canvas के बारे में खास जानकारी पढ़ें.

इस गाइड में, एचटीएमएल को 2D कैनवस में रेंडर करने का तरीका बताया गया है. 2D कैनवस में एचटीएमएल रेंडर करने के लिए, यह तरीका अपनाना होगा:

  1. अपना कैनवस तैयार करें. सही एट्रिब्यूट को डिक्लेयर करके सेट करें, ताकि ब्राउज़र को पता चल सके कि उसे एचटीएमएल को कैनवस में रेंडर करना है. यह सेटअप 2D, WebGL, और WebGPU कॉन्टेक्स्ट में एक जैसा होता है. कैनवस सेट अप करने और एचटीएमएल एलिमेंट को अलग-अलग ड्रॉ करने के लिए एलान करने का तरीका जानें.
  2. कैनवस में एलिमेंट की इमेज बनाएं.
  3. [ज़रूरी नहीं] डीओएम और पिक्सल को सिंक करें.

एचटीएमएल एलिमेंट को 2D कैनवस में ड्रॉ करना

कैनवस तैयार होने और एलिमेंट को drawable के तौर पर मार्क करने के बाद, drawElementImage() तरीके का इस्तेमाल करके उन्हें 2D कॉन्टेक्स्ट में रेंडर करें.

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const childElement1 = document.getElementById("childElement1");
const childElement2 = document.getElementById("childElement2");

canvas.onpaint = () => {
  ctx.reset();
  // 1. Draw the primary element at coordinate (20, 20)
  ctx.drawElementImage(childElement1, 20, 20);
  // 2. Draw the secondary nested button at a custom offset
  ctx.drawElementImage(childElement2, 40, 90);
}

drawElementImage() में 3-आर्ग्युमेंट, 5-आर्ग्युमेंट, 7-आर्ग्युमेंट, और 9-आर्ग्युमेंट वाले फ़ॉर्म इस्तेमाल किए जा सकते हैं. साथ ही, इसमें options पैरामीटर को भी इस्तेमाल किया जा सकता है. हालांकि, यह ज़रूरी नहीं है:

// 1. Basic position: (element, dx, dy, options?)
ctx.drawElementImage(targetElement, 100, 150);

// 2. Scaled / resized: (element, dx, dy, dWidth, dHeight, options?)
ctx.drawElementImage(targetElement, 100, 150, 180, 60);

// 3. Cropped, default size: (element, sx, sy, swidth, sheight, dx, dy, options?)
ctx.drawElementImage(targetElement, 0, 0, 90, 30, 100, 150);

// 4. Cropped and resized: (element, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight, options?)
ctx.drawElementImage(targetElement, 0, 0, 90, 30, 100, 150, 180, 60);
ओवरलोड फ़ॉर्म पैरामीटर लेआउट इफ़ेक्ट
डिफ़ॉल्ट साइज़ (element, dx, dy) पूरा एलिमेंट अपने डिफ़ॉल्ट साइज़ में, सबसे ऊपर बाएं कोने में (dx, dy) पर.
कस्टम डेस्टिनेशन बॉक्स (element, dx, dy, dwidth, dheight) यह पूरे एलिमेंट की इमेज को कैनवस पर dw × dh व्यूपोर्ट में स्केल करता है.
क्रॉप किया गया, डिफ़ॉल्ट साइज़ (element, sx, sy, swidth, sheight, dx, dy) सिर्फ़ swidth × sheight एरिया, जो (sx, sy) से शुरू होता है. इसे उस एरिया के डिफ़ॉल्ट साइज़ पर ड्रॉ किया जाता है. यह डिफ़ॉल्ट साइज़ वाले फ़ॉर्म के स्केल के बराबर होता है.
सोर्स स्लाइस से डेस्टिनेशन तक (element, sx, sy, swidth, sheight, dx, dy, dwidth, dheight) यह (sx, sy) से शुरू होने वाले सोर्स एलिमेंट को swidth × sheight डाइमेंशन के साथ काटता है. इसके बाद, उसे डेस्टिनेशन (dx, dy, dwidth, dheight) पर मैप करता है.

डीओएम और पिक्सल को सिंक करना

<canvas> रेंडरिंग ज़रूरी है, जबकि डीओएम लेआउट और सीएसएस स्टाइलिंग प्रतिक्रियाशील हैं. इसलिए, ब्राउज़र को रेंडर किए गए कैनवस पिक्सल, इंटरैक्टिव हिट-टेस्ट क्षेत्रों, और सुलभता ट्री को सिंक में रखने के लिए एक तरीके की ज़रूरत होती है. डीओएम और पिक्सल को सिंक करने का तरीका जानने से पहले, पक्का करें कि आपको paint इवेंट के बारे में पता हो. यह इवेंट तब ट्रिगर होता है, जब डीओएम एलिमेंट अपडेट होते हैं और उन्हें फिर से ड्रॉ करने की ज़रूरत होती है.

2D कैनवस कॉन्टेक्स्ट में, ब्राउज़र एलिमेंट के लेआउट कोऑर्डिनेट, सुलभता की सीमाओं, और पॉइंटर हिट-टेस्टिंग को ड्रॉ किए गए कैनवस कोऑर्डिनेट के साथ अपने-आप सिंक करता है.

एलिमेंट की ज्यामिति को मैन्युअल तरीके से अपडेट करना

ऐडवांस मामलों में, ज्यामिति के अपने-आप सिंक होने की सुविधा से ऑप्ट आउट किया जा सकता है. साथ ही, स्पेशल ट्रांसफ़ॉर्म को मैन्युअल तरीके से कंट्रोल किया जा सकता है. ब्राउज़र को एलिमेंट के मौजूदा हिट-टेस्ट निर्देशांकों को अपने-आप बदलने से रोकने के लिए, { preserveElementGeometry: true } को drawElementImage() पर पास करें:

// 1. Draw the element without altering its existing hit-test bounds
ctx.drawElementImage(targetElement, elementX, 200, { preserveElementGeometry: true });

// 2. Construct a custom transform matrix as needed,
// assuming scaleX/scaleY = canvas grid pixels per CSS pixel,
// from your resize observer (see "Units and sizing").
const currentTransform = new DOMMatrix();
currentTransform.a = 1.5;          // scale X
currentTransform.e = x / scaleX;   // translate X: grid px → CSS px
currentTransform.f = y / scaleY;   // translate Y: grid px → CSS px

// 3. Explicitly apply the custom transform
canvas.updateElementGeometry(targetElement, { canvasTransform: currentTransform });
2D में, drawElementImage() इस ज्यामिति को अपने-आप अपडेट करता है. इस डेमो में दिखाया गया है कि { preserveElementGeometry: true } सेट होने पर, ज्यामिति कैसे सिंक नहीं होती.

अगले चरण