如何获取椭圆边框的坐标

时间:2015-06-05 17:26:23

标签: javascript html html5-canvas

如何获取绘制椭圆边框的所有坐标?我可以用画布画它。

我的想法是获取所有坐标并将它们存储到数组中。单击画布时,我想检查该点是否在椭圆的边框内。

1 个答案:

答案 0 :(得分:0)

重新定义您的路径(不绘制它),然后使用(而不是isPointInPath()):

ctx.isPointInStroke(x, y)

它甚至会考虑笔划的线条粗细。

此解决方案的问题是IE(ie)不支持这些路径检查。为此,您需要一个手动解决方案。但是对于那些(你可以检查这个功能)的浏览器,简单地使用它:

实施例



var ctx = document.querySelector("canvas").getContext("2d");

function getEllipse(ctx, cx, cy, rx, ry) {   // render an ellipse
  var angleStep = 0.05, angle = angleStep;
  ctx.moveTo(cx + rx, cy);                   // start at angle 0
  while(angle < Math.PI*2) {
    ctx.lineTo(
      cx + rx * Math.cos(angle),             // store these to an array as wanted
      cy + ry * Math.sin(angle)
    );
    angle += angleStep
  }
  ctx.closePath();
}

// draw an ellipse:
getEllipse(ctx, 150, 75, 100, 60);
ctx.lineWidth = 10;
ctx.stroke();

// reuse ellipse path when checking for mouse position
ctx.canvas.onmousemove = function(e) {
  ctx.clearRect(0,0,300,150);
  var rect = this.getBoundingClientRect(),    // get adjusted mouse position
      x = e.clientX - rect.left,
      y = e.clientY - rect.top;
  
  ctx.strokeStyle = ctx.isPointInStroke(x, y) ?  "red" : "black";
  
  ctx.stroke();
};
&#13;
<canvas></canvas>
&#13;
&#13;
&#13;

请注意,上下文已经有一个椭圆方法,它还没有最大的支持,但是当它确实存在时,你可以代替沿着椭圆存储每个点,存储中心和半径(它确实支持旋转以及开始和结束角度)。稍后要考虑的事情。

截至2018/9的支持

api.CanvasRenderingContext2D.isPointInStroke                                       
On Standard Track                                                                  
https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/isPointInStroke

DESKTOP >        |Chrome    |Edge      |Firefox   |IE        |Opera     |Safari    
:----------------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:
isPointInStroke  |    Y     |    -     |    Y     |    -     |    Y     |    Y     

MOBILE >         |Chrome/A  |Edge/mob  |Firefox/A |Opera/A   |Safari/iOS|Webview/A 
:----------------|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:
isPointInStroke  |    Y     |    Y     |    Y     |    Y     |    Y     |    Y

Data from MDN - "npm i -g mdncomp" (c) epistemex                                   

对于这些浏览器,您可以使用this polyfill

其他替代方案是使用线路交叉。迭代您的数组并检查每个线段与从中心到鼠标的线。你会得到一个x / y坐标,然后对厚度进行半径检查(你可以通过选择最接近角度的线来进行优化等)。

如何在this answer (getIntersection)中找到行交叉点。