اكتشاف مرور الماوس فوق نقاط معينة داخل لوحة HTML؟

StackOverflow https://stackoverflow.com/questions/1221347

  •  10-07-2019
  •  | 
  •  

سؤال

لقد قمت بإنشاء محرك تصور بيانات تحليلية لـ Canvas وطُلب مني إضافة تمرير يشبه تلميح الأدوات فوق عناصر البيانات لعرض مقاييس مفصلة لنقطة البيانات الموجودة أسفل المؤشر.

بالنسبة إلى المخططات الشريطية ومخططات Gaant البسيطة والرسوم البيانية الشجرية وخرائط العقد ذات المساحات المربعة البسيطة أو نقاط الاهتمام المحددة، فقد تمكنت من تنفيذ ذلك من خلال تراكب عناصر DIV ذات الموضع المطلق مع سمات :hover، ولكن هناك بعض المرئيات الأكثر تعقيدًا مثل المخططات الدائرية وعرض تدفق حركة المرور الذي يحتوي على مئات المناطق المنفصلة المحددة بواسطة منحنيات بيزير.

هل من الممكن إرفاق تراكب بطريقة أو بأخرى، أو تشغيل حدث عندما يقوم المستخدم بتمرير الماوس فوق مسار مغلق محدد؟

يتم تعريف كل منطقة يجب تحديد التمرير لها على النحو التالي:

context.beginPath();
context.moveTo(segmentRight, prevTop);
context.bezierCurveTo(segmentRight, prevTop, segmentLeft, thisTop, segmentLeft, thisTop);
context.lineTo(segmentLeft, thisBottom);
context.bezierCurveTo(segmentLeft, thisBottom, segmentRight, prevBottom, segmentRight, prevBottom);
/*
 * ...define additional segments...
 */
// <dream> Ideally I would like to attach to events on each path:
context.setMouseover(function(){/*Show hover content*/});
// </dream>
context.closePath();

يعد الارتباط بكائن مثل هذا أمرًا تافهًا تقريبًا للتنفيذ في Flash أو Silverlight، نظرًا لأن تطبيق Canvas الحالي يتمتع بميزة الاستخدام المباشر لواجهة برمجة تطبيقات Javascript الموجودة لدينا والتكامل مع عناصر Ajax الأخرى، فإننا نأمل في تجنب وضع Flash في هذا المزيج.

أيه أفكار؟

هل كانت مفيدة؟

المحلول

هل يمكن التعامل مع الحدث MouseMove والحصول على س، ص تنسق من الحدث. ثم ربما عليك تكرار على كل المسارات الخاصة بك لاختبار إذا كانت نقطة هي على المسار. كان لي التي قد يكون لها بعض الرمز الذي يمكن استخدامه.

ويمكن حلقات على الأشياء بهذه الطريقة يكون بطيئا، خصوصا في IE. طريقة واحدة يمكن أن يحتمل تسريع العملية - وهذا هو الإختراق، ولكن سيكون فعالا جدا - سيكون لتغيير اللون الذي يوجه كل مسار مع ذلك أنه لا يمكن ملاحظتها من قبل البشر ولكن بحيث يكون كل مسار يتم رسمها في لون مختلف. لديك جدول للبحث عن ألوان لمسارات ومجرد بحث عن لون بكسل تحت الماوس.

نصائح أخرى

قماش الظل

أفضل طريقة رأيتها في أي مكان آخر لاكتشاف تمرير الماوس هي تكرار جزء الرسم الذي تريد اكتشافه على لوحة قماشية مخفية ومُنظفة.ثم قم بتخزين كائن ImageData.يمكنك بعد ذلك التحقق من مصفوفة ImageData بحثًا عن البكسل محل الاهتمام وإرجاع القيمة true إذا كانت قيمة alpha أكبر من 0.

// slow part
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillRect(100,100,canvas.width-100,canvas.height-100);
var pixels = ctx.getImageData(0,0,canvas.width,canvas.height).data;

// fast part
var idx = 4 * (mouse_x + mouse_y * canvas.width) + 3;
if (pixels[idx]) { // alpha > 0
  ...
}

مزايا

  • يمكنك اكتشاف أي شيء تريده نظرًا لأنك تقوم فقط بتكرار أساليب السياق.يعمل هذا مع PNG alpha والأشكال المركبة المجنونة والنص وما إلى ذلك.
  • إذا كانت صورتك ثابتة إلى حد ما، فأنت بحاجة فقط إلى القيام بذلك مرة واحدة لكل منطقة اهتمام.
  • "القناع" بطيء، لكن البحث عن البكسل رخيص للغاية.لذا فإن "الجزء السريع" يعد أمرًا رائعًا لاكتشاف تمرير الماوس.

سلبيات

  • هذا هو خنزير الذاكرة.كل قناع هو قيم W*H*4.إذا كان لديك مساحة صغيرة من القماش أو مناطق قليلة تحتاج إلى إخفاءها، فالأمر ليس بهذا السوء.استخدم مدير مهام Chrome لمراقبة استخدام الذاكرة.
  • توجد حاليًا مشكلة معروفة في getImageData في Chrome وFirefox.لن يتم تجميع النتائج على الفور إذا قمت بإبطال المتغير، لذلك إذا قمت بذلك بشكل متكرر، فسترى ارتفاع الذاكرة بسرعة.في النهاية، يتم جمع البيانات المهملة ولا ينبغي أن يؤدي ذلك إلى تعطل المتصفح، ولكن يمكن أن يفرض ذلك ضرائب على الأجهزة التي تحتوي على كميات صغيرة من ذاكرة الوصول العشوائي (RAM).

اختراق لحفظ الذاكرة

بدلاً من تخزين مصفوفة ImageData بأكملها، يمكننا فقط أن نتذكر وحدات البكسل التي لها قيم ألفا.إنه يوفر قدرًا كبيرًا من الذاكرة، ولكنه يضيف حلقة إلى عملية القناع.

var mask = {};
var len = pixels.length;
for (var i=3;i<len;i+=4) if ( pixels[i] ) mask[i] = 1;

// this works the same way as the other method
var idx = 4 * (mouse_x + mouse_y * canvas.width) + 3;
if (mask[idx]) {
  ...
}

ويمكن أن يتم ذلك باستخدام طريقة ctx.isPointInPath، ولكن لم يتم تنفيذ ذلك في ExCanvas لشركة آي إي. ولكن حل آخر يتمثل في استخدام الخرائط HTML، كما فعلت لهذه المكتبة الصغيرة: HTTP : //phenxdesign.net/projects/phenx-web/graphics/example.htm الذي يمكن الحصول على الإلهام من ذلك، لكنه لا يزال عربة صغيرة

وأود أن أقترح تتراكب مخطط صورة مع الإحداثيات الصحيحة تعيينها على المجالات التي تتطابق مع البنود التي تجرها قماش. بهذه الطريقة، يمكنك الحصول على تلميحات ومجموعة كبيرة من وظائف DOM / متصفح أخرى مجانا.

وكنت بحاجة الى القيام كشف نقرات الماوس لشبكة من المربعات (مثل خلايا جداول اكسل). أن يصل إلى سرعة، وتنقسم الشبكة إلى مناطق خفض بشكل متكرر حتى بقي عدد قليل من الخلايا، على سبيل المثال لشبكة 100x100، يمكن لل4 مناطق الأولى ستكون شبكات 50X50 تضم الأرباع الأربعة. ثم يمكن تقسيم هذه إلى 4 أخرى كل (وبالتالي إعطاء 16 مناطق 25x25 لكل منهما). وهذا يتطلب عددا قليلا من المقارنات وأخيرا الشبكة 25x25 يمكن اختبار لكل خلية (625 المقارنات في هذا المثال).

وهناك كتاب من قبل اريك رويل المسمى "HTML5 CANVAS COOKBOOK". في هذا الكتاب هناك فصل يدعى "التفاعل مع قماش: إرفاق المستمعين الحدث إلى أشكال والمناطق". mousedown، يمكن تنفيذ mouseup، عند تمرير الماوس، mouseout، mousemove، touchstart، touchend وtouchmove الأحداث. أقترح بشدة أن تقرأ ذلك.

لا يمكن أن يتم ذلك (وأيضا، على الأقل ليس بهذه السهولة)، لأن الكائنات التي رسم على القماش (مسارات) ليست ممثلة على النحو نفسه الكائنات في قماش. ما أعنيه هو أنه مجرد السياق 2D بسيطة وبمجرد رسمها شيء على ذلك، فإنه ينسى تماما كيف تم رسمها. انها مجرد مجموعة من بكسل لذلك.

في لمشاهدة مرر الفأرة فوق ويحب لذلك، كنت بحاجة الى بعض نوع من قماش ناقلات الرسومات، وهذا هو SVG أو تنفيذ بنفسك على رأس القائمة (وهو ما اقترح سام هاسلر)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top