くっそ。
ちょっとハマってしまったのでメモっとく。
HTML5 の canvas でのマウスクリック位置の取得方法。
よく、
canvas 上で取得出来る座標値はブラウザ上の(ブラウザ左上位置からの)座標値。だから、取得した座標値から、canvas 要素開始位置までの幅・高さ(オフセット値)を引かないと、canvas 上の座標の絶対値は取れない。
って説明を見るけど、これでは実際には不十分。
なんでかっていうと、マウスクリック位置の座標値はブラウザのスクロールによって変化するから。
例えば、ブラウザの左上から 縦横 100ピクセルのところから canvas 要素が始まっていたら、canvas 要素の上をクリックして得られる X 値から 100 を引いてやれば canvas の中の座標値は取得できる。
canvas の中の縦横 50ピクセルのところをクリックして得られる X, Y軸の位置はそれぞれ 150になるので、そこからオフセット値の 100を引いてやれば正しい 50という数値が得られるわけである。
x = event.clientX - canvas.offsetLeft;y = event.clientY - canvas.offsetTop;
という感じね。
でも、マウスクリックの座標値って、ホントにブラウザで表示している状態での左上からの位置なので、例えばブラウザを 30ピクセルほど上にスクロールさせたら、canvas の中の縦横 50ピクセルのところをクリックして得られる Y軸の位置は 150から 120に変わるのだ。30ピクセルほどはすでにブラウザの上に隠れてるわけね。
そうすると、上の例だと 150 - 100 で 50というのが正しい「canvas 上での絶対座標値」なのに、マウスクリック座標値が 120になっちゃうので 120 - 100 で 20という誤った数値になってしまうわけだ。
なので、「canvas 上で取得できる座標値からオフセット値を引いたら、実際の canvas 要素条の座標値が取得できる」は、ブラウザがスクロールしておらず、最上部から表示されている場合のみ有効なので、完璧ではないのだ。
じゃあ、どうするかというと、オフセット値ではなく getBoundingClientRect の戻り値を使うのである。
これは実際にブラウザ表示されている状態の canvas 要素の開始位置を取得出来るので(例えば、canvas 要素の上端がブラウザの上端と同じだったら Y 座標値として 0 が取得できる。canvas 要素の上部がブラウザの上に出てしまえばマイナス値が返ってくるので)ブラウザのスクロール状態に関係なく、canvas 上の絶対座標値が取得できるのだ。
var rect = event.target.getBoundingClientRect();x = event.clientX - Math.floor(rect.left);y = event.clientY - Math.floor(rect.top);
みたいな感じね。(小数点で値が返ってくるので、Math.floor メソッドを使ってます)
いやあ、マウスクリックの座標値がブラウザ上の実際の座標値とは思いもしなかったので、すっかりハマってもうたがな(^^;;;
コメントする