JavaScript 相対的なマウス位置を取得する

phiary に引っ越しました. 毎日プログラミングやWebに関する情報を発信しています! RSS 登録してたまに覗いたり, tweet やハテブして拡散してもらえると幸いです.

Pocket

canvasでゲームを作る際に、canvasの左上を基準としたマウス位置を
取得する処理が必要になることが多々あったのでその方法をメモっておきます。

Sample

canvas内にマウスを乗せるとその位置が表示されます。
左上にマウスを置くと Mouse X, MouseY が (0, 0) に、
右下にマウスを置くと (640, 480) になるのがわかると思います。

http://tmlife.net/examples/mouse-pos/

Source

流れ
  1. 相対位置を取得したい要素に”mousemove”イベントを登録
  2. その中で、コールバックの引数eを使用し”スクリーンを基準とした位置(e.client)”と、”要素の位置(getBoundingClientRect)”を取得する
  3. “スクリーンを基準とした位置”から”要素の位置”を引くことで相対位置を求める

たったこれだけです。肝になるのはgetMousePosOnElement()内の
getBoundingClientRect()です。

詳しくはソースのscriptタグ内のコメントで書いています。

<!DOCTYPE html> 
<html lang="ja"> 
    <head> 
        <meta charset="utf-8"> 
        <title>Mouse Pos</title>
        
        <style>
            #canvas {
                border: solid 1px #000;
                margin: 32px;
            }
        </style>
        
        <script type="text/javascript">
            
            var $id = function(id){ return document.getElementById(id); };
            
            var canvas = null;              // キャンバス
            var g = null;                   // コンテキスト
            var mouse = { x: null, y:null };// マウス
            
            window.onload = function()
            {
                canvas = $id("canvas");
                g = canvas.getContext("2d");
                
                // 要素の上でマウスが動いた際の処理
                canvas.addEventListener("mousemove", function(e){
                    // マウス位置を更新
                    getMousePosOnElement(e);
                    // 描画
                    draw();
                }, false);
                
                // 要素からマウスが出た際の処理
                canvas.addEventListener("mouseout", function(e){
                    mouse.x = "none";
                    mouse.y = "none";
                    draw();
                }, false);
            };
            
            /**
             * マウス位置を取得
             * @param {Object} e
             */
            var getMousePosOnElement = function(e)
            {
                // getBoundingClientRectはtargetが占める領域、
                // つまり親要素によるズレと自身のmarginを含めた値を返す
                // この値をグローバルなマウス値(e.clientX, e.clientY)から
                // 引いてやることで相対的なマウス位置を取得する
                // ただし、自身のpaddingとborderは考慮してくれないみたいなので、
                // 0か1pxにしておくことをオススメします
                var rect = e.target.getBoundingClientRect();
                mouse.x = e.clientX - rect.left;
                mouse.y = e.clientY - rect.top;
                
                return mouse;
            };
            
            /**
             * マウス位置の点と、マウスの情報を表示
             */
            var draw = function()
            {
                // クリア
                g.clearRect(0, 0, canvas.width, canvas.height);
                
                // マウスの位置にマルを描画
                g.fillStyle = "rgba(255, 0, 0, 1.0)";
                g.beginPath();
                g.arc(mouse.x, mouse.y, 16, 0, Math.PI*2, false);
                g.fill();
                
                // マウスの情報を表示
                g.fillStyle = "rgba(0, 0, 0, 1.0)";
                g.fillText("Canvas Width : "+canvas.width, 8, 16);
                g.fillText("Canvas Height: "+canvas.height, 8, 32);
                g.fillText("Mouse X : "+mouse.x, 8, 48);
                g.fillText("Mouse Y : "+mouse.y, 8, 64);
            };
            
        </script>

    </head>
    
    <body>
        
        <h1>Mouse Pos</h1>
        <p>
            特定の要素を基準としたマウスの位置を取得します。<br />
            主にcanvasでゲームを作る際に使えると思います。<br />
        </p>
        <p style="color:red">
            ※paddingやborderを指定している場合その分ずれてしまうので、
            基本0か1pxに指定しておくことをオススメします。
        </p>
        
        <canvas id="canvas" width=640 height=480></canvas>
        
    </body>
</html>
    

TRACK BACK URL

POST COMMENT

メールアドレスが公開されることはありません。

COMMENT