2011-01-31 17 views
8

私はjqueryとhtml5キャンバスを勉強しています。私がしたいのは単純なhtml5の描画例です。マウスが動くと、マウスの下に赤い四角形が描かれます。キャンバス内でjavascriptでマウス位置を取得

私のコードは単純ですが、キャンバス内でマウスカーソルの位置を取得するのに問題があります。

今、x = event.offsetX;を使用しています。マウスの位置を取得します。これはクロムでうまく動作しますが、firefoxの場合は動作しません。コードをx = event.layerXに変更しました。レイヤーXは、キャンバスの位置ではなく、ウェブページに対する私のマウスの位置であるようです。私はいつもオフセットを見るからです。

私は最初に、firefoxの下で正しいマウスの位置を得るために行うべき正しいことは何ですか。第二に、どうすればfirefox、chrome、safari、operaのために動作するコードを書くことができますか?あなたは、互換性を心配する必要はありません

<!doctype html /> 
<html><head> 
<script type="text/javascript" src="jquery.js"></script> 
<script type="text/javascript"> 
    $(document).ready(
function(){ 

var flip = document.getElementById('flip'); 
    var context = flip.getContext('2d'); 
context.fillStyle = "rgb(255,255,255)"; 
context.fillRect(0, 0, 500, 500); 

     $("a").click(function(event){alert("Thanks for visiting!");}); 
    $("#flip").mousemove(function(event){ 
     var x, y; 


    x = event.layerX; 
    y = event.layerY; 


    //alert("mouse pos"+event.layerX); 
    var flip = document.getElementById('flip'); 
    var context = flip.getContext('2d'); 
context.fillStyle = "rgb(255,0,0)"; 
context.fillRect(x, y, 5, 5); 
    } 
    ); 
    } 
);  
    </script> 
    </head> <body bgcolor="#000000"> <a href="http://jquery.com/">jQuery</a><canvas id="flip" width="500" height="500"> 
    This text is displayed if your browser does not support HTML5 Canvas.</canvas> </body></html> 
+4

'<!doctype html />'は無効であり、多くのDOMの動作を変更するquirksモードを呼び出します。 '<!doctype html>'は正しいDTDです。 –

答えて

8

enter image description here

<!DOCTYPE html> 

<html> 
    <head> 
     <meta charset = "utf-8"> 

     <script> 
      Element.prototype.leftTopScreen = function() { 
       var x = this.offsetLeft; 
       var y = this.offsetTop; 

       var element = this.offsetParent; 

       while (element !== null) { 
        x = parseInt (x) + parseInt (element.offsetLeft); 
        y = parseInt (y) + parseInt (element.offsetTop); 

        element = element.offsetParent; 
       } 

       return new Array (x, y); 
      } 

      document.addEventListener ("DOMContentLoaded", function() { 
       var flip = document.getElementById ("flip"); 

       var xy = flip.leftTopScreen(); 

       var context = flip.getContext ("2d"); 

       context.fillStyle = "rgb(255,255,255)"; 
       context.fillRect (0, 0, 500, 500); 

       flip.addEventListener ("mousemove", function (event) { 
        var x = event.clientX; 
        var y = event.clientY; 

        context.fillStyle = "rgb(255, 0, 0)"; 
        context.fillRect (x - xy[0], y - xy[1], 5, 5); 
       }); 
      });  
     </script> 

     <style> 
      #flip { 
       border: 1px solid black; 
       display: inline-block; 

      } 

      body { 
       text-align: center; 
      } 
     </style> 
    </head> 

    <body> 
     <canvas id = "flip" width = "500" height = "500">This text is displayed if your browser does not support HTML5 Canvas.</canvas> 
    </body> 
</html> 

、唯一のIE(前9)ネイティブにキャンバスをサポートしていません:

は、ここに私のコードです。

+1

この回答は問題を解決しますが、DOMを非現実的に拡張してホイールを再構成します。 –

+4

'<!doctype html />'は無効で、たくさんのDOMの動作を変更するquirksモードを呼び出します! '<!doctype html>'は正しいDTDです。 –

+0

ウィンドウがスクロールアップされていない場合は、leftTopOffset関数がブレークします。 –

2

要素がどこにあるかを調べるためには、カスタム関数が必要です。 Here is an example。これは、quirksモードと私のJavaScriptライブラリからこの関数を使用して、jQueryに変換するのは難しくありません。

function findPos(obj) { 
    var curleft = curtop = 0; 

    if (obj.offsetParent) { 
     do { 
      curleft += obj.offsetLeft; 
      curtop += obj.offsetTop; 
     } while (obj = obj.offsetParent); 

     return [curleft, curtop]; 
    } 
} 

EDIT

これはpageXをサポートしていないため、それにIEで動作しません。これを修正するには、thisのような関数を使ってイベントオブジェクトを渡す必要があります。しかし、2x2p1pによると、キャンバスはバージョン9以下のInternet Explorerではサポートされていません。

15

この件については多くの質問があり、常にDOMをブラウズしたり、offsetXとoffsetYを使用することを提案しています。

canvas 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); 
+1

これはすてきな解決策ですが、キャンバスに枠やパディングが付いている場合は機能しません。 –

+1

getBoundingClientRect()はボーダーボックスの四角形を指定しますが、これはハンドルの位置のスタイリングとスクロールを行う唯一の解決策です同じ方法。 このソリューションでは、次のような醜いコードを使用する必要があります。 parseInt(canvas.style.borderLeftWidth.substring(-2) 私のアドバイス:親divにパディングとボーダーを追加する。 – AxFab

関連する問題