2013-05-28 5 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», нашего радиуса.

Уравнение расстояния в 2d эвклидовом пространстве - 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.x и bubble.y и (x1,y1) быть x и y.

+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

Альтернатива (не всегда полезно, что это будет onl у работы за последний путь (перо) определена, но я привожу его в качестве опции):

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

+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 тест перфорации:

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

+1

Благодарим за создание такого читаемого и повторно используемого кода. Просто примечание о тестировании производительности в современных браузерах кажется, что использование квадратного корня всегда немного быстрее. – pedalpete

Смежные вопросы