これまでは、キャンバスの表面の特定の位置に円を描くことができるコードがありましたが、動いているように見せるためには、何度も何度も描き続ける必要があります。動きを滑らかにするために少し位置を変えて、1秒間に60回描くのが目安です(1秒間に60コマというのが人間の目で認識できる最大数だからだと思いますが)。もちろん、別の位置に描画するたびに、古い描画をクリアする必要があります。
アニメーションに適したものにするために、コードを少し変更しましょう。
<script type="text/javascript">
function init()
{
canvas = document.getElementById('canvas');
if(canvas.getContext)
context = canvas.getContext('2d');
else return;
setInterval(draw, 1000 / 60); // 60 times per second
}
function draw()
{
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "rgb(150,29,28)";
// var startPoint = (Math.PI/180)*0; Kinda redundant, it's just 0
// var endPoint = (Math.PI/180)*360; Again, it's just PI times 2
context.beginPath();
context.arc(200, 200, 150, 0, Math.PI * 2, true);
context.fill();
context.closePath();
}
</script>
</head>
<body onload="init();">
<canvas id="canvas" width="500" height="500"></canvas><br>
オブジェクトを定点に向かって移動させる面白い方法はたくさんありますが、最も簡単なのは、もちろん、直線に沿って移動することです。そのためには、
- オブジェクトの現在位置を含むベクトル
- オブジェクトのターゲット位置を含むベクトル
手元にあるようにコードを変更しましょう
var canvas, context,
position = {x: 200, y: 200},
target = {x: 400, y: 400};
function init()
{
...
}
function draw()
{
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "rgb(150,29,28)";
context.beginPath();
context.arc(position.x, position.y, 150, 0, Math.PI * 2, true);
context.fill();
context.closePath();
}
良い!このように、オブジェクトの値の 1 つを変更するたびにposition
、円の位置が影響を受けます。
ターゲット位置から現在位置を差し引くと、現在位置からターゲット位置をまっすぐ指す別のベクトルが得られますよね? そのベクトルを取得し、それを正規化して長さを 1 にすると、結果は実際にはターゲットからオブジェクトの位置までの角度 (コサイン、サイン) になります。つまり、その正規化されたベクトルをオブジェクトの現在の位置に追加すると、オブジェクトは一度に 1 単位ずつターゲット位置に向かって移動します。
ベクトルの正規化は、そのコンポーネントをその長さで単純に割ることです。
function normalize(v)
{
var length = Math.sqrt(v.x * v.x + v.y * v.y);
return {x: v.x / length, y: v.y / length};
}
var step = normalize({x: target.x - position.x, y: target.y - position.y});
OK、あとはオブジェクトの現在の位置にベクトルを追加し続けてstep
、目標位置に到達するだけです。
function normalize(v)
{
var length = Math.sqrt(v.x * v.x + v.y * v.y);
return {x: v.x / length, y: v.y / length};
}
var canvas, context,
position = {x: 200, y: 200},
target = {x: 400, y: 400},
step = normalize({x: target.x - position.x, y: target.y - position.y});
function init()
{
canvas = document.getElementById('canvas');
if(canvas.getContext)
context = canvas.getContext('2d');
else return;
setInterval(draw, 1000 / 60);
}
function draw()
{
context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "rgb(150,29,28)";
context.beginPath();
context.arc(position.x, position.y, 150, 0, Math.PI * 2, true);
context.fill();
context.closePath();
position.x += step.x;
position.y += step.y;
}
そして、あなたはそれを持っています。もちろん、これは非常に基本的なコードです。オブジェクトがターゲットに到着したかどうかを確認するコードを追加する必要があります。そうしないと、ターゲットを通過し続けます。動きが遅すぎる場合は、step
ベクトルを任意の速度係数でスケーリングします。また、実際のアプリでは、円だけでなく多くのオブジェクトが存在するため、すべてのオブジェクトに位置、ターゲット位置、色などがあるため、完全にオブジェクト指向にする必要があります。ベクトルを扱うと便利です。これは私がしばらく前に自分用に書いたものです: http://pastebin.com/Hdxg8dxn