HTML-in-Canvas API ช่วยให้คุณแสดงผลซับทรี DOM แบบอินเทอร์แอกทีฟที่เข้าถึงได้ในบริบท Canvas 2 มิติโดยตรง อ่านภาพรวมของ HTML-in-Canvas เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับ API และประโยชน์ของ API
คู่มือนี้แสดงวิธีแสดงผล HTML เป็น Canvas 2 มิติ การแสดงผล HTML ใน Canvas 2 มิติต้องทำตามขั้นตอนต่อไปนี้
- เตรียมผืนผ้าใบ ตั้งค่าแอตทริบิวต์ที่ถูกต้องอย่างชัดเจนเพื่อให้เบราว์เซอร์ทราบว่าควรแสดงผล HTML เป็น Canvas การตั้งค่านี้เหมือนกันในบริบท 2D, WebGL และ WebGPU ดูวิธีตั้งค่า Canvas และวิธีประกาศองค์ประกอบ HTML ที่จะวาดแยกกัน
- วาดรูปภาพองค์ประกอบลงใน Canvas
- [ไม่บังคับ] ซิงค์ 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 });
drawElementImage() จะอัปเดตเรขาคณิตนี้โดยอัตโนมัติ การสาธิตนี้แสดงให้เห็นว่าเรขาคณิตไม่ซิงค์กันอย่างไรเมื่อตั้งค่า { preserveElementGeometry: true }ขั้นตอนถัดไป
- ทำความเข้าใจแนวคิดทางเทคนิคหลักเบื้องหลัง HTML-in-Canvas
- ดูวิธีแสดงผล HTML ใน WebGL Canvas
- ดูวิธีแสดงผล HTML ใน WebGPU Canvas
- ดูข้อมูลเกี่ยวกับกลยุทธ์สำรอง
- แจ้งปัญหาใน GitHub เพื่อแชร์ความคิดเห็น
- ดูคอลเล็กชันเดโม HTML-in-Canvas โดยชุมชน