2017-02-06 1 views
0

Я написал общую библиотеку javascript, которая создает различные типы графиков SVG (штрих-коды, графики, графики и т. Д.). У меня также есть код для выделения выделения от this post, который прекрасно работает.Как выбрать все элементы SVG в прямоугольнике с помощью javascript

Итак, теперь у меня есть координаты x1, y1, x2, y2 в моем SVG, и я ищу простой способ выбора всех элементов SVG, которые имеют по крайней мере 1 пиксель в пределах этого выбора.

Для участка с точными точками это легко выполнимо, но я ищу простое общее решение, которое будет работать для прямоугольников, эллипсов и дорожек.

+2

Почтовый индекс для лучшего понимания вопроса/проблемы. – user7393973

+0

Я уточнил вопрос, чтобы уточнить параметры, которые у меня есть. У меня есть координаты topLeft и bottomRight в моем SVG, и я ищу все элементы внутри (или частично внутри) этих границ. – JJFlash42

+0

вы можете получить ограничительную рамку каждой формы (getBBox) и посмотреть, находится ли она внутри вашего выбора, но это не является надежным. –

ответ

1

Это действительно лишь частичный ответ, поскольку я могу показать вам, как достичь своей цели в простых ситуациях, но не во всех сценариях, которые вы предложили.

Упрощенным решением было бы использовать svgSvgElement.getIntersectionList. Приведенный ниже код демонстрирует это. Он показывает, как определить, какой из трех цветных треугольников «ударил» прямоугольником выбора. Обратите внимание, однако, что он не определяет, какие элементы перекрывают прямоугольник выделения, но который элемент ограничивает поля перекрывает прямоугольник выделения. Таким образом, синий треугольник ниже считается перекрытым, как ожидалось, и красный треугольник считается не перекрывающимся, как ожидалось, но зеленый треугольник равен, который считается перекрытым не потому, что сам треугольник, а потому, что вокруг него расположен зеленый прямоугольник. Чтобы фактически определить, какая форма сама перекрывается, прямоугольник более сложный и был источником большого притягивания волос с самого начала.

const qs = (selctr) => document.querySelector(selctr); 
 

 
const svg = qs('svg' ); 
 
const green = qs('#green'); 
 
const blue = qs('#blue'); 
 
const red = qs('#red' ); 
 

 
const r = svg.createSVGRect(); 
 
r.x = 10; 
 
r.y = 10; 
 
r.width = 100; 
 
r.height = 40; 
 
const nodeList = svg.getIntersectionList(r, null); 
 
const arr = Array.from(nodeList); 
 
console.log('The following triangles "overlap" the black rectangle:'); 
 
console.log('green:', arr.indexOf(green) >= 0, '(?!)'); 
 
console.log('blue: ', arr.indexOf(blue) >= 0); 
 
console.log('red: ', arr.indexOf(red ) >= 0);
<svg> 
 
    <g fill="none" stroke-width="1" stroke-dasharray="2" opacity="0.5"> 
 
    <rect x="25" y="10" width="100" height="40" stroke="black"/> 
 
    <rect x="10" y="40" width="20" height="40" stroke="green" transform="translate(0)"/> 
 
    <rect x="10" y="40" width="20" height="40" stroke="blue" transform="translate(50)"/> 
 
    <rect x="10" y="40" width="20" height="40" stroke="red" transform="translate(120)"/> 
 
    </g> 
 
    <g opacity="0.5"> 
 
    <path id="green" fill="green" d="M10,40 L30,60 20,80" transform="translate(0)"/> 
 
    <path id="blue" fill="blue" d="M10,40 L30,60 20,80" transform="translate(50)"/> 
 
    <path id="red" fill="red" d="M10,40 L30,60 20,80" transform="translate(120)"/> 
 
    </g> 
 
</svg>

Это было suggested that you could use document.elementFromPoint как своего рода обходные для этого. Например, вы можете проверить, может ли, например, какая-либо из четырех угловых точек или центральной точки вашего прямоугольника выбора попадать внутрь вашей фигуры. Однако следует отметить, что даже такой подход будет не хватать следующее:

<svg> 
 
    <rect x="10" y="10" width="50" height="50" fill="none" stroke="black" stroke-width="1" stroke-dasharray="2" opacity="0.5"/> 
 
    <path fill="red" opacity="0.5" d="M45,30 L80,0 90,70"/> 
 
</svg>

+0

Удивительные, даже если не совершенные, это те функции, которые я искал! – JJFlash42