Хит-тестирование форм 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.

  1. Создайте изображение, которое использует URI данных, содержащий externalHTML вашего SVG (вам может понадобиться включить в него правила стиля), например, так (этого изображения не должно быть на странице). Вы можете использовать обработчик события onload, чтобы определить, когда он загружается, если вам нужно.
  2. Создайте холст, который будет использоваться для вашего прямоугольника проверки нажатия (этот холст не должен быть на странице)

Чтобы проверить, пересекается ли прямоугольник с какой-либо из ваших фигур, сделайте следующее:

  1. Убедитесь, что размер холста равен размеру прямоугольника (установите его ширину и высоту)
  2. Очистите холст, используя метод canvas context clearRect ()
  3. Нарисуйте SVG на холсте в точке -x, -y, чтобы часть изображения, которая перекрывает холст, соответствовала области, которую вы хотите протестировать с помощью drawImage()
  4. Получите ImageData холста, используя контекст getImageData (). Каждый четвертый элемент массива данных является альфа-байтом, и ненулевое значение означает, что часть SVG перекрывает прямоугольник. Если все 4 байта равны 0, то ваш SVG не пересекает прямоугольник.

getIntersectionList отлично работает в Opera. Моя проблема заключается в том, что функции в полной спецификации SVG 1.1, касающиеся этого, требуют, чтобы элементы были визуализированы (и возможная цель для событий указателя), чтобы быть обнаруженными как попадание. К сожалению, это делает эти функции бесполезными для тестирования попаданий в игровом мире, где в настоящее время видна только часть мира.

Другие вопросы по тегам