Получение местоположения мыши на холсте

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

Ответы на вопрос(9)

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

 Soviut09 нояб. 2012 г., 00:55
Можете ли вы объяснить, что я должен добавить к ответу, чтобы сделать его лучше. Я согласен, что это довольно общий вопрос и, возможно, нужен пример кода и т. Д. Но до сих пор люди только что сказали «не очень хороший ответ
 Richard Garside09 авг. 2010 г., 12:31
Как вы получаете X и Y элемента Canvas dom таким образом, чтобы он работал во всех браузерах?
 b1nary.atr0phy09 окт. 2012 г., 11:10
Всегда приятно видеть кого-то с 18k представителем, который раздает койки ...
 Soviut09 окт. 2012 г., 22:16
Разум говорил мне, почему мой совет "койка"? Как вы думаете, это неправильно, недостаточно подробно и т. Д.? Это было бы намного полезнее. Кроме того, мой представитель не обязательно означает, что мои ответы будут идеальными, поэтому существует система голосования. Не согласны? Тогда проголосуй.
 Ramy Al Zuhouri10 окт. 2013 г., 13:19
Вы можете добавить, как получить позицию (x, y) из элемента DOM.
Простой подход с использованием мышиных свойств и свойств холста:

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

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

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) вызвал событие и затем использует смещение этого элемента, чтобы выяснить правильную позицию.

Решение Вопроса

возможно, добавить слушатель события 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 */
}
 prideout09 февр. 2013 г., 20:21
Если e.offsetX определен, но равен 0, то этот код делает неправильную вещь.
 Soviut14 июл. 2009 г., 07:22
Я настоятельно рекомендую использовать JQuery или какую-либо другую инфраструктуру javascript, которая стандартизирует смещения.
 Richard Garside09 авг. 2010 г., 12:28
Это сработало только для меня, если я установил положение холста относительно, как предложено Нат.
 Wayne Burkett26 дек. 2011 г., 23:37
@ Ричард - Это потому чтоlayerX а такжеlayerY относятся к документ на пенсию для непозиционированных элементов. Смотрите мой ответ здесь для получения дополнительной информации: / Stackoverflow.com вопросы / 5085689 / ...

носительную позицию, атрибуты 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);
 Buxtehude16 сент. 2016 г., 08:37
это должен быть принятый ответ
 funky-nd07 янв. 2016 г., 10:44
Niceeeeeeeeeeeee

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

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

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

 Neelam11 янв. 2012 г., 08:24
Спасибо, я получал разные значения до этого.
 garg06 янв. 2012 г., 01:04
Спасибо! Это была моя проблема.
 Mikey06 нояб. 2011 г., 02:46
изучал интернет, чтобы выяснить, почему Firefox (7) сообщал о странном значении для слоя Y - это исправило это, большое спасибо!
 Mike Moore25 апр. 2012 г., 06:38
+ 1 Это исправило проблему смещения в 5-10 пикселей, которая была у меня в FF 11. Спасибо!
 Wayne Burkett05 янв. 2014 г., 20:40
Это не тоттольк илинеобходим способ сделать это. Что это за ответдолже объяснил, чтоe.layerX а такжеe.layerY относительно холста, когда он является позиционированным элементом, но относительно всего документа, когда это не так. Обратите внимание, что эти свойства не являются частью какого-либо стандарта. Есть лучшие способы сделать это.

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

 uchamp19 февр. 2015 г., 08:40
замечательный метод полезности. Я думаю, что в большинстве случаев вам не нужно каждый раз вычислять смещения холста.

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

$(document).ready(function() {

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

}

function canvasClick( e ){

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

}

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

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

 justanotherhobbyist10 июл. 2012 г., 12:16
Эта библиотека была великолепна, спасибо за ссылку.
 b1nary.atr0phy09 окт. 2012 г., 11:08
GEE больше не поддерживается и переименовывается разработчиком (-ями) как «полностью устарела».

Ваш ответ на вопрос