เพื่อติดตามสิ่งที่กำลังถูกวาด แอพพลิเคชั่นจำนวนมาก เช่น แอพพลิเคชั่นการวาดภาพ ระบบการออกแบบโดยใช้คอมพิวเตอร์ช่วย (ระบบ CAD) และเกม จะรักษารายการของออบเจ็กต์ที่แสดงอยู่ในปัจจุบัน โดยทั่วไปแล้ว แอปพลิเคชันเหล่านี้อนุญาตให้ผู้ใช้จัดการวัตถุที่แสดงอยู่บนหน้าจอในปัจจุบัน ตัวอย่างเช่น ในแอปพลิเคชัน CAD เราสามารถเลือก ย้าย ซูม ฯลฯ องค์ประกอบในการออกแบบได้
- "เทคโนโลยีแกนผ้าใบ HTML5"
เช่นเดียว 实现拖拽
ใน Canvas Canvas จัดเตรียม API ที่เรียกว่า isPointInPath(x, y)
เพื่อตรวจสอบว่า 点(x, y)
อยู่ในเส้นทางหรือไม่ ส่งคืนค่าจริงหากอยู่ภายในเส้นทาง เราก็จะได้ไอเดียดังนี้
รักษา 数组
ที่สามารถอธิบายแต่ละเส้นทาง และใช้ ispointInPath(x, y)
เพื่อพิจารณาว่าตำแหน่งที่คลิกอยู่ในเส้นทางใดเส้นทางหนึ่งหรือไม่ หากอยู่ในเส้นทางนี้ ให้เลือกเส้นทางนี้ ดำเนินการ (ย้าย ซูม ฯลฯ) แล้วจึงวาดภาพกราฟิก
ในบทความนี้ ฉันใช้ 多边形拖拽为例进行说明
. การสาธิตมีดังนี้ (เหตุผลที่อยู่เบื้องหลังสำนักพิมพ์คือซอฟต์แวร์บันทึกหน้าจอ: japanese_ogre:):
CodePen จะเปิดขึ้น
วิธีการวาดรูปหลายเหลี่ยมในการ Demo ก็มีสรุปไว้ก่อนแล้วจะไม่ลงรายละเอียดอีกครับ ghost:: การวาดรูปหลายเหลี่ยมแบบ Canvas
คำอธิบายของความคิดรูปด้านล่างให้คำอธิบายคร่าวๆ และรหัสหลอก แนวคิดนี้ไม่ใช่เรื่องยาก แต่มีรายละเอียดบางอย่างที่ต้องจัดการ
โครงสร้างโค้ดแสดงอยู่ที่นี่และแนวคิดของโค้ดถูกทำเครื่องหมายไว้ในความคิดเห็นโค้ดโดยละเอียดเพิ่มเติมใน CodePen
เนื่องจากบทความนี้เน้นเรื่องการลาก จึงมีคำอธิบายส่วนของการวาดน้อยลง
// ฟังก์ชันฟังก์ชันเส้นทางวาดรูปหลายเหลี่ยม DrawPolygonPath//คำจำกัดความของคลาสรูปหลายเหลี่ยม คลาสรูปหลายเหลี่ยม{ ...}//คืนตำแหน่งในผืนผ้าใบตามฟังก์ชันเหตุการณ์การคลิก positoinInCanvas//รับระยะทางเส้นตรงระหว่างฟังก์ชันสองจุด getDistance// ในระยะเริ่มต้น ให้บันทึกการลาก ลากวัตถุ canvas.onmousedown//ลากเฟส, วาดพาธ, ลากเส้น canvas.onmousemove//เฟสสิ้นสุด, อัปเดตตำแหน่งวัตถุลาก canvas.onmouseupคำอธิบายของส่วนสำคัญ
จากนั้น ให้เริ่มประมวลผลส่วนสำคัญและรายละเอียดของโค้ด
วิธีการรักษาอาร์เรย์ของอ็อบเจ็กต์การลากในระหว่างการเริ่มต้นโปรแกรม เราจะกำหนดอาร์เรย์ polygonArray
รูปหลายเหลี่ยมอาร์เรย์ = []
ทุกครั้งที่วาดรูปหลายเหลี่ยมใหม่ วัตถุรูปหลายเหลี่ยมใหม่จะถูกผลักเข้าไปในอาร์เรย์เพื่อการบำรุงรักษา
const polygon = รูปหลายเหลี่ยมใหม่ (mouseStart.get ('x'), mouseStart.get ('y'), sideNum, รัศมี); polygonArray.push (รูปหลายเหลี่ยม); // บันทึกวัตถุเส้นทาง
ในการคลิกครั้งต่อๆ ไป จำเป็นต้องพิจารณาว่าตำแหน่งการคลิกอยู่ในเส้นทางตามข้อมูลที่เกี่ยวข้องหรือไม่
วิธีการเลือกวัตถุที่จะลากเมื่อคลิก ขั้นแรก รับตำแหน่งที่สอดคล้องกัน canvas中
เมื่อคลิก รหัสของฉันใช้ mouseStart
เพื่อบันทึก x
และ y
จากนั้นสำรวจ polygon
ใน polygonArray
เรียก polygon.createPath()
ระหว่างการสำรวจ และใช้ isPointInPath()
เพื่อพิจารณาว่ามีเส้นทางอยู่ที่ตำแหน่งที่คลิกหรือไม่ หากเป็นเช่นนั้น draggingPolygon = polygon
จะสิ้นสุดฟังก์ชัน
const pos = positionInCanvas(e, canvasLeft, canvasTop);//รับตำแหน่งพิกเซลใน canvas//บันทึกจุดเริ่มต้นของเมาส์ smouseStart.set('x', pos.x);mouseStart.set('y', pos. y);...for (ให้รูปหลายเหลี่ยมของ polygonArray) { polygon.createPath(); (ctx.isPointInPath(mouseStart.get('x'), mouseStart.get('y'))) { DraggingPolygon = รูปหลายเหลี่ยม;การคำนวณเมื่อลาก
ต้องเข้าใจส่วนนี้อย่างถ่องแท้ ขอแนะนำให้คุณแก้ไขข้อบกพร่องโดยใช้ console.log(draggingPolygon)
สองตัวและโค้ดในการสาธิต เนื่องจากเราอยู่ในขั้นตอน mousemove
และฟังก์ชันต่างๆ จะถูกทริกเกอร์บ่อยมากในขั้นตอนนี้
ฉันพยายามแสดงออกอย่างชัดเจนด้วยคำพูด
ขั้นแรก ให้คำนวณระยะห่างจาก mouseStart
เมื่อ move
ซึ่งบันทึกเป็นค่าต่าง มี offsetX
บนแกน x และ offsetY
บนแกน y
const pos = ตำแหน่งInCanvas (e, canvasLeft, canvasTop), diff = แผนที่ใหม่ ([ ['offsetX', pos.x - mouseStart.get('x')], ['offsetY', pos.y - mouseStart.get( 'y')] ]);
จากนั้นบันทึก centerX
และ centerY
ของวัตถุลากปัจจุบัน บันทึกเป็น temp
ให้ tempCenterX = DraggingPolygon.centerX, tempCenterY = DraggingPolygon.centerY;
นี่เป็นจุดที่เข้าใจยาก ทำไมเราจึงควรบันทึกมันไว้? อ่านต่อคุณจะใช้มันในภายหลัง
ตั้งค่าตำแหน่งกึ่งกลางใหม่ของการลากรูปหลายเหลี่ยมตามออฟเซ็ตใน diff
DraggingPolygon.centerX += diff.get('offsetX'); DraggingPolygon.centerX += diff.get('offsetY');
จากนั้นเคลียร์ผ้าใบและวาดเส้นทางและลายเส้นใหม่
ctx.clearRect(0, 0, canvas.width, canvas.height);สำหรับ (ให้รูปหลายเหลี่ยมของ polygonArray) { DrawPolygonPath(polygon.sideNum, polygon.radius, polygon.centerX, polygon.centerY, ctx); );}
ในที่สุด tempCenterX
และ tempCenterY
ที่กล่าวถึงข้างต้นก็ถูกนำมาใช้:
DraggingPolygon.centerX = tempCenterX; DraggingPolygon.centerY = tempCenterY;
ทำไมเราต้องทำเช่นนี้?
เนื่องจากการลากของเรา 基于多边形的原位置
และระยะ mousemove
不能确定函数的最终位置
หากไม่มีการกู้คืนในขณะนี้ 漂移
จะเกิดขึ้น ฉันใส่ความคิดเห็นในโค้ดสองบรรทัดนี้ และ มีผลดังนี้:
หากฉันไม่ได้อธิบายให้ชัดเจน ฉันแนะนำให้ทุกคนแก้ไขและแก้ไขโค้ด
กำลังประมวลผลหลังจากการลาก หลังจากการลากเสร็จสิ้น ก็อยู่ในขั้นตอน mouseup
ในขณะนี้ เราได้กำหนดตำแหน่งสุดท้ายของ DragginPolygon แล้ว เพียงอัปเดต และสุดท้ายก็ตั้งค่าเป็น null เพื่อแยก 在没有拖拽多边形情况下,鼠标在画布上移动触发对应代码
const pos = ตำแหน่งInCanvas (e, canvasLeft, canvasTop), offsetMap = แผนที่ใหม่ ([ ['offsetX', pos.x - mouseStart.get('x')], ['offsetY', pos.y - mouseStart.get( 'y')] ]); DraggingPolygon.centerX += offsetMap.get('offsetX'); DraggingPolygon.centerY += offsetMap.get('offsetY'); การลากPolygon = null;บทสรุป
ในความเป็นจริง การใช้ฟังก์ชันนี้ไม่ใช่เรื่องยาก สิ่งสำคัญคือการเข้าใจแนวคิด: การติดตามทำได้โดยการรักษารายการของออบเจ็กต์ที่แสดงอยู่ในปัจจุบันและทำการตัดสินใจด้วย isPointInPath
สุดท้ายนี้ขอเชิญชวนทุกท่านมาแลกเปลี่ยนเรียนรู้
อ้างอิง"เทคโนโลยีแกนผ้าใบ HTML5"
ข้างต้นคือเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการศึกษาของทุกคน ฉันหวังว่าทุกคนจะสนับสนุน VeVb Wulin Network