لتتبع ما يتم رسمه، تحتفظ العديد من التطبيقات، مثل تطبيقات الرسم وأنظمة التصميم بمساعدة الكمبيوتر (أنظمة CAD) والألعاب، بقائمة من الكائنات المعروضة حاليًا. عادةً ما تسمح هذه التطبيقات للمستخدمين بمعالجة الكائنات المعروضة حاليًا على الشاشة. على سبيل المثال، في تطبيق CAD، يمكننا تحديد العناصر في التصميم ونقلها وتكبيرها وما إلى ذلك
-"التقنية الأساسية لقماش HTML5"
وينطبق الشيء نفسه 实现拖拽
في Canvas. يوفر Canvas واجهة برمجة تطبيقات تسمى isPointInPath(x, y)
لتحديد ما إذا كانت 点(x, y)
موجودة في المسار. يُرجع صحيحًا إذا كان ضمن المسار. لذلك يمكننا أن نحصل على الأفكار التالية:
احتفظ 数组
يمكنها وصف كل مسار، واستخدم ispointInPath(x, y)
لتحديد ما إذا كان الموضع الذي تم النقر عليه في مسار معين، وإذا كان في هذا المسار، فحدد هذا المسار، وقم بتنفيذ العمليات (النقل، والتكبير، وما إلى ذلك). ، ثم قم برسم الرسومات
في هذه المقالة، أستخدم 多边形拖拽为例进行说明
العرض التوضيحي كما يلي (السبب وراء الطباعة هو برنامج تسجيل الشاشة: japanese_ogre:):
يفتح كود بن
لقد تم تلخيص كيفية رسم المضلعات في العرض التوضيحي من قبل، لذلك لن أخوض في التفاصيل مرة أخرى: Ghost:: رسم مضلع قماشي
شرح الأفكاريقدم الشكل أدناه وصفًا تقريبيًا ورمزًا زائفًا، الفكرة ليست صعبة، ولكن هناك بعض التفاصيل التي يجب التعامل معها.
تم إدراج بنية التعليمات البرمجية هنا وتم وضع علامة على أفكارها، كما توجد تعليقات أكثر تفصيلاً على التعليمات البرمجية في CodePen.
نظرًا لأن هذه المقالة تركز على السحب، سيكون هناك وصف أقل لجزء الرسم.
// وظيفة رسم مسار المضلع drawPolygonPath // تعريف فئة المضلع class Polygon { ...} // إرجاع الموضع في اللوحة القماشية وفقًا لوظيفة حدث النقر positoinInCanvas // احصل على مسافة الخط المستقيم بين نقطتين وظيفة getDistance // في مرحلة البداية، قم بتسجيل كائن السحب، Canvas.onmousedown// مرحلة السحب، رسم المسار، الرسم، Canvas.onmousemove// مرحلة النهاية، تحديث موضع كائن السحب Canvas.onmouseupوصف الأجزاء الرئيسية
بعد ذلك، ابدأ في معالجة الأجزاء الرئيسية وتفاصيل الكود
كيفية الحفاظ على مجموعة من كائنات السحبأثناء تهيئة البرنامج، نقوم بتعريف مصفوفة polygonArray
مضلع صفيف = []
في كل مرة يتم رسم مضلع جديد، سيتم دفع كائن مضلع جديد إلى المصفوفة للصيانة.
const polygon = new Polygon(mouseStart.get('x'), mouseStart.get('y'), SideNum, radius);polygonArray.push(polygon);// تسجيل كائن المسار
في عمليات النقر اللاحقة، من الضروري تحديد ما إذا كان موضع النقر في المسار بناءً على المعلومات المقابلة.
كيفية تحديد الكائن لسحبه عند النقر عليه أولاً، احصل على الموضع المقابل canvas中
عند النقر عليه. يستخدم الكود الخاص بي mouseStart
لتسجيل x
و y
بعد ذلك، قم باجتياز polygon
في polygonArray
، واستدعاء polygon.createPath()
أثناء الاجتياز، واستخدم isPointInPath()
لتحديد ما إذا كان هناك مسار في الموضع الذي تم النقر عليه. إذا كان الأمر كذلك، فإن draggingPolygon = polygon
ينهي الوظيفة.
const pos = PositionInCanvas(e, CanvasLeft, CanvasTop);// احصل على موضع البكسل في اللوحة القماشية// سجل نقطة بداية الماوس smouseStart.set('x', pos.x);mouseStart.set('y', pos. y);...for (let polygon of polygonArray) { polygon.createPath(); (ctx.isPointInPath(mouseStart.get('x'), mouseStart.get('y'))) { DraggingPolygon = polygon } };الحساب عند السحب
يجب أن يكون هذا الجزء مفهومًا تمامًا. يوصى بتصحيح الأخطاء بناءً على اثنين من console.log(draggingPolygon)
والتعليمات البرمجية في العرض التوضيحي، لأننا في مرحلة mousemove
، ويتم تشغيل الوظائف بشكل متكرر جدًا في هذه المرحلة.
أحاول التعبير عن ذلك بوضوح بالكلمات
أولاً، احسب المسافة من mouseStart
عند move
، والتي يتم تسجيلها على أنها فرق. هناك offsetX
على المحور السيني offsetY
على المحور الصادي.
const pos = PositionInCanvas(e, CanvasLeft, CanvasTop), diff = new Map([ ['offsetX', pos.x - mouseStart.get('x')], ['offsetY', pos.y - mouseStart.get( 'y')] ]);
ثم سجل centerX
و centerY
لكائن السحب الحالي، المسجل كدرجة حرارة
دع tempCenterX = DraggingPolygon.centerX، tempCenterY = DraggingPolygon.centerY؛
هذه هي النقطة التي يصعب فهمها. لماذا يجب أن نسجلها؟ استمر في القراءة، سوف تستخدمه لاحقًا.
قم بتعيين الموضع المركزي الجديد لسحب المضلع وفقًا للإزاحة الموجودة في diff
DraggingPolygon.centerX += diff.get('offsetX'); DraggingPolygon.centerY += diff.get('offsetY');
ثم قم بمسح اللوحة القماشية وارسم مسارات وحدودًا جديدة
ctx.clearRect(0, 0, Canvas.width, Canvas.height);for (let polygon of polygonArray) { drawPolygonPath(polygon.sideNum, polygon.radius, polygon.centerX, polygon.centerY, ctx.stroke(); );}
وأخيرًا، يتم استخدام tempCenterX
و tempCenterY
المذكورين أعلاه:
DraggingPolygon.centerX = tempCenterX;
لماذا نحتاج للقيام بذلك؟
لأن السحب لدينا 基于多边形的原位置
، ولا يمكن لمرحلة mousemove
不能确定函数的最终位置
. إذا لم يكن هناك انتعاش في هذا الوقت، فسوف يحدث 漂移
التأثير هو كما يلي:
إذا لم أوضح الأمر، أنصح الجميع بتعديل الكود وتصحيحه.
المعالجة بعد السحب بعد اكتمال السحب، يكون في مرحلة mouseup
. في هذا الوقت، حددنا الموضع النهائي لـ DragginPolygon، ما عليك سوى تحديثه، ثم تعيينه أخيرًا على قيمة خالية لاستبعاد 在没有拖拽多边形情况下,鼠标在画布上移动触发对应代码
const pos = PositionInCanvas(e, CanvasLeft, CanvasTop), offsetMap = new Map([ ['offsetX', pos.x - mouseStart.get('x')], ['offsetY', pos.y - mouseStart.get( 'y')] ]); drawgingPolygon.centerX += offsetMap.get('offsetX'); OffsetMap.get('offsetY'); DragingPolygon = null;خاتمة
في الواقع، ليس من الصعب تنفيذ هذه الوظيفة. المفتاح هو فهم المفهوم: يتم تحقيق التتبع من خلال الاحتفاظ بقائمة الكائنات المعروضة حاليًا وإصدار الأحكام باستخدام isPointInPath.
وأخيرا، أرحب بالجميع للتبادل والتعلم
مراجع"التقنية الأساسية لقماش HTML5"
ما ورد أعلاه هو المحتوى الكامل لهذه المقالة وآمل أن يكون مفيدًا لدراسة الجميع وآمل أيضًا أن يدعم الجميع شبكة VeVb Wulin.