我编写了一个通用的javascript库,可以创建各种类型的SVG图形(条形图,图形,饼形图等)。我还有来自this post的选取框选择的代码很好用。
所以现在我的SVG中有x1,y1,x2,y2坐标,我正在寻找一种简单的方法来选择在该选择中至少有1个像素的所有SVG元素。
对于只有点的情节,这很容易实现,但我正在寻找一种适用于矩形,椭圆和路径的简单通用解决方案。
答案 0 :(得分: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>