Вопрос по javascript, html5, canvas – Получение местоположения мыши на холсте

43

Есть ли способ, чтобы получить местоположение мыши внутри<canvas> тег? Я хочу расположение относительно верхнего правого угла<canvas>, а не всю страницу.

Ваш Ответ

9   ответов
41

возможно, добавить слушатель события onmousemove к элементу canvas, и тогда вы сможете получить координаты относительно холста из самого события.

Это тривиально, если вам нужно только поддерживать определенные браузеры, но между f.ex есть различия. 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 */
}
Я настоятельно рекомендую использовать JQuery или какую-либо другую инфраструктуру javascript, которая стандартизирует смещения. Soviut
Это сработало только для меня, если я установил положение холста относительно, как предложено Нат. Richard Garside
@ Ричард - Это потому чтоlayerX а такжеlayerY относятся к документ на пенсию для непозиционированных элементов. Смотрите мой ответ здесь для получения дополнительной информации: / Stackoverflow.com вопросы / 5085689 / ... Wayne Burkett
Если e.offsetX определен, но равен 0, то этот код делает неправильную вещь. prideout
35

носительную позицию, атрибуты offsetX и offsetY могут вводить в заблуждение.

Вы должны использовать функцию:canvas.getBoundingClientRect() из холста API.

  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);
Niceeeeeeeeeeeee funky-nd
это должен быть принятый ответ Buxtehude
22

position: относительный;

установите для вашего тега холста, чтобы получить относительную позицию мыши внутри холста.

И смещение меняется, если есть граница

изучал интернет, чтобы выяснить, почему Firefox (7) сообщал о странном значении для слоя Y - это исправило это, большое спасибо! Mikey
Спасибо! Это была моя проблема. garg
Спасибо, я получал разные значения до этого. Neelam
+ 1 Это исправило проблему смещения в 5-10 пикселей, которая была у меня в FF 11. Спасибо! Mike Moore
Это не тоттольк илинеобходим способ сделать это. Что это за ответдолже объяснил, чтоe.layerX а такжеe.layerY относительно холста, когда он является позиционированным элементом, но относительно всего документа, когда это не так. Обратите внимание, что эти свойства не являются частью какого-либо стандарта. Есть лучшие способы сделать это. Wayne Burkett
16

который я когда-либо создавал. Он работает во всех браузерах со всеми видами отступов, полей, границ и надстроек (например, верхняя панель 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 функция.

замечательный метод полезности. Я думаю, что в большинстве случаев вам не нужно каждый раз вычислять смещения холста. uchamp
7

поскольку он нормализует некоторые атрибуты события.

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);
});

Это работает для меня во всех браузерах.

РЕДАКТИРОВАТЬ

Я скопировал код из одного из моих классов, которые я использовал, поэтому вызов jQuerythis.canvas был неправ. Обновленная функция определяет, какой элемент DOM targ) вызвал событие и затем использует смещение этого элемента, чтобы выяснить правильную позицию.

6

GEE - это бесконечно полезная библиотека для сглаживания проблем с холстом, включая расположение мыши.

Эта библиотека была великолепна, спасибо за ссылку. justanotherhobbyist
GEE больше не поддерживается и переименовывается разработчиком (-ями) как «полностью устарела». b1nary.atr0phy
2
Простой подход с использованием мышиных свойств и свойств холста:

http: //jsfiddle.net/Dwqy7/5
(Примечание: границы не учитываются, что приводит к смещению на единицу):

Добавьте событие мыши на свой холст
canvas.addEventListener("mousemove", mouseMoved);

Отрегулируйтеevent.clientX а такжеevent.clientY основано на:
canvas.offsetLeft
window.pageXOffset
window.pageYOffset
canvas.offsetTop
Thus:

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);
}
Off-by-1-pixel - ваша граница в 1 пиксель (границы и отступы учитываются). Вы также должны учитывать прокрутку ... Ура! : -) markE
@ markE Спасибо за внимание; Я изменил код выше и в JSFiddle для учета прокрутки. Я не смог найти способ отрегулировать границы холста. Keving
1

Я бы использовал jQuery.

$(document).ready(function() {

    $("#canvas_id").bind( "mousedown", function(e){ canvasClick(e); } );

}

function canvasClick( e ){

    var x = e.offsetX;
    var y = e.offsetY;

}

Таким образом, ваш холст может быть где угодно на вашей странице, относительным или абсолютным.

-1

чтобы получить локальную позицию внутри холста.

Как вы получаете X и Y элемента Canvas dom таким образом, чтобы он работал во всех браузерах? Richard Garside
Всегда приятно видеть кого-то с 18k представителем, который раздает койки ... b1nary.atr0phy
Разум говорил мне, почему мой совет "койка"? Как вы думаете, это неправильно, недостаточно подробно и т. Д.? Это было бы намного полезнее. Кроме того, мой представитель не обязательно означает, что мои ответы будут идеальными, поэтому существует система голосования. Не согласны? Тогда проголосуй. Soviut
Можете ли вы объяснить, что я должен добавить к ответу, чтобы сделать его лучше. Я согласен, что это довольно общий вопрос и, возможно, нужен пример кода и т. Д. Но до сих пор люди только что сказали «не очень хороший ответ Soviut
Вы можете добавить, как получить позицию (x, y) из элемента DOM. Ramy Al Zuhouri

Похожие вопросы