Хит-тестирование форм SVG? - PullRequest
25 голосов
/ 01 февраля 2010

Браузеры, в которых реализованы части спецификации SVG (Firefox и т. Д.), Проводят для нас бесплатное тестирование - если я присоединяю прослушиватель mousedown к объекту SVG, я получаю уведомление при каждом щелчке по фигуре. Это удивительно, особенно для сложных форм многоугольников.

Мне интересно, есть ли способ использовать эту функцию для еще большего тестирования хитов. Я хочу знать, пересекает ли данный прямоугольник какую-либо из моих форм SVG.

Например, я добавляю 3 сложных полигона к своему элементу. Теперь я хочу знать, пересекает ли прямоугольник (40, 40, 100, 100) какой-либо из них. У кого-нибудь есть идея, как я мог бы подключиться к уже существующей поддержке тестирования хитов вместо того, чтобы добавлять весь этот код сам?

Спасибо

Ответы [ 4 ]

26 голосов
/ 01 февраля 2010

В SVG 1.1 DOM есть только правильный метод (к сожалению, он еще не реализован в Mozilla):

var nodelist = svgroot.getIntersectionList(hitrect, null);

Полный рабочий пример см. здесь .

15 голосов
/ 01 февраля 2010

Я не знаю ни одного способа пересечения целого прямоугольника. Но вы можете пересечь точку, чтобы вы могли построить более сложную проверку из этого:

var el= document.elementFromPoint(x, y);

даст вам элемент с наивысшей суммой в определенной координате страницы. Вы получите элемент <svg>, если ни одна фигура внутри SVG не будет нажата.

Это нестандартное расширение Mozilla , но оно работает и в WebKit. К сожалению, хотя он существует в Opera, он не будет заглядывать внутрь <svg>, поэтому в этом браузере элементом всегда будет элемент SVGSVGElement.

1 голос
/ 03 мая 2017

Chrome-версия checkIntersection (и getIntersectionList) проверяет ограничивающие рамки элемента, а не сами элементы. Я смог написать свой собственный checkIntersection, который работает на Chrome, используя холст с этим довольно сложным подходом, который, кажется, хорошо работает для маленьких прямоугольников и будет медленным для больших, так что это удобно для тестирования попаданий. Этот метод будет работать в качестве полизаполнения для checkIntersection в Chrome, для небольших прямоугольников и, возможно, других браузеров, у которых нарушены реализации checkIntersection.

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

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

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

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

...