Получение местоположения мыши на холсте [дубликат]
-
12-09-2019 - |
Вопрос
На этот вопрос уже есть ответ здесь:
Есть ли способ получить указатель мыши местоположения внутри <canvas>
пометка?Я хочу, чтобы местоположение относительно верхнего правого угла <canvas>
, а не на всей странице.
Решение
Вероятно, самый простой способ - добавить прослушиватель событий onmousemove к элементу canvas, и тогда вы сможете получить координаты относительно canvas из самого события.
Это тривиально выполнить, если вам нужно поддерживать только определенные браузеры, но между ними есть различия, например.Opera и Firefox.
Что-то подобное должно сработать для этих двоих:
function mouseMove(e)
{
var mouseX, mouseY;
if(e.offsetX) {
mouseX = e.offsetX;
mouseY = e.offsetY;
}
else if(e.layerX) {
mouseX = e.layerX;
mouseY = e.layerY;
}
/* do something with mouseX/mouseY */
}
Другие советы
Принятый ответ не будет работать каждый раз.Если вы не используете относительное положение, атрибуты offsetX и offsetY могут ввести в заблуждение.
Вы должны использовать функцию: canvas.getBoundingClientRect()
из API canvas.
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
canvas.addEventListener('mousemove', function(evt) {
var mousePos = getMousePos(canvas, evt);
console.log('Mouse position: ' + mousePos.x + ',' + mousePos.y);
}, false);
Также обратите внимание, что вам понадобится CSS:
положение:относительный;
установите в свой тег canvas, чтобы получить относительное положение мыши внутри canvas.
И смещение изменяется, если есть граница
Я поделюсь самым пуленепробиваемым кодом мыши, который я создал на данный момент.Он работает во всех браузерах со всеми видами отступов, полей, границ и дополнений (например, верхняя панель stumbleupon).
// Creates an object with x and y defined,
// set to the mouse position relative to the state's canvas
// If you wanna be super-correct this can be tricky,
// we have to worry about padding and borders
// takes an event and a reference to the canvas
function getMouse = function(e, canvas) {
var element = canvas, offsetX = 0, offsetY = 0, mx, my;
// Compute the total offset. It's possible to cache this if you want
if (element.offsetParent !== undefined) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
} while ((element = element.offsetParent));
}
// Add padding and border style widths to offset
// Also add the <html> offsets in case there's a position:fixed bar (like the stumbleupon bar)
// This part is not strictly necessary, it depends on your styling
offsetX += stylePaddingLeft + styleBorderLeft + htmlLeft;
offsetY += stylePaddingTop + styleBorderTop + htmlTop;
mx = e.pageX - offsetX;
my = e.pageY - offsetY;
// We return a simple javascript object with x and y defined
return {x: mx, y: my};
}
Вы заметите, что я использую некоторые (необязательные) переменные, которые не определены в функции.Они такие:
stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10) || 0;
stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10) || 0;
styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10) || 0;
styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10) || 0;
// Some pages have fixed-position bars (like the stumbleupon bar) at the top or left of the page
// They will mess up mouse coordinates and this fixes that
var html = document.body.parentNode;
htmlTop = html.offsetTop;
htmlLeft = html.offsetLeft;
Я бы рекомендовал вычислить их только один раз, именно поэтому они не находятся в getMouse
функция.
Для определения положения мыши я обычно использую jQuery, поскольку он нормализует некоторые атрибуты события.
function getPosition(e) {
//this section is from http://www.quirksmode.org/js/events_properties.html
var targ;
if (!e)
e = window.event;
if (e.target)
targ = e.target;
else if (e.srcElement)
targ = e.srcElement;
if (targ.nodeType == 3) // defeat Safari bug
targ = targ.parentNode;
// jQuery normalizes the pageX and pageY
// pageX,Y are the mouse positions relative to the document
// offset() returns the position of the element relative to the document
var x = e.pageX - $(targ).offset().left;
var y = e.pageY - $(targ).offset().top;
return {"x": x, "y": y};
};
// now just make sure you use this with jQuery
// obviously you can use other events other than click
$(elm).click(function(event) {
// jQuery would normalize the event
position = getPosition(event);
//now you can use the x and y positions
alert("X: " + position.x + " Y: " + position.y);
});
Это работает у меня во всех браузерах.
Редактировать:
Я скопировал код из одного из моих классов, которые я использовал, поэтому вызов jQuery для this.canvas
был неправ.Обновленная функция определяет, какой элемент DOM (targ
) вызвал событие, а затем использует смещение этого элемента для определения правильного положения.
НУ И ДЕЛА это бесконечно полезная библиотека для устранения проблем с canvas, включая расположение мыши.
Простой подход с использованием события мыши и свойств холста:
Демонстрация функциональности JSFiddle http://jsfiddle.net/Dwqy7/5/
(Примечание:границы не учитываются, что приводит к постепенному):
Добавьте событие мыши к вашему холсту
canvas.addEventListener("mousemove", mouseMoved);
Отрегулируйте
event.clientX
иevent.clientY
основанный на:
canvas.offsetLeft
window.pageXOffset
window.pageYOffset
canvas.offsetTop
Таким образом:canvasMouseX = event.clientX - (canvas.offsetLeft - window.pageXOffset); canvasMouseY = event.clientY - (canvas.offsetTop - window.pageYOffset);
В исходном вопросе запрашивались координаты в правом верхнем углу (вторая функция).Эти функции должны находиться в пределах области, в которой они могут получить доступ к элементу canvas.
0,0 в верхнем левом углу:
function mouseMoved(event){
var canvasMouseX = event.clientX - (canvas.offsetLeft - window.pageXOffset);
var canvasMouseY = event.clientY - (canvas.offsetTop - window.pageYOffset);
}
0,0 в правом верхнем углу:
function mouseMoved(event){
var canvasMouseX = canvas.width - (event.clientX - canvas.offsetLeft)- window.pageXOffset;
var canvasMouseY = event.clientY - (canvas.offsetTop - window.pageYOffset);
}
Я бы использовал jQuery.
$(document).ready(function() {
$("#canvas_id").bind( "mousedown", function(e){ canvasClick(e); } );
}
function canvasClick( e ){
var x = e.offsetX;
var y = e.offsetY;
}
Таким образом, ваш холст может находиться в любом месте вашей страницы, относительном или абсолютном.
Вычтите смещения X и Y элемента canvas DOM из положения мыши, чтобы получить локальное положение внутри canvas.