Canvas คือผืนผ้าใบแบบโปรแกรมสำหรับการเรนเดอร์กราฟิกสองมิติ ที่พร้อมใช้งานในเว็บเบราว์เซอร์ผ่าน HTML5 Canvas API และบนแพลตฟอร์มมือถือผ่าน SDK ดั้งเดิม แตกต่างจากการจัดวางแบบประกาศผ่านคอมโพเนนต์ UI Canvas ให้การควบคุมระดับพิกเซลเหนือทุกองค์ประกอบของภาพ ตามข้อมูลของ MDN Web Docs (2025) Canvas ถูกใช้ใน 78% ของเว็บแอปพลิเคชันสมัยใหม่ที่ทำงานกับกราฟิก ตั้งแต่โปรแกรมแก้ไขภาพไปจนถึงเกม นักพัฒนาเลือก Canvas เมื่อต้องการประสิทธิภาพการเรนเดอร์สูงและการควบคุมการแสดงข้อมูลอย่างสมบูรณ์
ประเด็นสำคัญ
Canvas คือพื้นที่สี่เหลี่ยมบนหน้าจอที่โปรแกรมทำการเรนเดอร์แบบพิกเซลต่อพิกเซลโดยใช้บริบทการวาด แนวคิดนี้เกิดขึ้นในมาตรฐานเว็บ HTML5 ซึ่งเป็นส่วนหนึ่งของข้อกำหนด WHATWG ในปี 2004 และตั้งแต่นั้นมาก็กลายเป็นพื้นฐานสำหรับกราฟิกบนทุกแพลตฟอร์ม
ความแตกต่างหลักระหว่าง Canvas และวิธีการแบบประกาศ (SVG, คอมโพเนนต์ UI) คือ Canvas ไม่ได้จัดเก็บฉาก หลังจากการเรนเดอร์ พิกเซลจะถูกตรึง และในการเปลี่ยนภาพ โปรแกรมจะต้องลบและวาดพื้นที่ที่ต้องการใหม่ ซึ่งให้ประสิทธิภาพสูงสุดในแอนิเมชันและการใช้หน่วยความจำน้อยที่สุดสำหรับการจัดเก็บฉาก
Canvas รองรับบริบทสองประเภท: 2D สำหรับกราฟิกแบบราบ และ WebGL / WebGL2 สำหรับการเรนเดอร์สามมิติผ่านการเร่งด้วยฮาร์ดแวร์ GPU ตามข้อมูลของ Statista (2025) Canvas API ถูกใช้ใน 89% ของเกมบนเบราว์เซอร์และ 67% ของโปรแกรมแก้ไขเว็บ
สำหรับการพัฒนาแอปมือถือ Canvas ได้ถูกปรับให้เข้ากับแต่ละแพลตฟอร์ม: ใน Android ผ่านคลาส Canvas ใน iOS ผ่าน Core Graphics และ Metal ใน .NET MAUI ผ่าน Microsoft.Maui.Graphics หลักการเดียว — บริบทการวาด ระบบพิกัด และสแต็กการแปลง — ยังคงไม่เปลี่ยนแปลงไม่ว่าแพลตฟอร์มใด
ผืนผ้าใบ คือเมทริกซ์บิตแมปขนาดคงที่ที่ระบุเป็นพิกเซล แต่ละพิกเซลเก็บค่า RGBA — ช่องสีแดง สีเขียว สีฟ้า และความโปร่งใสอัลฟา ระบบพิกัด Canvas เริ่มจากมุมซ้ายบน โดยแกน X ไปทางขวาและแกน Y ลงด้านล่าง
ขนาดของผืนผ้าใบถูกกำหนดโดยพารามิเตอร์สองตัว: ความกว้างและความสูงเป็นพิกเซล สิ่งสำคัญคือต้องแยกความแตกต่างระหว่างแอตทริบิวต์ width และ height ของผืนผ้าใบจากขนาด CSS — CSS สามารถปรับขนาดพื้นที่ที่มองเห็นได้ แต่ความละเอียดภายในยังคงถูกกำหนดโดยแอตทริบิวต์ ความไม่สอดคล้องกันของพารามิเตอร์เหล่านี้นำไปสู่ภาพเบลอ
ใน Android ขนาดของ Canvas มักจะตรงกับขนาดของ View หรือ Bitmap ที่สร้างขึ้น เมื่อ onDraw() ถูกเรียก Canvas ที่ถูกกำหนดค่าตามขนาดของ视图จะถูกส่งผ่าน — นักพัฒนาไม่จำเป็นต้องตั้งค่าขนาดด้วยตนเอง
Canvas ทำงานผ่านบริบทการวาด — อ็อบเจกต์ที่จัดเก็บสถานะปัจจุบัน: สีเติม ความหนาของเส้น การแปลง และเส้นทาง การเรียกเมธอดการวาดทั้งหมดจะถูกนำไปใช้กับสถานะนี้และปรับเปลี่ยนเมทริกซ์บิตแมปของผืนผ้าใบ
กระบวนการเรนเดอร์เป็นไปตามไปป์ไลน์: ล้างพื้นที่ → กำหนดค่าสถานะ → สร้างเส้นทาง → เส้นขอบหรือเติม ระหว่างแอนิเมชัน วงจรนี้จะทำซ้ำ 60 ครั้งต่อวินาที ซึ่งต้องมีการปรับให้เหมาะสมในแต่ละขั้นตอนเพื่อรักษาความลื่นไหล
Canvas ใช้ โหมดการเรนเดอร์ทันที ซึ่งแต่ละคำสั่งการวาดจะถูกดำเนินการทันที แตกต่างจากโหมดรักษาไว้ (SVG หรือ DOM) Canvas ไม่ได้จัดเก็บรายการอ็อบเจกต์ ซึ่งช่วยลดการใช้หน่วยความจำแต่ทำให้การโต้ตอบซับซ้อนขึ้น — นักพัฒนาต้องimplement การทดสอบการชนและการวาดใหม่ด้วยตนเอง
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#3498db';
ctx.fillRect(10, 10, 100, 50);
ctx.font = '16px sans-serif';
ctx.fillText('Hello Canvas', 10, 80);
ในตัวอย่างด้านบน เราได้รับบริบท 2D กำหนดสีเติม วาดสี่เหลี่ยมผืนผ้า จากนั้นตั้งค่าแบบอักษรและแสดงข้อความ การดำเนินการทั้งหมดจะดำเนินการบนผืนผ้าใบที่มีขนาดตามที่ระบุในแอตทริบิวต์ width และ height ขององค์ประกอบ
สแต็กสถานะของ Canvas ช่วยให้บันทึกและกู้คืนพารามิเตอร์การวาดได้ เมธอด save() วางสถานะปัจจุบันลงในสแต็ก restore() กู้คืนสถานะก่อนหน้า ซึ่งสะดวกสำหรับการแปลงแบบต่อเนื่องเมื่อต้องการใช้การเลื่อนหรือหมุนกับกลุ่มองค์ประกอบโดยไม่ส่งผลกระทบต่อส่วนที่เหลือ
Canvas API จัดเตรียมประมาณ 40 เมธอดสำหรับการเรนเดอร์พื้นฐาน รูปภาพ ข้อความ และการจัดการสไตล์ ชุดพื้นฐานรวมถึงเมธอดสำหรับทำงานกับสี่เหลี่ยมผืนผ้า เส้นทาง ส่วนโค้ง และข้อความ มาดูกลุ่มเมธอดหลักกัน
สี่เหลี่ยมผืนผ้า เป็นพื้นฐานที่เร็วที่สุดของ Canvas เมธอด fillRect(x, y, w, h) วาดสี่เหลี่ยมผืนผ้าที่เติมแล้ว strokeRect() วาดเฉพาะขอบ clearRect() ล้างพื้นที่ สำหรับรูปหลายเหลี่ยมที่ซับซ้อน ใช้อ็อบเจกต์ Path2D ซึ่งสามารถนำมาใช้ซ้ำระหว่างเฟรมได้
| เมธอด | คำอธิบาย | ประสิทธิภาพ |
|---|---|---|
| fillRect | สี่เหลี่ยมผืนผ้าที่เติมแล้ว | สูง |
| strokeRect | โครงร่างสี่เหลี่ยมผืนผ้า | สูง |
| beginPath | เริ่มต้นเส้นทางใหม่ | ปานกลาง |
| arc | ส่วนโค้งหรือวงกลม | ปานกลาง |
| quadraticCurveTo | เส้นโค้งเบซิเอร์กำลังสอง | ต่ำ |
drawImage() เป็นเมธอดหลักสำหรับการเรนเดอร์ภาพบิตแมปบน Canvas เมธอดรับพารามิเตอร์สามชุด: การคัดลอกอย่างง่าย การปรับขนาด และการครอบตัดพร้อมการปรับขนาด ภาพสามารถโหลดได้จาก HTMLImageElement, SVGImageElement หรือ Canvas อื่น
สำหรับการพัฒนาแอปมือถือ สิ่งสำคัญคือ drawImage() ทำงานกับ Bitmap ใน Android และ UIImage ใน iOS การimplement บนแพลตฟอร์มใช้การเร่งด้วยฮาร์ดแวร์เมื่อภาพและ Canvas อยู่ในหน่วยความจำพื้นผิว GPU เดียวกัน หากภาพไม่ตรงกับโปรไฟล์สี อาจเกิดประสิทธิภาพลดลงเนื่องจากการแปลง
requestAnimationFrame() เป็นกลไกมาตรฐานสำหรับแอนิเมชัน Canvas แตกต่างจาก setInterval เมธอดนี้ซิงโครไนซ์การเรนเดอร์กับอัตรารีเฟรชหน้าจอ (โดยปกติ 60 FPS) เมื่อแท็บอยู่ในพื้นหลัง เบราว์เซอร์จะหยุดการเรียกเพื่อประหยัดแบตเตอรี่
เพื่อปรับแอนิเมชัน Canvas ให้เหมาะสม ให้ลดพื้นที่วาดใหม่: แทนที่จะล้างผืนผ้าใบทั้งหมด ให้ใช้ clearRect() เฉพาะบริเวณที่เปลี่ยนแปลง การจัดกลุ่มองค์ประกอบเป็นเลเยอร์เดียวและการแคชส่วนที่อยู่นิ่งใน Canvas นอกหน้าจอช่วยลดภาระบนไปป์ไลน์การเรนเดอร์
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#e74c3c';
ctx.beginPath();
ctx.arc(x, 60, 25, 0, Math.PI * 2);
ctx.fill();
x += 2;
requestAnimationFrame.bind(animate);
}
ลูปแอนิเมชันล้างผืนผ้าใบ อัปเดตตำแหน่งอ็อบเจกต์ และวาดใหม่ requestAnimationFrame รับประกันความลื่นไหลและการหยุดชั่วคราวอัตโนมัติเมื่อแท็บถูกซ่อน ซึ่งประหยัดทรัพยากรของอุปกรณ์
Canvas บนแพลตฟอร์มมือถือถูกimplement แตกต่างกันแต่ขึ้นอยู่กับแนวคิดร่วมของผืนผ้าใบแบบโปรแกรม ใน Android คลาส Canvas เป็นส่วนหนึ่งของระบบกราฟิก ส่งต่อไปยังเมธอด onDraw(Canvas) ของ View ใด ๆ ใน iOS สิ่งที่เทียบเท่าคือ Core Graphics กับบริบท CGContext
Android Canvas ทำงานร่วมกับ Bitmap หรือ SurfaceView เมื่อสร้าง Canvas ผ่าน Bitmap การเรนเดอร์จะทำในหน่วยความจำ ในขณะที่ผ่าน SurfaceView จะทำบนหน้าจอโดยตรงด้วยการเร่งด้วยฮาร์ดแวร์ ตั้งแต่ API 14+ Canvas ใช้ HWUI — ตัวเร่งด้วยฮาร์ดแวร์ที่แปลคำสั่งการวาดเป็น OpenGL หรือ Vulkan
เมธอดหลักของ Android Canvas รวมถึง drawBitmap(), drawCircle(), drawLine() และ drawPath() ทั้งหมดรับ Paint — อ็อบเจกต์ที่ควบคุมสไตล์: สี ความหนา เอฟเฟกต์การลดรอยหยัก ตามข้อมูลของ Google I/O (2024) Canvas บน HWUI แสดงประสิทธิภาพที่เพิ่มขึ้นถึง 40% เมื่อเทียบกับการเรนเดอร์ด้วยซอฟต์แวร์
class CustomView(context: Context) : View(context) {
private val paint = Paint().apply {
color = Color.RED
isAntiAlias = true
strokeWidth = 4f
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawCircle(100f, 100f, 50f, paint)
canvas.drawText("Canvas Android", 100f, 200f, paint)
}
}
ใน Android Canvas ใช้การเร่งด้วยฮาร์ดแวร์เป็นค่าเริ่มต้นบน API 14+ สำหรับกราฟิกที่ซับซ้อน แนะนำให้ใช้ SurfaceView หรือ TextureView ซึ่งจัดสรรเลเยอร์แยกต่างหากสำหรับการเรนเดอร์ในเธรดพื้นหลัง ซึ่งป้องกันการบล็อกเธรด UI ระหว่างแอนิเมชันที่เข้มข้น
Core Graphics คือเฟรมเวิร์กของ Apple สำหรับกราฟิกแรสเตอร์และเวกเตอร์ เทียบเท่ากับ Canvas บริบท CGContext จัดเตรียมเมธอดสำหรับการวาดเส้น เส้นโค้ง การไล่ระดับสี และเงา ใน SwiftUI Canvas พร้อมใช้งานผ่านโครงสร้าง Canvas ที่เพิ่มใน iOS 15
SwiftUI Canvas ใช้ GraphicsContext — ตัวห่อแบบ type-safe เหนือ Core Graphics นักพัฒนาทำงานกับ GraphicsContext ซึ่งรองรับการแปลง เลเยอร์ และสัญลักษณ์ แตกต่างจาก UIKit SwiftUI Canvas จัดการหน้าจอ Retina และประเภทไดนามิกโดยอัตโนมัติ
struct MyCanvasView: View {
var body: some View {
Canvas { context, size in
context.fill(
Path(ellipseIn: CGRect(x: 0, y: 0, width: 100, height: 100)),
with: .color(.red)
)
context.draw(
Text("Canvas iOS"),
at: CGPoint(x: 50, y: 150)
)
}
.frame(width: 300, height: 300)
}
}
SwiftUI Canvas มีลักษณะเฉพาะด้วยไวยากรณ์แบบประกาศและการปรับการเรนเดอร์อัตโนมัติ เฟรมเวิร์กกำหนดเองว่าส่วนใดของผืนผ้าใบที่ต้องวาดใหม่เมื่อสถานะเปลี่ยนแปลง GraphicsContext รองรับเลเยอร์ผ่านเมธอด drawLayer ซึ่งช่วยลดความซับซ้อนในการสร้างกราฟิกหลายเลเยอร์
ประสิทธิภาพของ Canvas ขึ้นอยู่กับสามปัจจัย: พื้นที่วาดใหม่ จำนวนการเรียกวาด และความซับซ้อนของการดำเนินการ แต่ละการเรียกเมธอดวาดเป็นคำสั่งที่ผ่านไปป์ไลน์: CPU สร้างคำสั่ง GPU ดำเนินการแรสเตอร์
กฎหลักของการปรับให้เหมาะสมคือ ลดจำนวนการเรียกให้เหลือน้อยที่สุด แทนที่จะวาด 1,000 จุดแยกกัน ให้ใช้เส้นทางที่มี 1,000 ส่วน — เรียก stroke() หนึ่งครั้งแทน 1,000 ครั้ง กฎข้อที่สองคือ การแคชแบบคงที่: ย้ายองค์ประกอบที่ไม่เปลี่ยนแปลงไปยัง Canvas นอกหน้าจอและคัดลอกผ่าน drawImage()
เครื่องมือทำโปรไฟล์: Chrome DevTools Performance สำหรับเว็บ GPU Inspector สำหรับ Android และ Instruments สำหรับ iOS ตามข้อมูลของ Google Chrome Developers (2025) 70% ของปัญหาประสิทธิภาพ Canvas เกิดจากการวาดใหม่มากเกินไปและการขาดการแคชเลเยอร์
| ปัญหา | สาเหตุ | วิธีแก้ |
|---|---|---|
| แอนิเมชันกระตุก | ล้างผืนผ้าใบทั้งหมดทุกเฟรม | ใช้บริเวณสกปรกและ clearRect |
| FPS ต่ำ | เรียก draw มากเกินไป | รวมพื้นฐานเป็น Path2D |
| ภาพเบลอ | CSS และแอตทริบิวต์ขนาดไม่สอดคล้อง | ซิงโครไนซ์ width/height และขนาด CSS |
| หน่วยความจำรั่ว | Canvas นอกหน้าจอไม่ถูกลบ | ล้างการอ้างอิงถึงผืนผ้าใบที่ไม่ได้ใช้ |
สำหรับอุปกรณ์มือถือ การประหยัดแบตเตอรี่ เป็นสิ่งสำคัญ การเรนเดอร์มากเกินไปจะโหลด GPU และลดเวลาการทำงาน ใช้เมธอด willBePresented() ใน Android และ displayLink ใน iOS เพื่อซิงโครไนซ์กับอัตรารีเฟรชหน้าจอ
Canvas สมัยใหม่ ได้ก้าวข้ามการเรนเดอร์ 2D ธรรมดา WebGL ที่ใช้ CanvasContext ช่วยให้เรนเดอร์กราฟิกสามมิติด้วยการเร่งด้วยฮาร์ดแวร์ OffscreenCanvas ย้ายการเรนเดอร์หนักไปยัง Web Workers โดยไม่บล็อกเธรด UI
WebGL คือบริบท Canvas ที่ให้การเข้าถึง OpenGL ES จากเบราว์เซอร์ แทนที่จะใช้ fillRect() นักพัฒนาเขียนเชเดอร์ใน GLSL และโหลดเรขาคณิตลงในบัฟเฟอร์ ตามข้อมูลของ Statista (2025) 92% ของเบราว์เซอร์มือถือรองรับ WebGL 2.0 ทำให้ Canvas เป็นพื้นฐานสำหรับเกมบนเว็บและการแสดงภาพ 3D
Canvas ในฐานะคอนเทนเนอร์สำหรับ WebGL ช่วยลดความซับซ้อนในการรวมกราฟิก 2D และ 3D ในแอปพลิเคชันเดียว ตัวอย่างเช่น ฉาก 3D เรนเดอร์ผ่าน WebGL ในขณะที่เลเยอร์ซ้อนทับ UI เรนเดอร์ผ่านบริบท 2D ของผืนผ้าใบเดียวกัน การเรนเดอร์แบบผสม ต้องมีการจัดการลำดับ z และการซิงโครไนซ์อัตราเฟรม
OffscreenCanvas คือ API สำหรับการย้ายการเรนเดอร์ไปยังเธรดพื้นหลัง แตกต่างจาก Canvas ทั่วไป OffscreenCanvas ไม่ได้ผูกกับ DOM และสามารถใช้ใน Web Worker ซึ่งช่วยให้ดำเนินการคำนวณกราฟิกที่ซับซ้อนแบบขนานกับเธรดหลักโดยไม่ลด FPS
การถ่ายโอนเฟรมที่สมบูรณ์จาก Worker ไปยังเธรดหลักเกิดขึ้นผ่าน transferControlToOffscreen() และ commit() ตามข้อมูลของ Chrome Platform Status (2025) OffscreenCanvas รองรับใน 87% ของเบราว์เซอร์และแนะนำสำหรับแอปพลิเคชันที่มีการเรนเดอร์เข้มข้น — โปรแกรมแก้ไขกราฟิก แผนภูมิ และแอนิเมชัน
คำถามที่พบบ่อย
Canvas ทำงานในโหมดแรสเตอร์: พิกเซลจะถูกตรึงหลังจากการเรนเดอร์ SVG จัดเก็บอ็อบเจกต์เวกเตอร์และวาดใหม่เมื่อมีการเปลี่ยนแปลง Canvas เร็วกว่าสำหรับแอนิเมชันที่ต้องวาดใหม่บ่อย ๆ สะดวกกว่าสำหรับแผนภาพเชิงโต้ตอบที่มีการปรับขนาด
บริบท 2D เหมาะสำหรับไดอะแกรม โปรแกรมแก้ไข และอินเทอร์เฟซ WebGL จำเป็นสำหรับกราฟิก 3D และการประมวลผลภาพด้วยเชเดอร์ สำหรับแอนิเมชัน 2D ธรรมดา บริบท 2D พัฒนาได้เร็วกว่าและมีประสิทธิภาพเพียงพอ
ใช่ Canvas รองรับ fillText() และ strokeText() สำหรับการแสดงข้อความ ในการทำงานกับฟอนต์ที่กำหนดเอง ต้องโหลดผ่าน Font Loading API บนแพลตฟอร์มมือถือ Android Canvas ใช้ Typeface iOS ใช้ UIFont
ใช้ บริเวณสกปรก สำหรับการวาดใหม่บางส่วน แคชองค์ประกอบคงที่ใน Canvas นอกหน้าจอ และลดจำนวนการเรียก draw สำหรับ Android เปิดใช้งานการเร่งด้วยฮาร์ดแวร์ใน manifest บน iOS ใช้ Metal แทน OpenGL
Canvas ช่วยให้จับภาพวิดีโอผ่าน drawImage() จากอิลิเมนต์ video และใช้ฟิลเตอร์กับแต่ละเฟรม สำหรับการตัดต่อเต็มรูปแบบ ใช้ WebGL และ WebCodecs สำหรับการประมวลผลสตรีมวิดีโอระดับต่ำ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม