【问题标题】:Detect if user clicks inside a circle检测用户是否在圆圈内点击
【发布时间】:2013-05-23 11:18:17
【问题描述】:

如何检测用户何时在红色气泡内点击?

它不应该是一个方形的场地。鼠标必须真的在圆圈内:

代码如下:

<canvas id="canvas" width="1000" height="500"></canvas>
<script>
var canvas = document.getElementById("canvas")
var ctx = canvas.getContext("2d")

var w = canvas.width
var h = canvas.height

var bubble = {
  x: w / 2,
  y: h / 2,
  r: 30,
}

window.onmousedown = function(e) {
    x = e.pageX - canvas.getBoundingClientRect().left
    y = e.pageY - canvas.getBoundingClientRect().top

    if (MOUSE IS INSIDE BUBBLE) {
        alert("HELLO!")
    }
}

ctx.beginPath()
ctx.fillStyle = "red"
ctx.arc(bubble.x, bubble.y, bubble.r, 0, Math.PI*2, false)
ctx.fill()
ctx.closePath()
</script>

【问题讨论】:

  • 如果你知道光标的位置和圆的位置和大小(而且它确实是圆,不是省略号),那么只要简单的几何计算就可以确定点(光标)是否在圆圈内。 stackoverflow.com/questions/481144/…
  • 听说过 sinus 和 cosinus ...?
  • @CBroe Trig 在这种情况下不需要,也不会有用。
  • 不知道为什么会被赞成。它没有显示任何研究工作,并且已经被问多次次。投票结束。

标签: javascript html events canvas click


【解决方案1】:

要测试一个点是否在一个圆内,您需要确定给定点与圆心之间的距离是否小于圆的半径。

您可以比较点之间的非平方根(或静止平方)距离,而不是使用涉及使用(慢)平方根的点距离公式。如果该距离小于半径平方,那么你就在里面!

// x,y is the point to test
// cx, cy is circle center, and radius is circle radius
function pointInCircle(x, y, cx, cy, radius) {
  var distancesquared = (x - cx) * (x - cx) + (y - cy) * (y - cy);
  return distancesquared <= radius * radius;
}

(不使用您的代码,因为我想为以后来此问题的围观者保留通用功能)

这理解起来稍微复杂一些,但速度也更快,如果您打算在绘图/动画/对象移动循环中检查圆内点,那么您会希望以最快的方式进行.

相关JS性能测试:

http://jsperf.com/no-square-root

【讨论】:

  • 感谢您制作这样可读和可重用的代码。只是关于性能测试的说明,在现代浏览器中,使用平方根似乎稍微快一点。
【解决方案2】:

只需计算鼠标指针和圆心之间的distance,然后判断它是否在里面:

var dx = x - bubble.x,
dy = y - bubble.y,
dist = Math.sqrt(dx * dx + dy * dy);

if (dist < bubble.r) {
  alert('hello');
}

Demo

作为 cmets 中的mentioned,要消除Math.sqrt(),您可以使用:

var distsq = dx * dx + dy * dy,
rsq = bubble.r * bubble.r;

if (distsq < rsq) {
   alert('HELLO');
}

【讨论】:

  • 你甚至可以通过这样的测试去掉“昂贵的”Math.sqrt:dxdx+dydy
【解决方案3】:

另一种选择(并不总是有用,这意味着它仅适用于(重新)定义的最后一条路径,但我将其作为一个选项提出):

x = e.pageX - canvas.getBoundingClientRect().left
y = e.pageY - canvas.getBoundingClientRect().top

if (ctx.isPointInPath(x, y)) {
    alert("HELLO!")
}

路径可以顺便说一句。可以是任何形状。

更多详情:
http://www.w3.org/TR/2dcontext/#dom-context-2d-ispointinpath

【讨论】:

  • +1 表示包含任何路径的答案。请务必提及,必须在使用 isPointInPath 进行命中测试之前定义(或重新定义)要测试的路径。
【解决方案4】:

圆,是到中心点的距离等于某个数字“R”的所有点的几何位置。

您想找到距离小于或等于我们的半径“R”的点。

二维欧几里得空间中的距离方程为d(p1,p2) = root((p1.x-p2.x)^2 + (p1.y-p2.y)^2)

检查p与圆心的距离是否小于半径。

假设我有一个半径为r 的圆,中心位于(x0,y0) 位置和一个点(x1,y1),我想检查该点是否在圆内。

我需要检查 d((x0,y0),(x1,y1)) &lt; r 是否转换为:

Math.sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0)) < r

在 JavaScript 中。

现在您知道所有这些值 (x0,y0)bubble.xbubble.y(x1,y1)xy

【讨论】:

  • p1 是你的圆的中心(你已经通过宽度/2 和高度/2 计算出来了)。 p2 是您针对圆圈检查的当前鼠标位置。
猜你喜欢
  • 1970-01-01
  • 2016-02-08
  • 2015-07-02
  • 1970-01-01
  • 2020-11-25
  • 2013-01-13
  • 1970-01-01
  • 2012-08-29
相关资源
最近更新 更多