[js] あの楽器の図形描画をcanvasで

あの楽器は初音ミクがPVで持ってる楽器の事です。

一年ちょっと前にMooToolsでやろうとして匙を投げたんだけど、
「canvas使えばやれるかな」と当時言ってた事を覚えがてらやっつけてみた。

AnoRect – jsdo.it – share JavaScript, HTML5 and CSS

忘れないうちに図形描画の解説入れておこうと思う。

Canvasのテンプレート

初歩的な事についてはMozilla Developer Centerのチュートリアルが分かりやすいと思う。

Canvas要素をgetElementByIdで取得してgetContextする流れはほぼテンプレです。
テンプレなら使いまわしが出来るよねってことでクラス化したのが次のソース。

var myCanvas = function(){
  var mycanvas = {
    
    canvas:null,
    context:null,
    
	//イベントリスナー
    addEvent:function(obj, type, fn, ref_obj){
      if(obj.addEventListener)
        obj.addEventListener( type, fn, false );
    },
    
	//実行関数。引数はcanvasのID
    load:function(id){
		
      this.addEvent(window, 'load', function(event,ref_obj){
        
        mycanvas.canvas = document.getElementById(id);
        
        if (mycanvas.canvas.getContext){
          mycanvas.setSize(window.innerWidth, window.innerHeight);//全画面
          mycanvas.context = mycanvas.canvas.getContext('2d');
		  //ここに処理を書く
		}

      });
    },
	
    //canvasの高さと横幅をセット
    setSize:function(x,y){
        mycanvas.canvas.height = y;
        mycanvas.canvas.width = x;
	}
  };
  
  return mycanvas;
};

使用するときはnewしてloadするだけです。loadにはcanvasのIDを渡します。

var mycanvas = new myCanvas();
mycanvas.load('test'); //<canvas id="test"></canvas>

「ここに処理を書く」というところに次のソースを書くと、画面中央に1辺が100pxの正方形が描画されます

 mycanvas.context.strokeRect(window.innerWidth/2-50, window.innerHeight/2-50, 100, 100);

自分自身を示すのはthisではなくmycanvasになるので注意です。
IEは未対応なので何も対策してないですが、9がリリースされたら9だけ対応させる処理が必要になると思う。

イベントの登録

内臓したイベントリスナーを利用してクリックイベントを登録してみる。
クリックされた時の座標を元に、1辺が100pxの正方形を描画させます。

前に追加したstrokeRectの行をカットして、次のソースに置き換えます。

mycanvas.addEvent(mycanvas.canvas,"click", mycanvas.clickhandler);

Canvas#testにクリックイベントを登録。
クリックした時に実行されるclickhandlerというメソッドをsetSize()の下に作成します。

}, //setSize()の閉じカッコ(カンマ追加)
clickhandler:function(event) {
      if (!event) { event = window.event; }
      var x = event.layerX;
      var y = event.layerY;
	  
      mycanvas.context.strokeRect(x-50, y-50, 100, 100);
}

これでクリックした点を中心に正方形が描画されていく。
描画する前にclearRectで全て塗りつぶせばクリックごとに場所を移動する感じになります。

mycanvas.context.clearRect(0,0, mycanvas.canvas.width, mycanvas.canvas.height);

でもこれだとパラパラ漫画状態なので、jsdoitで流行ってるパーティクルみたいに描かれた図形そのものを独立させて動かすってことが出来ません。
パラパラ漫画をもっと発展させてアクティブに動かすならセル画に1枚1枚図形を書けばいいわけで、
そのセル画をJavaScriptでやろうと思った場合にはオブジェクトにしなければなりません。

正方形のオブジェクトRectの簡単な例です。これを適当な場所にコピペする。
クリックした場所に描いた正方形にtransrateとrotateを使ってぐるっと回転させます。

function Rect(ctx,x,y) {
	var a = 0;//初期アングル
	var id = setInterval(rotate,10);//タイマー
	
	function rotate(){
		ctx.save();//状態を保存
		ctx.translate(x, y);//クリック位置に移動させる
		ctx.rotate(a * Math.PI/180);//回転
		ctx.translate(-x, -y);//元に戻す
		ctx.strokeRect(x-50, y-50, 100, 100);//描画
		ctx.restore();//状態を戻す
		a+=5;//5度回す
		if(a>90) clearInterval(id);//90度回したら終了
	}
}

あとはクリックで呼ばれた時のstrokeRectをインスタンス作成にすればOK

new Rect(mycanvas.context,x,y);

rotateはそのまま使うだけだとcanvasの左上(座標で言うと0,0)が中心点になるので、
translateで中心を図形の重心に移動させてからrotateを実行すれば図形がその場で回転する。
save()とrestore()はセーブポイントの作成とロードで、restoreを使うたびに1つ前の保存状態に戻すことが出来る。

実行デモとソース全文

続きます。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください