PublishedAt

WebDev

มารู้จักกับ HTML5 Canvas กันดีกว่า

มารู้จักกับ HTML5 Canvas กันดีกว่า

สวัสดีครับ มาเรียนรู้พื้นฐานของ HTML5 Canvas กันดีกว่า โดยเนื้อหานี้จะอธิบายถึง Canvas วิธีใช้งาน และตัวอย่างการใช้งาน เพื่อต่อยอดไปเขียนเกม ในบทถัดไปครับ

HTML5 Canvas คืออะไร?

Canvas คือ HTML element ที่ เปรียบเสมือนกับกระดานวาดภาพ ที่เราสามารถวาดภาพ โดยใช้ JavaScript เพื่อเขียนโค้ดเพื่อวาดภาพ หรือสร้าง animation ได้

เราสามารถสร้าง canvas ได้ด้วยการใช้ HTML <canvas> กำหนดขนาดของ canvas โดยใช้ attribute width และ height (ขนาด default คือกว้าง 300x150 px) ดังนี้

<canvas id="myCanvas" width="500" height="500">
เบราว์เซอร์ของคุณไม่รองรับ Canvas กรุณาอัปเดตเบราว์เซอร์
</canvas>

การใช้งาน canvas และ context

const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')

ตัวอย่างการวาดสี่เหลี่ยมสีแดงลงบน canvas

ctx.fillStyle = 'red'
ctx.fillRect(10, 10, 100, 100)

ระบบพิกัดของ Canvas

Canvas มีระบบพิกัดที่เริ่มต้นจากจุด (0, 0) ซึ่งอยู่ที่มุมซ้ายบนของ canvas ระบบพิกัดนี้มีแกน x และแกน y ที่แบ่ง canvas เป็น 4 ด้าน

  • จุดเริ่มต้น : (0, 0) มุมซ้ายบน
  • แกน x : เพิ่มขึ้นไปทางขวา
  • แกน y : เพิ่มขึ้นไปทางล่าง

Canvas Coordinate System

Drawing

ด้านบนเราเห็นตัวอย่างการวาดสีเหลี่ยมกันไปแล้ว เรามาทำความเข้าใจเพิ่มกันดีกว่า

วาดสี่เหลี่ยม rectangles

จะมีด้วยกัน 3 แบบคือ

  1. fillRect(x, y, width, height) - วาดสี่เหลี่ยมที่มีสีพื้นหลัง
  2. strokeRect(x, y, width, height) - วาดสี่เหลี่ยมที่มีเส้นขอบ
  3. clearRect(x, y, width, height) - ล้างสี่เหลี่ยม

เป็นการวาดสี่เหลี่ยมที่มีสีพื้นหลัง ลงไปใน canvas โดยใช้ค่า x, y ในการระบุตำแหน่งมุมซ้ายบนของสี่เหลี่ยม และค่า width, height ในการระบุขนาดของสี่เหลี่ยม ตัวอย่างด้านล่างคือ

  • วาดสี่เหลี่ยมที่ตำแหน่ง x = 10, y = 10
  • มีขนาด width = 100, height = 100
ctx.fillStyle = 'red'
ctx.fillRect(10, 10, 100, 100)

ต่อมา strokeRect(x, y, width, height) - วาดสี่เหลี่ยมที่มีเส้นขอบ (อันนี้วาดเส้น ไม่ได้ระบายถมทับทั่งสี่เลี่ยมนะครับ)

ctx.strokeStyle = 'blue'
ctx.strokeRect(10, 10, 100, 100)

สุดท้าย clearRect(x, y, width, height) - ล้างสี่เหลี่ยม เอาไว้ลบ สี่เหลี่ยม เหมือนคล้ายๆ ยางลบใน Paint ส่วนใหญ่ เอาไว้ clear canvas

ctx.clearRect(10, 10, 100, 100)

วาดเส้น paths

paths คือการวาดเส้นที่มีเส้นขอบ แต่ไม่มีพื้นหลัง เริ่มต้นด้วย beginPath ตามด้วย moveTo(x, y) และ lineTo(x, y) ตามด้วย stroke() เพื่อวาดเส้น เช่น

ctx.beginPath()
ctx.moveTo(10, 10)
ctx.lineTo(100, 100)
ctx.stroke() // หรือ ctx.fill()

วาดวงกลม

ใช้ arc(x, y, radius, startAngle, endAngle) เพื่อวาดวงกลม

  • Math.PI คือ 180 องศา
  • Math.PI * 2 คือ 360 องศา
ctx.beginPath()
ctx.arc(50, 50, 30, 0, Math.PI * 2)
ctx.stroke()

วาดเส้น Line

ใช้ lineTo(x, y) เพื่อวาดเส้นตรง เริ่มต้นต้น beginPath() และจบด้วย stroke() หรือ fill() ตามที่ต้องการ

ctx.beginPath()
ctx.moveTo(10, 10)
ctx.lineTo(100, 100)
ctx.stroke()

ตัวอย่าง Canvas ทั้งหมด

ctx = canvas.getContext('2d')
// 1. สี่เหลี่ยม (เต็ม)
ctx.fillStyle = '#f00'
ctx.fillRect(50, 50, 100, 80)
// 2. สี่เหลี่ยม (ขอบเท่านั้น)
ctx.strokeStyle = '#0f0'
ctx.lineWidth = 3
ctx.strokeRect(200, 50, 100, 80)
// 3. วงกลม
ctx.fillStyle = '#2ecc71'
ctx.beginPath()
ctx.arc(400, 90, 40, 0, Math.PI * 2)
ctx.fill()
// 4. เส้น
ctx.strokeStyle = '34df50'
ctx.lineWidth = 5
ctx.beginPath()
ctx.moveTo(50, 200)
ctx.lineTo(200, 250)
ctx.stroke()
// 5. ตัวหนังสือ
ctx.fillStyle = '#00f'
ctx.font = '24px Arial'
ctx.textAlign = 'left'
ctx.fillText('Ahoy!', 250, 230)
This is canvas

ตัวอย่างข้อผิดพลาดที่มักพบบ่อยๆ

ลืมล้าง Canvas

// ❌ ผิด - รูปทรงจะซ้อนทับกัน
function draw() {
ctx.fillRect(x, y, 50, 50)
}
// ✅ ถูก - ล้างก่อนวาดใหม่
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.fillRect(x, y, 50, 50)
}

ลืมปิด Path

// ❌ ผิด - อาจได้ผลการวาดที่ไม่คาดคิด
ctx.beginPath()
ctx.arc(100, 100, 50, 0, Math.PI * 2)
ctx.fill()
ctx.arc(200, 100, 50, 0, Math.PI * 2) // ยังคงอยู่ใน path เดิม!
ctx.fill()
// ✅ ถูก - แต่ละรูปทรงมี path ของตัวเอง
ctx.beginPath()
ctx.arc(100, 100, 50, 0, Math.PI * 2)
ctx.fill()
ctx.beginPath()
ctx.arc(200, 100, 50, 0, Math.PI * 2)
ctx.fill()

Basic animations

การที่จะบังคับ animation เราสามารถทำได้หลักๆ คือ ใช้

  • setInterval()
  • setTimeout()
  • requestAnimationFrame()

ตัวอย่างการใช้ setInterval() เพื่อให้รูปทรงขยับไปทางขวา

let x = 0
// ทุกๆ 100 มิลลิวินาที เลื่อนไปทางขวา 5 หน่วย (pixel)
setInterval(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.fillRect(x, 100, 50, 50)
x += 5
}, 100)

ตัวอย่าง setTimeout() เพื่อให้รูปทรงขยับไปทางขวา

let x = 0
// ทุกๆ 100 มิลลิวินาที เลื่อนไปทางขวา 5 หน่วย (pixel)
setTimeout(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.fillRect(x, 100, 50, 50)
x += 5
}, 100)

ตัวอย่าง requestAnimationFrame() เพื่อให้รูปทรงขยับไปทางขวา

let x = 0
// ทุกเฟรม เลื่อนไปทางขวา 5 หน่วย (pixel)
requestAnimationFrame(() => {
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.fillRect(x, 100, 50, 50)
x += 5
})

ปกติ เราจะสร้าง function เพื่อเอาไว้ reuse ในการเคลื่อนที่รูปทรง

function moveRight() {
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.fillRect(x, 100, 50, 50)
x += 5
if (x > canvas.width) {
x = 0
}
requestAnimationFrame(moveRight)
}
moveRight()
This is canvas

สรุป

ตัวอย่างบทความนี้เป็นตัวอย่างการใช้ Canvas ในการวาดภาพ และใช้ requestAnimationFrame() เพื่อทำ animation ให้รูปภาพขยับไปในทิศทาง ต่างๆ ที่เราต้องการ โดยใช้ แนวแกน x, y

หวังว่าบทความนี้จะช่วยให้คุณเข้าใจการใช้ Canvas ในการวาดภาพ และทำ animation ได้ดีขึ้น แล้วเดี๋ยวบทความต่อไป ลองมาทำเกมง่ายๆ ด้วย HTML5 Canvas กันครับ

Happy Coding ❤️

Authors
avatar

Chai Phonbopit

เป็น Web Dev ในบริษัทแห่งหนึ่ง ทำงานมา 10 ปีกว่าๆ ด้วยภาษาและเทคโนโลยี เช่น JavaScript, Node.js, React, Vue และปัจจุบันกำลังสนใจในเรื่องของ Blockchain และ Crypto กำลังหัดเรียนภาษา Rust

Related Posts