Я создал библиотеку холста для управления сценами фигур для некоторых рабочих проектов. Каждая фигура представляет собой объект с связанным с ним способом рисования. Во время обновления холста каждая фигура в стеке рисуется. Форма может иметь характерные связанные события мыши, которые все обернуты вокруг собственных событий мыши DOM.
Я нашел некоторые методы в дикой природе для обнаружения мыши на отдельных фигурах, каждый из которых работает, но с некоторыми довольно серьезными оговорками.
-
Прозрачный холст-призрак используется для индивидуальной индивидуальной формы. Затем я сохраняю копию холста призрака с помощью
getImageData()
. Как вы можете себе представить, это занимает много памяти, когда есть много точек с привязанными событиями мыши (100 кликабельных фигур на холсте 960x800 составляют ~ 300 МБ в памяти). -
Чтобы обойти проблему памяти, я начал перебирать пиксельные данные и сохранять только адреса в пикселях с ненулевой альфа. Это хорошо работало для уменьшения памяти, но значительно увеличило загрузку процессора. Я повторяю только каждый 4-й индекс (RGBA), и любой пиксельный адрес с ненулевой альфа-памятью сохраняется как хэш-ключ для быстрого поиска во время перемещения мыши. Он по-прежнему перегружает мобильные браузеры и Firefox в Linux в течение 10 секунд.
-
Я читал о методе, где все фигуры будут нарисованы на одном холсте-призраке, используя цвет, чтобы различать, какая форма принадлежит каждому пикселю. Я был очень доволен этой идеей, потому что теоретически она должна иметь возможность различать миллионы форм.
К сожалению, это нарушается сглаживанием, которое нельзя отключить при большинстве реализаций холста. Каждый нечеткий край создает десятки цветов, которые можно смело игнорировать, кроме того, что они могут смешать/с перекрывающимися краями формы. Последнее, что я хочу сделать, когда кто-то пересекает мышь по границе формы, - это загорать полуслучайные события mouseover для несвязанных фигур, связанных с цветами, которые возникли из смешивания из-за AA.
Я знаю, что это не новая проблема для разработчиков видеоигр и не должно быть быстрых алгоритмов для такого рода вещей. Если кто-то знает об алгоритме, который может разрешить (реалистично) сотни форм, не занимая процессор более чем на несколько секунд или резко увеличивая потребление ОЗУ, я был бы очень благодарен.
Есть две другие темы при обнаружении мыши, оба из которых обсуждают эту тему, но они идут не дальше, чем 3 метода, которые я описываю. Обнаружить наведение определенных точек в HTML-холсте? и холст HTML5 вокруг холста.
EDIT: 2011/10/21
Я тестировал другой метод, который более динамичен и не требует хранения чего-либо, но он искалечен проблемой производительности в Firefox. Метод в основном состоит в том, чтобы перебирать фигуры и: 1) очищать 1x1 пиксель под мышью, 2) рисовать фигуру, 3) получать 1x1 пиксель под мышью. Удивительно, но это очень хорошо работает в Chrome и IE, но, к сожалению, в Firefox.
Очевидно, Chrome и IE могут оптимизировать, если вам нужна только небольшая область пикселей, но Firefox, похоже, не оптимизируется на основе нужной области пикселей. Возможно, внутренне он получает весь холст, а затем возвращает область вашего пикселя.
Код и исходный вывод здесь: http://pastebin.com/aW3xr2eB.