我有一些坐标点,例如 [0,0],[30,0],[30,20],[60,20],[60,40],[0,40],[0,0]
将这些点作为输入,需要生成带有可单击角的形状。 边缘彼此重叠。第一次单击时,第一段越过第二段;第二次单击时,第二段越过第一段,第三次单击则产生斜切效果。
Possible Polygon interaction effects 是否可以在角落处放置不透明度为0的矩形以进行点击检测,但是问题是如何检测将矩形放置在角落处的确切位置。
第二,将这些点转换为直线或路径的最佳方法是什么? 生成的线条应足够粗,但不能穿过笔划宽度。
我之前尝试过使用strokewidth进行路径设置,所以行联接斜接无效。 有任何建议请。
示例代码,其中线条和矩形位于拐角处,但由于笔画宽度的缘故,它给我带来的效果并不理想:
<svg id="SvgjsSvg1001" width="700" height="400" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" viewBox="-100 -20 350 200"><defs id="SvgjsDefs1002"></defs><g id="SvgjsG1008" transform="matrix(2.5,0,0,2.5,0,0)"><line id="SvgjsLine1009" x1="0" y1="0" x2="30" y2="0" stroke-linecap="square" stroke="#ffdc0b" stroke-width="4"></line><line id="SvgjsLine1010" x1="30" y1="0" x2="30" y2="20" stroke-linecap="square" stroke="#002438" stroke-width="4"></line><line id="SvgjsLine1011" x1="30" y1="20" x2="60" y2="20" stroke-linecap="square" stroke="#9b56bb" stroke-width="4"></line><line id="SvgjsLine1012" x1="60" y1="20" x2="60" y2="40" stroke-linecap="square" stroke="#c6c7e2" stroke-width="4"></line><line id="SvgjsLine1013" x1="60" y1="40" x2="0" y2="40" stroke-linecap="square" stroke="#318700" stroke-width="4"></line><line id="SvgjsLine1014" x1="0" y1="40" x2="0" y2="0" stroke-linecap="square" stroke="#fe854f" stroke-width="4"></line>
<rect width="5" height="5" x="30" y="0"></rect>
<rect width="5" height="5" x="30" y="20"></rect>
<rect width="5" height="5" x="60" y="20"></rect>
<rect width="5" height="5" x="60" y="40"></rect>
<rect width="5" height="5" x="0" y="40"></rect>
<rect width="5" height="5" x="0" y="0"></rect></g></svg>
答案 0 :(得分:0)
我希望这是您要问的:为了绘制矩形,我正在使用每条路径的边界点。其中两个是重叠的:第一个和最后一个。但这无关紧要,因为您需要鼠标交互。一个失踪了。可以使用包含路径的组的边界框来绘制。
对于鼠标交互,我在每个角落使用cursor: pointer;
。
const SVG_NS = "http://www.w3.org/2000/svg";
let pathsRy = Array.from(document.querySelectorAll("path"));
let rectsRy = [];
pathsRy.forEach(p => {
let pbbox = p.getBBox();
rectsRy.push(
drawRect(
{
x: pbbox.x,
y: pbbox.y,
width: 5,
height: 5,
class: "corner"
},
svg
)
);
});
let gbbox = group.getBBox();
rectsRy.push(
drawRect(
{
x: gbbox.x + gbbox.width - 5,
y: gbbox.y + gbbox.height - 5,
width: 5,
height: 5,
class: "corner"
},
svg
)
);
function drawRect(o, parent) {
var rect = document.createElementNS(SVG_NS, "rect");
for (var name in o) {
if (o.hasOwnProperty(name)) {
rect.setAttributeNS(null, name, o[name]);
}
}
parent.appendChild(rect);
return rect;
}
.corner {
fill: rgba(255, 0, 0, 0.5);
cursor: pointer;
}
svg {
overflow: visible;
}
path {
fill: none;
stroke: black;
stroke-linejoin: round;
}
<svg id="svg" viewBox="0 0 70 70" width="200" >
<g id="group">
<path d="M0,0 L30,0 25,5 5,5z" />
<path d="M30,0 L30,20 25,25 25,5z" />
<path d="M30,20 L60,20 55,25 25,25" />
<path d="M60,20 L60,40 55,35 55,25" />
<path d="M60,40 L0,40 5,35 55,35z" />
<path d="M0,40 L0,0 5,5 5,35z" />
</g>
</svg>
请注意,这适用于这种形状。对于具有多个“转折点”且处于不同位置的形状,它将不起作用。
更新我弄清了您的代码。由于所有行都具有相同的stroke-linecap
,因此将其放在SVG中。另外,由于我需要在JavaScript中移动stroke-width
,因此也要在其中使用它。
在Java语言中,我定义了行数组linesRy
。对于每一行,我都得到x1和y1属性的值。
使用每行和stroke-width
的x1和y1属性的值的值,我在每个角上绘制了一个粉红色的rect
。
OP更新了发布一些代码的问题。我也在更新代码:
const SVG_NS = "http://www.w3.org/2000/svg";
let strokeWidth = 4
let linesRy = Array.from(document.querySelectorAll("line"));
linesRy.forEach((l)=>{
l.setAttributeNS(null, "stroke-width", strokeWidth);
let x = l.getAttribute("x1");
let y = l.getAttribute("y1");
drawRect({
x:x-strokeWidth/2,
y:y-strokeWidth/2,
width:strokeWidth,
height:strokeWidth,
class:"pink"
}, SvgjsG1008);
})
function drawRect(o, parent) {
var rect = document.createElementNS(SVG_NS, "rect");
for (var name in o) {
if (o.hasOwnProperty(name)) {
rect.setAttributeNS(null, name, o[name]);
}
}
parent.appendChild(rect);
return rect;
}
line{
stroke-linecap:square;
}
.pink{fill:pink}
<svg id="SvgjsSvg1001" width="700" height="400" viewBox="-100 -20 350 200">
<g id="SvgjsG1008" transform="matrix(2.5,0,0,2.5,0,0)"><line id="SvgjsLine1009" x1="0" y1="0" x2="30" y2="0" stroke="#ffdc0b" ></line>
<line id="SvgjsLine1010" x1="30" y1="0" x2="30" y2="20" stroke="#002438"></line>
<line id="SvgjsLine1011" x1="30" y1="20" x2="60" y2="20" stroke="#9b56bb"></line>
<line id="SvgjsLine1012" x1="60" y1="20" x2="60" y2="40" stroke="#c6c7e2"></line>
<line id="SvgjsLine1013" x1="60" y1="40" x2="0" y2="40" stroke="#318700" ></line>
<line id="SvgjsLine1014" x1="0" y1="40" x2="0" y2="0" stroke="#fe854f" ></line>
<!--
<rect width="5" height="5" x="30" y="0"></rect>
<rect width="5" height="5" x="30" y="20"></rect>
<rect width="5" height="5" x="60" y="20"></rect>
<rect width="5" height="5" x="60" y="40"></rect>
<rect width="5" height="5" x="0" y="40"></rect>
<rect width="5" height="5" x="0" y="0"></rect>-->
</g></svg>