Из комментария:
Лично я бы просто переключился на использование SVG.Это больше для чего это было сделано.Однако, возможно, стоит взглянуть на источник EaselJS .Есть метод Stage.getObjectUnderPoint (), и его демонстрация этого, кажется, работает отлично.
В итоге я посмотрел на источник, и библиотека использует ваш первый подход - отдельный скрытый холст для каждогоobject.
Одна идея, которая пришла в голову, была попытка создать некий контент-ориентированный алгоритм для обнаружения сглаженных пикселей и того, к какой форме они принадлежат.Я быстро отклонил эту идею.
Однако у меня есть еще одна теория.Кажется, что нет никакого способа использовать призрачные холсты, но, возможно, есть способ генерировать их только тогда, когда они необходимы.
Обратите внимание, что следующая идея является теоретической и непроверенной. Возможно, я мог упустить что-то, что означало бы, что этот метод не будет работать.
Наряду с рисованием объекта, сохраните метод, в котором вы нарисовали этот объект.Затем, используя метод рисования объекта, вы можете рассчитать грубую ограничивающую рамку для этого объекта.При нажатии на холст, выполните цикл по всем имеющимся на нем объектам и извлеките те, чьи ограничивающие рамки пересекаются с точкой.Для каждого из этих извлеченных объектов нарисуйте их отдельно на холсте-призраке, используя ссылку на метод для этого объекта.Определите, находится ли мышь над небелым пикселем, очистите холст и повторите.
В качестве примера рассмотрим, что я нарисовал два объекта.Я буду хранить методы рисования прямоугольника и круга в удобочитаемой форме.
circ = ['beginPath', ['arc', 75, 75, 10], 'closePath', 'fill']
rect = ['beginPath', ['rect', 150, 5, 30, 40], 'closePath', 'fill']
(Вы можете захотетьчтобы минимизировать сохраненные данные или использовать другой синтаксис, такой как синтаксис SVG)
Поскольку я рисую эти круги в первый раз, я также буду записывать размерные значения и использовать их для определения границполе ( Примечание: вам нужно будет компенсировать ширину хода ).
circ = {left: 65, top: 65, right: 85, bottom: 85}
rect = {left: 150, top: 5, right: 180, bottom: 45}
На холсте произошло событие щелчка.Точка мыши - {x: 70, y: 80}
Проходя по двум объектам, мы обнаруживаем, что координаты мыши попадают в границы круга.Таким образом, мы помечаем объект круга как возможного кандидата на столкновение.
Анализируя метод рисования кругов, мы можем воссоздать его на холсте-призраке и затем проверить, попадают ли координаты мыши в небелые пиксели.*
После определения того, делает это или нет, мы можем очистить холст-призрак, чтобы подготовиться к рисованию на нем еще объектов.
Как вы можете видеть, это устраняет необходимость хранить 960 x 800x 100 пикселей и только 960 x 800 x2 не более.
Эту идею лучше всего реализовать как своего рода API для автоматической обработки хранилища данных (например, метод рисования, размеры...).