web関連
【javascript,HTML5】canvas上のクリックをした位置に点を描画する方法
canvas上でクリックをしたら点がつくみたいなことをしたかったときの備忘録
ソースコード
<canvas id="canvas" width="500" height="3500"></canvas>
<script>
window.onload = () =>{
// キャンパスの要素を取得
const canvas = document.getElementById('canvas');
// 2次元の描画を行うメソッド
const ctx = canvas.getContext('2d');
// 座標とcanvasサイズを入れる用の変数
let x = 0;
let y = 0;
let w = canvas.width;
let h = canvas.height;
// 背景塗る
ctx.fillStyle = '#ccc';
// fillRect(x座標, y座標, 幅, 高さ)
ctx.fillRect(0, 0, w, h);
// es6以前の書き方:function onClick (e) {…}
let onClick = (e) => {
let rect = e.target.getBoundingClientRect();
// e.clientX(Y)がwindow左上からのクリックされた座標
// rect.left(top)がwindow左上からのcanvasの座標
x = e.clientX - rect.left;
y = e.clientY - rect.top;
draw();
}
// es6以前の書き方:function draw() {…}
const draw = () => {
// canvasで背景色つけてるとclearRectで初期化すると真っ白になっちゃうのでfillRectで初期化(塗りつぶし)
ctx.fillStyle = '#ccc';
ctx.fillRect(0, 0, w, h);
// 背景色が真っ白ならclearRectでもいいと思う
// ctx.clearRect(0, 0, w, h);
// クリックされた位置に描画処理
ctx.fillStyle = '#000';
// fillRect(x座標, y座標, 幅, 高さ)
ctx.fillRect(x, y, 10, 10);
}
canvas.addEventListener('click', onClick, false);
};
</script>
クリックされた位置に10pxの正方形を描画
再度クリックされたらfillRect()
でcanvasを塗りつぶしてから新しい点を描画
clientX(Y)とgetBoundingClientRect()の違い
clientX(Y)
window左上からのクリックされた座標を取得、canvasの高さが画面サイズ以上ありスクロールが発生してもWindow左上からの距離でを返すね(返す値がブラウザの画面サイズを超えることはない)
getBoundingClientRect()
クリックされた位置じゃなくてクリックされたcanvas自体のwindow左上からの座標を返すから、スクロールでcanvasの上部が隠れるとマイナス値を返すわ
で、それらを
「Window左上からのクリックされた座標(e.client) – Window左上基準のcanvas自体の座標(rect)」
と計算することでドキュメント全体の左上からの座標を取得できるみたい
ちょっと気になったんだけどスクロールしてcanvas最上部が隠れると
rect.top
はマイナス値を返すわけだけど、引き算の「-(マイナス)」と負数の「-(マイナス)」が続くわけで計算ってどうなるんだって結果見たら
// y = e.clientY - rect.top
1200 = 500 - (-700)
って計算結果になった
足し算になるんすね
メモ:canvasにfillRect()で色を入れたときのclearRect()
clearRect()
はcanvasを初期化するときとかに使うわけだけどfillRect()
で色を付けていると真っ白にされちゃうね
色を入れている時はclearRect()
で初期化しないでfillRect()
で上書き(初期化)するのがいいかも
参考:イベント系がまとめられてた
canvasのクリックイベントについてまとめられているわ
今回のコードはほぼここを参考に作った
クリックした後の点ってどうやって描画してんだろうって思って調べた
これと前回の画像比率固定を合わせて画像上のクリックした位置に点をつけて比率を変えても点の位置が写真上の同じ場所に位置し続けるってのやろうと思ったけど、あれはリサイズ時に画像を再描画しているから点消えるわってなった
もしやるのであれば「点描画」と「画像」のレイヤーを分けないと無理だわ
今度はレイヤー分けるやつの勉強しよっと
一個だけ点を描画するように書いている