はしくれエンジニアもどきのメモ

情報系技術・哲学・デザインなどの勉強メモ・備忘録です。

JavaScirpt でマウス座標(位置)を取得する

JavaScirpt でマウス座標(位置)を取得する

JavaScirpt でマウス座標(位置)を取得方法をメモ。取得する方法は2 種類あるようです。

(clientX, clientY)(pageX, pageY) の違いと、 (getBoundingClientRect().left[top], getBoundingClientRect().top)(offsetLeft, offsetTop) の違いをまとめておきます。

サンプル

ドラッグでCanvas 上に線を引けるサンプルです。その下にマウスの座標値が表示されます。

cartman0.github.io

コード

JavaScript でマウス座標を取得し、Canvas上に線を描画

clientX[Y] と getBoundingClientRect().left[top]

Canvas 上の座標を求めるコードを以下に示します(サンプルではこちらを使用)。

        

canvas.addEventListener("mousemove", function(e){
 //2.マウスが動いたら座標値を取得
 var rect = e.target.getBoundingClientRect();
 mouse.x = e.clientX - rect.left;
 mouse.y = e.clientY - rect.top;
}

clientX, clientY では、ページのスクロール関係なく、ページ左上部を0 とし、マウスの位置を取得します。 そのため、スクロールして、ページ左上部の座標clientY の値は0 になります。

参考リンク:MouseEvent.clientX - Web API インターフェイス | MDN

getBoundingClientRect().left getBoundingClientRect().top では、 任意のevent が起きたtarget(要素)のBoundingBoxの位置(top, left, right, bottom)を取得できます。 これらの値は、ページのスクロールを考慮した位置です。そのため、スクロールして画面からはみ出た.top の値はマイナス(-)になります。

参考リンク:element.getBoundingClientRect - Web API インターフェイス | MDN

getBoundingClientRect().left[top] の値がスクロールを考慮しているので、 スクロールしてあるcanvas 上でも正しい座標位置が取れ、マウスで描画することができます。

pageX[Y] と offsetLeft[Top]

結論からいうと、MDNでpageX[Y] のページ[UIEvent.pageX - Web API インターフェイス | MDN]を見ると、 unstandard になっているので、使わないほうが良さそうです。

pageX[Y] と offsetLeft[Top] での場合のコードを以下に示します。

        

canvas.addEventListener("mousemove", function(e){
 //2.マウスが動いたら座標値を取得
 mouse.x = e.pageX - canvas.offsetLeft;
 mouse.y = e.pageY - canvas.offsetTop;
}

pageX, pageY は、clientX[Y] とは逆で、スクロールを考慮します。 そのため、スクロールすると左上部のPageY の値は0 とはならず、スクロールする度に大きくなっていきます。

参考リンク:

UIEvent.pageX - Web API インターフェイス | MDN

offsetLeft, offsetTop では、こちらもgetBoundingClientRect().left[top] とは逆で、スクロールを考慮しません。そのため、スクロールしてもoffsetTop の値は変わりません。

参考リンク:Element.offsetLeft - Web API インターフェイス | MDN

まとめ

マウス座標(位置)を取得する場合は、 clientX, clientYgetBoundingClientRect().left, getBoundingClientRect().top の組み合わせを使用するのが良さそうです。