2016-11-30 17 views
1

私はHTML5キャンバス要素で作業しようとしています。私がしようとしていることの1つは、描画やその他の目的のためにキャンバス上でマウスを追跡するmousemoveイベントを設定することです。私は、マウスが終わったキャンバス内のピクセルの正確な座標を取得する方法について決定的な答えを見つけることができませんでした。私はこのHTMLを持っていたウェブ上のチュートリアル(私はレンダリングされたページに、それは明らかにするためにキャンバスに背景色を追加しました)が見つかりました:Javascriptでは、なぜgetBoundingClientRect()が浮動小数点値を返すのですか?

<!DOCTYPE HTML> 
<html> 
    <head> 
    <style> 
     body { 
     margin: 0px; 
     padding: 0px; 
     } 

     #myCanvas { 
     background-color: cornflowerblue; 
     } 
    </style> 
    </head> 
    <body> 
    <canvas id="myCanvas" width="578" height="200"></canvas> 
    <script> 
     function writeMessage(canvas, message) { 
     var context = canvas.getContext('2d'); 
     context.clearRect(0, 0, canvas.width, canvas.height); 
     context.font = '18pt Calibri'; 
     context.fillStyle = 'black'; 
     context.fillText(message, 10, 25); 
     } 
     function getMousePos(canvas, evt) { 
     var rect = canvas.getBoundingClientRect(); 
     return { 
      x: evt.clientX - rect.left, 
      y: evt.clientY - rect.top 
     }; 
     } 
     var canvas = document.getElementById('myCanvas'); 
     var context = canvas.getContext('2d'); 

     canvas.addEventListener('mousemove', function(evt) { 
     var mousePos = getMousePos(canvas, evt); 
     var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y; 
     writeMessage(canvas, message); 
     }, false); 
    </script> 
    </body> 
</html> 

をページがロードされると、あなたのようにキャンバスを参照してくださいページの左上隅に青い矩形が表示されます。マウスを上に移動すると、キャンバス内のテキストが変化し、マウスの位置がXとYのそれぞれに1つの2つの整数として表示されます。

次に、キャンバススタイルを変更して上と下の余白を追加して残りページの内容は変更されません。

#myCanvas { 
    background-color: cornflowerblue; 
    margin-left: 30px; 
    margin-top: 30px; 
} 

キャンバスの青い矩形は、私が予想したようにページの左上からオフセットされていました。しかし、キャンバス上にマウスを置くと、キャンバスに表示されていたXとYのマウス座標が小数点以下の小数点の浮動小数点として表示されていました。コードを少しトレースすると、getBoundingClientRect()は、左上と左の値が浮動小数点数を返すようです。

私はgetBoundingClientRect()によって返される値を切り捨てたり丸めたりすることができますが、間違った方法で私に伝わるように感じます。

何とかgetBoundingClientRect()を間違って使用していますか、浮動小数点値を返す必要がありますか?

さまざまなマウスイベントを聴いているときにキャンバス上にマウスの正確なX座標とY座標を取得する明確な方法がありますか?

答えて

3

tldr;あなたはあなたのブラウザでズーム/ズーム解除を行いました。模倣ザッツこのjsfiddleあなたの問題で

問題

margin-left: 30px; 

ナビゲータズームは(通常の)を100%に設定されているときに自分のコンピュータ上で言ったようにそれが動作していません。しかし、ブラウザをズームインすると、そのような動作に気付くでしょう。

代わり
margin-left: 11%; 

あなたはこのjsfiddleに似%のマージンを使用する場合は、それが戻って浮動マウス位置の天気をズームが上かないんわかります。

答え

ところは、画面に表示されるマウスの位置が計算される:それがピクセルベースであるため、全体の位置座標を有していてもよいです。

しかし、getBoundingClientRectは、マージンやズームなどの修飾子を適用した後、GPUにレンダリングするように指示する前に、ブラウザが「要素の境界線を定義する」と計算して返します。要するに、要素の実際の位置を返します。要素の実際の位置は、後でGPUによって近似され、ピクセルのマトリックス内でレンダリングされます。ピクセルマージン/サイズ/パディング/ etcを使用すると、要素の位置は整数ベースのままですが、em /%の位置決め値をズームまたは使用すると浮動ポジションになることがあります。

ソリューション

  1. ラウンドの境界
  2. は、それが実際に浮動位置であり、それは、それが画面に収まるようにするために、それを丸める必要があるだけのGPUだと仮定し

編集:忘れられた解決策

+0

この質問を見ていましたか? – VSO

+0

あなたの答えを消化しようとしています。しかし、あなたのソリューションから、getBoundingClientRect()が常に「ほぼ丸みを帯びた」浮動小数点を返すとは限りません。この質問があります。マウスを使った正確な衝突検出と、キャンバスに描かれているものをピクセル単位で行う方法はありませんか? – vfs23

+0

キャンバスのCSSサイズは変更されますが、jsサイズではなく、キャンバスにピクセルベースの要素を保存するのが難しいため、後で他の問題が発生することもあります。 –

関連する問題