2013-05-28 58 views
30

如何檢測用戶在紅色泡泡內點擊的時間?檢測用戶是否在圓圈內點擊

它不應該像一個方形領域。鼠標必須是真正的圈內:

img

下面的代碼:

<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> 
+1

如果您知道光標和圓的位置和大小的位置(和它真的是一個圓,沒有省略號),它只是一個簡單的幾何計算來確定點(光標)是否在圓內。 http://stackoverflow.com/questions/481144/equation-for-testing-if-a-point-is-inside-a-circle – qJake

+0

聽說過竇和餘弦......? – CBroe

+1

@CBroe Trig在這種情況下不需要,也不會有用。 –

回答

45

的圓,是其距離從一箇中心點等於某一所有點的幾何位置數字「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)) < r翻譯爲:

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

在JavaScript中。

現在你知道所有這些值(x0,y0)bubble.xbubble.y(x1,y1)xy

+0

p1是你圓圈的中心(你已經通過寬度/ 2和高度/ 2來計算)。 p2是當前鼠標位置,您正在檢查該圓圈。 –

3

纔算鼠標指針和您的圈子的中心之間的distance,然後再決定是否它的內部:

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

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

Demo

正如評論mentioned,消除Math.sqrt()你可以使用:

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

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

你甚至可以通過如下測試來切出「昂貴」的Math.sqrt:dx * dx + dy * dy markE

+0

@markE優點:)謝謝! –

2

一個替代方案(並不總是有用的意思,它會y工作的最後路徑(重新)定義,但我把它作爲一個選項):

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

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

路可以btw。是任何形狀。

有關詳細信息:
http://www.w3.org/TR/2dcontext/#dom-context-2d-ispointinpath

+0

對於包含任何路徑的答案+1。一定要提到要測試的路徑必須在使用isPointInPath進行命中測試之前進行定義(或重新定義)。 – markE

26

測試一個點一個圓圈內,你要確定給定的點與圓心之間的距離小於半徑這個圈子。

除了使用包含使用(慢)平方根的點距離公式之外,還可以比較點之間的非平方根(或平方)距離。如果這個距離小於半徑平方,那麼你在!

// 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 PERF測試:

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

+1

感謝您製作這種可讀且可重複使用的代碼。就性能測試而言,在現代瀏覽器中,似乎使用平方根更快。 – pedalpete

相關問題