canvasでアニメーションさせてみる | blog lab 【アメブロカスタマイズとネタ話】

blog lab 【アメブロカスタマイズとネタ話】

コメント欄にプロフィール画像、などのカスタマイズの小ネタと、普段の話のネタを書いていきます。

前回の記事では円を表示させるまで行きましたが、今回はそれを動かしてみようと思います。
まずは前回のおさらいから。

ただ円を描くだけのコードから、後々のことを考えてCircleオブジェクトを使ってオブジェクト指向っぽく書きましょう、というところまで書いたと思います。

以下、そのコードと結果表示

<script type="text/javascript">
$(function() {

/*jQueryなら$("#canvas").get(0)でOK*/
var canvas = document.getElementById("canvas");
if (!canvas || !canvas.getContext) {return false;};

/*コンテキストを取得*/
var ctx = canvas.getContext("2d");

/*2πラジアンを前もって計算しておく*/
var pi360 = Math.PI*2;

/*Circleオブジェクト*/
function Circle(){
this.initialize.apply(this,arguments);
} /*Circleここまで*/

/*Circleオブジェクトのプロパティを設定*/
Circle.prototype={

/*コンストラクタ*/
initialize:function(x,y,r,fill,stroke) {
this.x = x||0; /*x座標*/
this.y = y||0; /*y座標*/
this.r = r||5; /*半径*/
this.fill = fill||"#000000"; /*塗りの色*/
this.stroke = stroke||fill; /*縁の色*/
}, /*initializeここまで*/

/*レンダリング(描く)用関数*/
render:function(){
ctx.beginPath();
ctx.fillStyle = this.fill;
ctx.strokeStyle = this.stroke;
ctx.arc(this.x, this.y, this.r, 0, pi360,true);
ctx.closePath();
ctx.fill();
/*縁の色が塗りの色と違う色なら縁取り*/
if(this.fill === this.stroke){}else{ctx.stroke();}
} /*renderここまで*/
}; /*Circle.prototypeここまで*/

var circle = new Circle(50,50,30,"black"); /*Circleインスタンスを作る*/
circle.render(); /*表示する*/
});
</script>

↓結果はこちら


アニメーションの手順

canvas自体にはアニメーションの機能がないので、秒間何フレームのアニメーションにするかを先ず決めて、それからフレームごとに全消し→全描画することになります。
フレームレート(1秒あたりのフレーム数)をまず決めるとともに、canvasの大きさも設定するのが良いかと思います。

var canvas = document.getElementById("canvas");
if (!canvas || !canvas.getContext) {return false;};
var ctx = canvas.getContext("2d");
var pi360 = Math.PI*2;
var FRAMERATE = 60; /*フレームレート*/
var canvasWidth = 400; /*canvasの幅*/
var canvasHeight = 200; /*canvasの高さ*/
canvas.width = canvasWidth;
canvas.height = canvasHeight;

次に、フレームごとにする作業(全消し→全描画)を関数に纏めてみます。
名前はupdateとかstepでいいかと思います。
まずは上方向に動くアニメーションを作ってみます。

/*表示する*/
function step(){
/*全消し*/
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
/*canvasから上にはみ出たら下に移動*/
if(circle.y + circle.r < 0){circle.y = canvasHeight + circle.r;};
/*circleのy座標から1を引く*/
circle.y = circle.y - 1;
/*circleを描画*/
circle.render();
};/*stepここまで*/

これで縦移動のアニメーションが実現できるはずです!
実際にやってみましょう。

$(function() {
var canvas = document.getElementById("canvas2");
if (!canvas || !canvas.getContext) {return false;};
var ctx = canvas.getContext("2d");
var pi360 = Math.PI*2;
var FRAMERATE = 60; /*フレームレート*/
var canvasWidth = 400; /*canvasの幅*/
var canvasHeight = 200; /*canvasの高さ*/
canvas.width = canvasWidth;
canvas.height = canvasHeight;

function Circle(){
this.initialize.apply(this,arguments);
} /*Circleここまで*/

Circle.prototype={
initialize:function(x,y,r,fill,stroke) {
this.x = x||0;
this.y = y||0;
this.r = r||5;
this.fill = fill||"#000000";
this.stroke = stroke||fill;
}, /*initializeここまで*/
render:function(){
ctx.beginPath();
ctx.fillStyle = this.fill;
ctx.strokeStyle = this.stroke;
ctx.arc(this.x, this.y, this.r, 0, pi360,true);
ctx.closePath();
ctx.fill();
if(this.fill === this.stroke){}else{ctx.stroke();}
} /*renderここまで*/
}; /*Circle.prototypeここまで*/

var circle = new Circle(50,150,20,"red");
circle.render();

function step(){
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
if(circle.y + circle.r < 0){circle.y = canvasHeight + circle.r;};
circle.y = circle.y - 1;
circle.render();
};/*stepここまで*/

setInterval(step,(1000 / FRAMERATE));/*1フレームごとにstepを実行*/
});

↓結果はこちら

うまくいきました!

次回はより複雑なアニメーションにチャレンジしてみます。

記事の話題関連のツイート on twitter