web-dev-qa-db-ja.com

キャンバスでのマウスの位置の取得

<canvas>タグ内でロケーションマウスを取得する方法はありますか?ページ全体ではなく、<canvas>の右上隅を基準とした相対的な場所が必要です。

43
Sam Lee

最も簡単な方法は、おそらくonmousemoveイベントリスナーをキャンバス要素に追加し、イベント自体からキャンバスに関連する座標を取得することです。

特定のブラウザのみをサポートする必要がある場合、これは簡単に達成できますが、f.exには違いがあります。 OperaおよびFirefox。

このようなものは、これら2つで機能するはずです。

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 */
}
41

受け入れられた答えは毎回機能しません。相対位置を使用しない場合、属性offsetXおよびoffsetYは誤解を招く可能性があります。

キャンバスAPIのcanvas.getBoundingClientRect()関数を使用する必要があります。

  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);
37
AxFab

また、CSSが必要になることに注意してください。

位置:相対;

キャンバス内の相対的なマウス位置を取得するために、キャンバスタグに設定します。

境界線がある場合、オフセットが変更されます

22
Nat

これまでに作成した最も防弾のマウスコードを共有します。すべてのブラウザで機能し、あらゆる種類のパディング、マージン、境界線、アドオン(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関数には含まれていません。

16
Simon Sarris

マウスの位置については、イベント属性の一部を正規化するため、通常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);
});

これはすべてのブラウザで機能します。

編集:

使用していたクラスの1つからコードをコピーしたため、this.canvasへのjQuery呼び出しが間違っていました。更新された関数は、どのDOM要素(targ)がイベントを引き起こしたかを特定し、その要素のオフセットを使用して正しい位置を特定します。

7
miki725

[〜#〜] gee [〜#〜] は、マウスを含むキャンバスの問題をスムーズにするための非常に役立つライブラリです。ロケーション。

6
Collin

マウスイベントとキャンバスプロパティを使用した簡単なアプローチ:

JSFiddle機能のデモ http://jsfiddle.net/Dwqy7/5/
(注:境界線は考慮されないため、1つずれます):

  1. キャンバスにマウスイベントを追加する
    canvas.addEventListener("mousemove", mouseMoved);

  2. 以下に基づいて_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);

元の質問では、右上から座標を求めました(2番目の関数)。これらの関数は、キャンバス要素にアクセスできるスコープ内にある必要があります。

左上に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);
}
_
2
Keving

JQueryを使用します。

$(document).ready(function() {

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

}

function canvasClick( e ){

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

}

このように、キャンバスはページのどこにでも、相対または絶対に配置できます。

1
Joeri