Хит-тестирование форм SVG?
Браузеры, в которых реализованы части спецификации SVG (Firefox и т. Д.), Проводят для нас бесплатное тестирование - если я присоединяю прослушиватель mousedown к объекту SVG, я получаю уведомление при каждом нажатии на фигуру. Это удивительно, особенно для сложных форм многоугольников.
Мне интересно, есть ли способ, которым я могу использовать эту функцию для еще большего тестирования хитов. Я хочу знать, пересекает ли данный прямоугольник какую-либо из моих форм SVG.
Например, я добавляю 3 сложных полигона к своему элементу. Теперь я хочу знать, пересекает ли прямоугольник (40, 40, 100, 100) какой-либо из них. У кого-нибудь есть идеи, как я мог бы подключиться к уже существующей поддержке тестирования хитов вместо того, чтобы добавлять весь этот код сам?
Спасибо
4 ответа
В SVG 1.1 DOM есть только правильный метод (к сожалению, он еще не реализован в Mozilla):
var nodelist = svgroot.getIntersectionList(hitrect, null);
Полный рабочий пример смотрите здесь.
Я не знаю ни одного способа пересечения целого прямоугольника. Но вы можете пересечь точку, чтобы вы могли построить более сложную проверку из этого:
var el= document.elementFromPoint(x, y);
даст вам самый сложный элемент в определенной координате страницы. Вы получите <svg>
элемент, если никакие фигуры внутри SVG не ударили.
Это нестандартное расширение Mozilla, но оно работает и в WebKit. К сожалению, хотя он существует в Opera, он не заглянет внутрь <svg>
Таким образом, в этом браузере элемент всегда будет SVGSVGElement.
Chrome-версия checkIntersection (и getIntersectionList) проверяет ограничивающие блоки элементов, а не сами элементы. Я смог написать свой собственный checkIntersection, который работает на Chrome, используя холст с этим довольно сложным подходом, который, кажется, хорошо работает для маленьких прямоугольников и будет медленным для больших, так что это хорошо для тестирования попаданий. Этот метод будет работать как полизаполнение для checkIntersection в Chrome, для небольших прямоугольников и, возможно, для других браузеров, у которых нарушены реализации checkIntersection.
- Создайте изображение, которое использует URI данных, содержащий externalHTML вашего SVG (вам может понадобиться включить в него правила стиля), например, так (этого изображения не должно быть на странице). Вы можете использовать обработчик события onload, чтобы определить, когда он загружается, если вам нужно.
- Создайте холст, который будет использоваться для вашего прямоугольника проверки нажатия (этот холст не должен быть на странице)
Чтобы проверить, пересекается ли прямоугольник с какой-либо из ваших фигур, сделайте следующее:
- Убедитесь, что размер холста равен размеру прямоугольника (установите его ширину и высоту)
- Очистите холст, используя метод canvas context clearRect ()
- Нарисуйте SVG на холсте в точке -x, -y, чтобы часть изображения, которая перекрывает холст, соответствовала области, которую вы хотите протестировать с помощью drawImage()
- Получите ImageData холста, используя контекст getImageData (). Каждый четвертый элемент массива данных является альфа-байтом, и ненулевое значение означает, что часть SVG перекрывает прямоугольник. Если все 4 байта равны 0, то ваш SVG не пересекает прямоугольник.
getIntersectionList отлично работает в Opera. Моя проблема заключается в том, что функции в полной спецификации SVG 1.1, касающиеся этого, требуют, чтобы элементы были визуализированы (и возможная цель для событий указателя), чтобы быть обнаруженными как попадание. К сожалению, это делает эти функции бесполезными для тестирования попаданий в игровом мире, где в настоящее время видна только часть мира.