次のgifアニメを見てほしい。
これは矢印キーを押しっぱなしにしたときのオブジェクトの動きだ。
わかりづらいかもしれないが、初動(正確には2回目のイベント)が遅れて、「ダッ、ダダダダ…」みたい感じで動いている。
これを解決するための方法をまとめる。
スムーズに動かない場合の実装
先のgifアニメのコードは以下のとおり。
<div class="container">
<div class="box"></div>
</div>
const container = document.querySelector('.container');
const box = document.querySelector('.box');
let x = 0;
let y = 0;
document.body.addEventListener('keydown', e => {
switch (e.key) {
case 'ArrowUp':
x -= 10;
box.style.top = `${x}px`;
break;
case 'ArrowDown':
x += 10;
box.style.top = `${x}px`;
break;
case 'ArrowLeft':
y -= 10;
box.style.left = `${y}px`;
break;
case 'ArrowRight':
y += 10;
box.style.left = `${y}px`;
break;
}
});
イベントハンドラ内で座標のアップデートを行うと、1回目と2回目の実行の間に微妙な間がうまれてしまい、スムーズにオブジェクトを移動させることができない。解決策: スムーズに動かす実装
オブジェクトをスムーズに動かしたい。イメージ的には以下のgifアニメを見てほしい。
おわかりいただけただろうか?
先ほどの動作に比べて初動がスムーズになっているのがわかると思う。
実装は以下のとおり。
const container = document.querySelector('.container');
const box = document.querySelector('.box');
let x = 0;
let y = 0;
let keydown = '';
document.body.addEventListener('keydown', e => {
keydown = e.key;
});
document.body.addEventListener('keyup', e => {
keydown = '';
});
const update = () => {
switch (keydown) {
case 'ArrowUp':
x -= 10;
box.style.top = `${x}px`;
break;
case 'ArrowDown':
x += 10;
box.style.top = `${x}px`;
break;
case 'ArrowLeft':
y -= 10;
box.style.left = `${y}px`;
break;
case 'ArrowRight':
y += 10;
box.style.left = `${y}px`;
break;
}
window.requestAnimationFrame(update);
}
window.requestAnimationFrame(update);
addEventListnerではkeydownまたはkeypressの値を取得するだけ。実際の座標のアップデートはrequestAnimationFrame内で行っている(setTimeoutでも可)
これでキー押しっぱなしでも初動をスムーズにできる。
以上
written by @bc_rikko
0 件のコメント :
コメントを投稿