【问题标题】:How to determine if a coordinate is inside SVG Close Path?如何确定坐标是否在 SVG 关闭路径内?
【发布时间】:2019-03-21 17:51:25
【问题描述】:

我在 SVG 上设计了一个 Duval's Triangle(一种诊断工具), 不同颜色的段(闭合路径)的组合。 诊断结果将是一个坐标。 需要检测结果坐标在哪个 Closed Path 中?

就像在以下情况下,诊断结果是一个红点。 需要检测关闭路径,即在这种情况下:D2

【问题讨论】:

标签: javascript html svg


【解决方案1】:

您有多种选择:

【讨论】:

    【解决方案2】:

    这是使用 Paul LeBeau 的答案。

    1.

    首先是一个演示,您检查该点是否在某个路径中,在本例中为#c 路径。 请阅读我代码中的 cmets。

    // 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>

    2.

    第二个演示,我在画布上绘制多边形并使用上下文的方法isPointInPath(): 请阅读我代码中的 cmets。

    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}
    &lt;canvas id="canv"&gt;&lt;/canvas&gt;

    3

    这次使用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>

    【讨论】:

    • 非常感谢您的回答,我会尽快尝试您的解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    相关资源
    最近更新 更多