แสดงผล HTML เป็น Canvas 2 มิติ

HTML-in-Canvas API ช่วยให้คุณแสดงผลซับทรี DOM แบบอินเทอร์แอกทีฟที่เข้าถึงได้ในบริบท Canvas 2 มิติโดยตรง อ่านภาพรวมของ HTML-in-Canvas เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับ API และประโยชน์ของ API

คู่มือนี้แสดงวิธีแสดงผล HTML เป็น Canvas 2 มิติ การแสดงผล HTML ใน Canvas 2 มิติต้องทำตามขั้นตอนต่อไปนี้

  1. เตรียมผืนผ้าใบ ตั้งค่าแอตทริบิวต์ที่ถูกต้องอย่างชัดเจนเพื่อให้เบราว์เซอร์ทราบว่าควรแสดงผล HTML เป็น Canvas การตั้งค่านี้เหมือนกันในบริบท 2D, WebGL และ WebGPU ดูวิธีตั้งค่า Canvas และวิธีประกาศองค์ประกอบ HTML ที่จะวาดแยกกัน
  2. วาดรูปภาพองค์ประกอบลงใน Canvas
  3. [ไม่บังคับ] ซิงค์ DOM และพิกเซล

วาดองค์ประกอบ HTML ลงใน Canvas 2 มิติ

เมื่อ Canvas พร้อมและองค์ประกอบได้รับการทำเครื่องหมายเป็น drawable แล้ว ให้แสดงผลองค์ประกอบเหล่านั้นในบริบท 2 มิติโดยใช้เมธอด drawElementImage()

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 บน Canvas
ครอบตัด ขนาดเริ่มต้น (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)

ซิงค์ DOM และพิกเซล

เนื่องจากการแสดงผล <canvas> เป็นสิ่งจำเป็นในขณะที่เลย์เอาต์ DOM และการจัดรูปแบบ CSS เป็นแบบรีแอ็กทีฟ เบราว์เซอร์จึงต้องมีกลไกในการซิงค์พิกเซล Canvas ที่แสดงผล พื้นที่การทดสอบตัวชี้แบบอินเทอร์แอกทีฟ และโครงสร้างการช่วยเหลือพิเศษให้ตรงกัน ก่อนที่จะเรียนรู้วิธีซิงค์ DOM และพิกเซล โปรดทำความเข้าใจเหตุการณ์ paint ที่ทริกเกอร์เมื่อองค์ประกอบ DOM อัปเดตและต้องวาดใหม่

ในบริบท Canvas 2 มิติ เบราว์เซอร์จะซิงค์พิกัดเลย์เอาต์ขององค์ประกอบ ขอบเขตการช่วยเหลือพิเศษ และการทดสอบตัวชี้กับพิกัด Canvas ที่วาดโดยอัตโนมัติ

อัปเดตเรขาคณิตขององค์ประกอบด้วยตนเอง

ในสถานการณ์ขั้นสูง คุณสามารถเลือกไม่ใช้การซิงค์เรขาคณิตอัตโนมัติและควบคุมการเปลี่ยนรูปแบบเชิงพื้นที่ด้วยตนเองได้ ส่ง { 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 });
ในแบบ 2 มิติ drawElementImage() จะอัปเดตเรขาคณิตนี้โดยอัตโนมัติ การสาธิตนี้แสดงให้เห็นว่าเรขาคณิตไม่ซิงค์กันอย่างไรเมื่อตั้งค่า { preserveElementGeometry: true }

ขั้นตอนถัดไป