Canvasでアニメーションを作る
●setInterval() で簡単なアニメーション
●setTimeout() と new Date().getSeconds() で秒針のアニメーション
setInterval()メソッドを使用。
グリーンの円は、x,yにそれぞれ一定の値を足して動かしています。
Canvasのサイズは300×300pxにしているので、x,yがそれぞれ0より小さくなったり300より大きくなったら、一定の値をマイナスにするよう設定しているので、壁にバウンドするように見えます。
また、描画を繰り返すたびに、最初に画面いっぱいに透明度の低い黒の四角を描画しているので、前の円が軌跡のように残って見えています。
この黒い四角が無ければ、ただグリーンの円が点々と繋がってラインになっていくだけのアニメーションです。
function Draw1(){
var canvas = document.getElementById('canvas1');
var ctx = canvas.getContext('2d');
var speedX = 3.0;
var speedY = 3.2; //speedXと少しずらす(同じ値だと一直線に行ったり来たりするだけ)
var locationX = canvas.width/2;
var locationY = canvas.height/2;
setInterval(function(){
ctx.fillStyle = "rgba(0,0,0,0.1)"; //透明度の低い黒地を重ねることで軌跡を作っている
ctx.fillRect(0,0,canvas.width,canvas.height);
ctx.save(); /*ここで保存(次の↓globalCompositeOperationのため)*/
ctx.globalCompositeOperation = "lighter";
//位置を移動させる設定
locationX += speedX;
locationY += speedY;
if(locationX < 0 || locationX > 300){
speedX *= -1;
}
if(locationY < 0 || locationY > 300){
speedY *= -1;
}
//上で設定した座標で円を描く
ctx.beginPath();
ctx.fillStyle = '#060';
ctx.arc(locationX, locationY, 6, 0, Math.PI*2, true);
ctx.fill();
ctx.restore(); //globalCompositeOperationをsave状態に戻しています
}, 20);
};
setTimeout()メソッドで繰り返しを行っています。
(ただしコレはsetIntervalと違って遅れが出るらしいので、秒針には向かないかな。詳しくは本編記事で)
new Date() と getSeconds() を使って、秒針を表示してみました。
Canvas上にラインを描き、それを秒数に合わせて回転させるのですが、rotate() はCanvasの左上を回転の中心点にするため、全体を translate() で移動して、回転の中心点がCanvasの真ん中になるようにしています。
アニメーションのためのクリアは、clearRect() でできず(想定外の動きをし始めて...)、「canvas2.width = canvas2.width」でうまくいきました。
function Draw2() {
var canvas2 = document.getElementById('canvas2');
var ctx2 = canvas2.getContext('2d');
//ctx2.clearRect(0,0,canvas2.width,canvas2.height); ←これはダメだった
canvas2.width = canvas2.width; //canvas特有の全体をクリアする裏技だそうです
ctx2.translate(150,150); //回転の起点をcanvasの中心にする
ctx2.lineWidth = 3;
ctx2.strokeStyle = "#999";
// 回転の設定(1秒に6度ずつ回転させる)
var sec = new Date().getSeconds();
ctx2.rotate(sec * Math.PI/30);
// 秒針の描画
ctx2.beginPath();
ctx2.moveTo(0,0);
ctx2.lineTo(130,0);
ctx2.stroke();
// 時計のフレームの描画
ctx2.beginPath();
ctx2.arc(0,0,145,0,Math.PI*2,true);
ctx2.stroke();
setTimeout(Draw2,100);
};