我已经在SVG上设计了Duval三角形(诊断工具), 合并不同颜色的线段(封闭路径)。 诊断结果将是一个坐标。 是否需要检测结果坐标位于哪个闭合路径?
答案 0 :(得分:2)
您有几种选择:
SVG 2具有isPointInFill()
方法。您可以调用每个形状以查看点是否在路径的填充范围内。但是我相信只有Chrome和Opera才实现了SVG2的这一新功能。
https://developer.mozilla.org/en-US/docs/Web/API/SVGGeometryElement/isPointInFill
您可以将SVG绘制到画布上,并使用isPointInPath()
方法。
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/isPointInPath
您可以将SVG绘制到画布上,并使用getImageData()
方法获取该特定像素的颜色。
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData
当然,您也可以通过某种方式自己计算来数字地进行计算。
答案 1 :(得分:1)
这是使用保罗·勒博的答案。
首先是一个演示,您在其中检查该点是否在某个路径中,在这种情况下为#c
路径。
请阅读我的代码中的注释。
// creating a new SVG point
let point = svg.createSVGPoint()
point.x = 300;
point.y = 300;
//checking if the point is in the path c
console.log(c.isPointInFill(point));
svg{border:1px solid}
<svg id="svg" viewBox="0 0 606.731 526.504" width="200" >
<polygon id="a" fill="#D9D1E0" stroke="#020202" stroke-miterlimit="10" points="300.862,1.001 0.862,526.001 605.862,526.001 "/>
<polygon id="b" fill="#926BB5" stroke="#020202" stroke-miterlimit="10" points="289.576,19.681 442.34,283.546 411.092,343.437
515.705,526.001 428.453,525.716 337.314,365.138 385.054,280.945 262.668,66.555 "/>
<polygon id="c" fill="#8ED5ED" stroke="#020202" stroke-miterlimit="10" points="334.4,193.005 384.186,280.946 337.315,364.272
428.453,525.716 142.019,525.716 "/>
<circle cx="300" cy="300" r="5" fill="red" />
</svg>
第二个演示,其中我在画布上绘制多边形并使用上下文的方法isPointInPath()
:
请阅读我的代码中的注释。
let ctx = canv.getContext("2d");
canv.width = 606.731;
canv.height = 526.504;
// the main triangle
let duval = [300.862, 1.001, 0.862, 526.001, 605.862, 526.001];
// the arrays of points for the 2 polygons inside the main triangle
let rys = [
[
289.576,
19.681,
442.34,
283.546,
411.092,
343.437,
515.705,
526.001,
428.453,
525.716,
337.314,
365.138,
385.054,
280.945,
262.668,
66.555
],
[
334.4,
193.005,
384.186,
280.946,
337.315,
364.272,
428.453,
525.716,
142.019,
525.716
]
];
// drawing the polygons
drawPoly(duval, "#D9D1E0");
drawPoly(rys[0], "#926BB5");
drawPoly(rys[1], "#8ED5ED");
// the point to check
let p = { x: 300, y: 300 };
drawPoint(p);
// looping through the array of shapes to check if the point is in path
for (let i = 0; i < rys.length; i++) {
// draw again the polygon without stroking or filling
drawPoly(rys[i]);
//chect if the point is in path
if (ctx.isPointInPath(p.x, p.y)) {
// do something
console.log(i);
// if found break the loop
break;
}
}
// a function to draw a polygon from an array
function drawPoly(ry, color) {
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(ry[0], ry[1]);
for (let i = 2; i < ry.length; i += 2) {
ctx.lineTo(ry[i], ry[i + 1]);
}
ctx.closePath();
if (color) {
ctx.fill();
ctx.stroke();
}
}
function drawPoint(p) {
ctx.fillStyle = "red";
ctx.beginPath();
ctx.arc(p.x, p.y, 5, 0, 2 * Math.PI);
ctx.fill();
}
canvas{border:1px solid}
<canvas id="canv"></canvas>
这次使用getImageData()
方法获取该点的像素颜色。
该代码类似于上一个示例中的代码
let ctx = canv.getContext("2d");
canv.width = 606.731;
canv.height = 526.504;
let duval = [300.862, 1.001, 0.862, 526.001, 605.862, 526.001];
let rys = [
[
289.576,
19.681,
442.34,
283.546,
411.092,
343.437,
515.705,
526.001,
428.453,
525.716,
337.314,
365.138,
385.054,
280.945,
262.668,
66.555
],
[
334.4,
193.005,
384.186,
280.946,
337.315,
364.272,
428.453,
525.716,
142.019,
525.716
]
];
drawPoly(duval, "#D9D1E0");
drawPoly(rys[0], "#926BB5");
drawPoly(rys[1], "#8ED5ED");
function drawPoly(ry, color) {
ctx.fillStyle = color;
ctx.beginPath();
ctx.moveTo(ry[0], ry[1]);
for (let i = 2; i < ry.length; i += 2) {
ctx.lineTo(ry[i], ry[i + 1]);
}
ctx.closePath();
if (color) {
ctx.fill();
ctx.stroke();
}
}
// HERE BEGINS THE IMPORTANT PART
let imgData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
let p = { x: 300, y: 300 };
// mark the point with an empty circle
ctx.beginPath();
ctx.arc(p.x,p.y,5,0,2*Math.PI);
ctx.stroke();
// the index of the point p in the imgData.data array
let index = (p.y*imgData.width + p.x)*4;
//the red,green and blue components of the color of the pixel at the index
let r = imgData.data[index];
let g = imgData.data[index + 1];
let b = imgData.data[index + 2];
//test the color
test.style.background = `rgb(${r},${g},${b})`;
canvas{border:1px solid}
#test{width:50px; height:50px; border:1px solid;}
<canvas id="canv"></canvas>
<div id="test"></div>