このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docsコミュニティーについてもっと知り、仲間になるにはこちらから。
高度なアニメーション
前の章では、いくつかの基本的なアニメーションを作成して、物の動かし方を学びました。このパートでは、 運動そのものをより詳細に見て、 アニメーションをより高度にするための物理を追加していきましょう。
In this article
ボールの描画
アニメーションの勉強のために、ボールを使おうと思うので、最初にボールをキャンバス上に描きましょう。以下のコードで設定します。
<canvas width="600" height="300"></canvas>普通通り、まず描画コンテキストが必要になります。ボールを描くため、ball オブジェクトを作成して、プロパティと、キャンバスにボールを描くためのdraw() メソッドを持つようにします。
const canvas = document.getElementById("canvas");const ctx = canvas.getContext("2d");const ball = { x: 100, y: 100, radius: 25, color: "blue", draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); },};ball.draw();ここでは特別なことはなく、ボールは本当に単純な円で、arc() メソッドの助けを借りて描かれています。
速度の追加
ボールができたので、このチュートリアルの前の章で学んだような、基本的なアニメーションを追加する準備ができたことになります。ここでもwindow.requestAnimationFrame() がアニメーションを制御するのに役立っています。ボールは、位置に速度ベクトルを追加することで移動します。また、フレームごとにclear キャンバスに以前のフレームから古い円を削除しています。
const canvas = document.getElementById("canvas");const ctx = canvas.getContext("2d");let raf;const ball = { x: 100, y: 100, vx: 5, vy: 2, radius: 25, color: "blue", draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); },};function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); ball.draw(); ball.x += ball.vx; ball.y += ball.vy; raf = window.requestAnimationFrame(draw);}canvas.addEventListener("mouseover", (e) => { raf = window.requestAnimationFrame(draw);});canvas.addEventListener("mouseout", (e) => { window.cancelAnimationFrame(raf);});ball.draw();境界
境界で衝突テストを行わないと、ボールはすぐにキャンバスから飛び出してしまいます。ボールのx とy の位置がキャンバスの寸法から外れているかどうかをチェックし、速度ベクトルの向きを反転させる必要があります。そのために、draw メソッドに次のようなチェックを追加します。
if ( ball.y + ball.vy > canvas.height - ball.radius || ball.y + ball.vy < ball.radius) { ball.vy = -ball.vy;}if ( ball.x + ball.vx > canvas.width - ball.radius || ball.x + ball.vx < ball.radius) { ball.vx = -ball.vx;}最初のデモ
ここまでで実際にどのように見えるか見てみましょう。
HTML
<canvas width="600" height="300"></canvas>JavaScript
const canvas = document.getElementById("canvas");const ctx = canvas.getContext("2d");let raf;const ball = { x: 100, y: 100, vx: 5, vy: 2, radius: 25, color: "blue", draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); },};function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); ball.draw(); ball.x += ball.vx; ball.y += ball.vy; if ( ball.y + ball.vy > canvas.height - ball.radius || ball.y + ball.vy < ball.radius ) { ball.vy = -ball.vy; } if ( ball.x + ball.vx > canvas.width - ball.radius || ball.x + ball.vx < ball.radius ) { ball.vx = -ball.vx; } raf = window.requestAnimationFrame(draw);}canvas.addEventListener("mouseover", (e) => { raf = window.requestAnimationFrame(draw);});canvas.addEventListener("mouseout", (e) => { window.cancelAnimationFrame(raf);});ball.draw();結果
キャンバスにマウスを移動するとアニメーションを開始します。
加速
動きをよりリアルにするために、例えばこんな風に移動量を変化させることができます。
ball.vy *= 0.99;ball.vy += 0.25;これにより、フレームごとに垂直方向の速度が遅くなり、最終的にボールは床の上でバウンドするだけになります。
第 2 のデモ
HTML
<canvas width="600" height="300"></canvas>JavaScript
const canvas = document.getElementById("canvas");const ctx = canvas.getContext("2d");let raf;const ball = { x: 100, y: 100, vx: 5, vy: 2, radius: 25, color: "blue", draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); },};function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); ball.draw(); ball.x += ball.vx; ball.y += ball.vy; ball.vy *= 0.99; ball.vy += 0.25; if ( ball.y + ball.vy > canvas.height - ball.radius || ball.y + ball.vy < ball.radius ) { ball.vy = -ball.vy; } if ( ball.x + ball.vx > canvas.width - ball.radius || ball.x + ball.vx < ball.radius ) { ball.vx = -ball.vx; } raf = window.requestAnimationFrame(draw);}canvas.addEventListener("mouseover", (e) => { raf = window.requestAnimationFrame(draw);});canvas.addEventListener("mouseout", (e) => { window.cancelAnimationFrame(raf);});ball.draw();結果
後引き効果
これまで、前のフレームをクリアするときはclearRect メソッドを使用していました。このメソッドを半透明のfillRect に置き換えると、簡単に後引き効果を作ることができます。
ctx.fillStyle = "rgb(255 255 255 / 30%)";ctx.fillRect(0, 0, canvas.width, canvas.height);第 3 のデモ
HTML
<canvas width="600" height="300"></canvas>JavaScript
const canvas = document.getElementById("canvas");const ctx = canvas.getContext("2d");let raf;const ball = { x: 100, y: 100, vx: 5, vy: 2, radius: 25, color: "blue", draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); },};function draw() { ctx.fillStyle = "rgb(255 255 255 / 30%)"; ctx.fillRect(0, 0, canvas.width, canvas.height); ball.draw(); ball.x += ball.vx; ball.y += ball.vy; ball.vy *= 0.99; ball.vy += 0.25; if ( ball.y + ball.vy > canvas.height - ball.radius || ball.y + ball.vy < ball.radius ) { ball.vy = -ball.vy; } if ( ball.x + ball.vx > canvas.width - ball.radius || ball.x + ball.vx < ball.radius ) { ball.vx = -ball.vx; } raf = window.requestAnimationFrame(draw);}canvas.addEventListener("mouseover", (e) => { raf = window.requestAnimationFrame(draw);});canvas.addEventListener("mouseout", (e) => { window.cancelAnimationFrame(raf);});ball.draw();結果
マウス制御の追加
ボールに対してちょっとした制御をするために、たとえばmousemove イベントを使用してボールにマウスを追いかけさせるようなことができます。click イベントでボールを解放して、またバウンドさせることもできます。
第 4 のデモ
HTML
<canvas width="600" height="300"></canvas>JavaScript
const canvas = document.getElementById("canvas");const ctx = canvas.getContext("2d");let raf;let running = false;const ball = { x: 100, y: 100, vx: 5, vy: 1, radius: 25, color: "blue", draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); ctx.closePath(); ctx.fillStyle = this.color; ctx.fill(); },};function clear() { ctx.fillStyle = "rgb(255 255 255 / 30%)"; ctx.fillRect(0, 0, canvas.width, canvas.height);}function draw() { clear(); ball.draw(); ball.x += ball.vx; ball.y += ball.vy; if ( ball.y + ball.vy > canvas.height - ball.radius || ball.y + ball.vy < ball.radius ) { ball.vy = -ball.vy; } if ( ball.x + ball.vx > canvas.width - ball.radius || ball.x + ball.vx < ball.radius ) { ball.vx = -ball.vx; } raf = window.requestAnimationFrame(draw);}canvas.addEventListener("mousemove", (e) => { if (!running) { clear(); ball.x = e.clientX; ball.y = e.clientY; ball.draw(); }});canvas.addEventListener("click", (e) => { if (!running) { raf = window.requestAnimationFrame(draw); running = true; }});canvas.addEventListener("mouseout", (e) => { window.cancelAnimationFrame(raf); running = false;});ball.draw();結果
マウスでボールを動かし、クリックでボールを放します。
ブロック崩し
この短い章では、より高度なアニメーションを作成するためのテクニックをいくつか説明するだけです。他にもたくさんあります。パドルやレンガを追加して、このデモをブロック崩しゲームにするのはどうでしょうか?ゲーム開発領域では、ゲーム関連の記事を多数掲載しています。