1. 程式人生 > >4. Canvas旋轉與變形

4. Canvas旋轉與變形

一.旋轉與變形

1.變形方法:

變形方法中的旋轉/移動相關方法
方法 說明
setTransform(m11,m12,m21,m22,dx,dy)

變形矩陣的指定(清空先前的指定)

transform(m11,m12,m21,m22,dx,dy) 變形矩陣的指定(可重複指定)
rotate(angle) 旋轉
scale(x,y) 擴大/縮小
translate(x,y) 移動/變形
變形矩陣的 儲存/恢復方法
方法 說明
save() 記錄變形矩陣的狀態
restore() 恢復變形矩陣的狀態

 


2.移動與擴大/縮小:

語法:

context.scale(x,y);     x為長度縮放的比例,y是寬度縮放的比例

context.translate(x,y);    (x,y)為基點移動後的座標

 

例子1:

	<canvas id="cas" width="300" height="300"></canvas>
	<script type="text/javascript">
		//獲取上下文
		var canvas = document.getElementById("cas");
		var ctx = canvas.getContext("2d"); 

		//宣告繪製矩形的函式
		function drawRect(context,color){
			context.fillStyle = color;
			context.fillRect(20,20,50,50);
		}

		//繪製普通的矩形
		drawRect(ctx,"red");

		//移動矩形以及擴大/縮小矩形
		ctx.translate(30,30);    //繪製基點變成了(50,50)
		ctx.scale(2.5,0.8);

		//繪製第二個矩形
		drawRect(ctx,"green"); 
	</script>

 

效果圖:

 


3.旋轉

語法:

context.rotate(angle);

其中angle是弧度,red = deg*Math.PI/180;

 

例子:下面的例項結合了上一節的save()方法、restore()方法,以及本節的rotate()方法的應用。通過移動/旋轉等方式,分別繪製三個長方形。

 

	<canvas id="cas" width="300" height="300"></canvas>
	<script type="text/javascript">
		//獲取上下文
		var canvas = document.getElementById("cas");
		var ctx = canvas.getContext("2d"); 

		//定義描繪矩形的函式
		function drawRect(context,color){
			context.fillStyle = color;
			context.fillRect(0,0,100,30);
		}

		//定義旋轉函式
		function rotateDeg(context,deg){
			var rad = deg*Math.PI/180;
			context.rotate(rad);
		}

		//繪製普通的矩形
		drawRect(ctx,"red");

		//指定移動旋轉後繪圖
		ctx.save();   //儲存狀態
		ctx.translate(100,30);  //移動基點
		rotateDeg(ctx,45);     //旋轉45度
		drawRect(ctx,"blue");
		ctx.restore();

		ctx.translate(200,50);
		rotateDeg(ctx,0);
		drawRect(ctx,"green");
		ctx.restore();
	</script>

效果:

注意:ctx.save()是儲存當前狀態(包括原點座標,角度等等),ctx.restore()是返回最後一次儲存的狀態。

 


二.繪製文字

canvas不僅可以繪製圖像,還可以繪製文字。

文字繪製相關的方法
方法 說明
context.fillText(text,x,y) 描繪文字
context.fillText(text,x,y,maxWidth)
context.strokeText(text,x,y) 描繪檔案的輪廓
context.strokeText(text,x,y,maxWidth)

引數text是將要描繪的文字,引數x和y指定了描繪位置的座標。預設情況下,以描繪物件的左下為基準。引數maxWidth是可選的,其指定數值後,文字將顯示在指定的寬度內。

 

文字繪製相關的屬性
屬性 說明
context.font 定義文字的樣式。與CSS的font屬性設定的內容相同
context.textAlign 定義文字的對齊方式,可指定start,end,left,right,center等
context.textBaseline 定義檔案的基準線,可指定top,hanging,middle,alphabetic,bottom等

 


例子1:在此例中對同一個文字先後使用藍色描繪文字輪廓,紅色描繪文字,最後縮小寬度成一固定值並用綠色描繪文字。

 

	<canvas id="cas" width="300" height="300"></canvas>
	<script type="text/javascript">
		//獲取上下文
		var canvas = document.getElementById("cas");
		var ctx = canvas.getContext("2d"); 

		//定義文字
		var text = "在Canvas中進行文字描繪";

		//定義文字的字型
		ctx.font = "24px 'Arial'";

		//描繪文字的輪廓
		ctx.strokeStyle = "blue";
		ctx.strokeText(text,10,40);

		//描繪文字
		ctx.fillStyle = "red";
		ctx.fillText(text,10,85);

		//固定寬度
		ctx.fillStyle = "green";
		ctx.fillText(text,10,130,150);		
	</script>

 

效果圖:

 


對齊方式:將上面的文字改成居中對齊方式。

例子2:

	<canvas id="cas" width="300" height="300"></canvas>
	<script type="text/javascript">
		//獲取上下文
		var canvas = document.getElementById("cas");
		var ctx = canvas.getContext("2d"); 

		//定義文字
		var text = "在Canvas中進行文字描繪";

		//定義文字的字型
		ctx.font = "24px 'Arial'";

		//居中對齊,這裡設定為居中對齊,那麼下面的座標就是中心座標,而不是左下角座標
		ctx.textAlign = "center";

		//描繪文字的輪廓
		ctx.strokeStyle = "blue";
		ctx.strokeText(text,canvas.width/2,canvas.height/2);
	
	</script>

 

效果:

 


基準線

文字的垂直方向使用textBaseline屬性來定義:top(字頂端)、middle(字中央)、bottom(字底部)、hanging(羅馬字上緣)、alphabetic(羅馬字基線)、ideographic(羅馬字下緣)。

 


三.canvas實現動畫效果

 

  1. 圓球跳動的動畫:
      <canvas width="300" height="300" id="can"></canvas>
      <script type="text/javascript">
        function getId(id){
          return typeof(id) === 'string' ? document.getElementById(id) : id;
        }
    
        var canvas = getId("can");
        var ctx = canvas.getContext("2d");
    
        var ball = {x:10, y:100, dir_x:5, dir_y:5};
        setInterval(drawBall, 50);
    
        function drawBall(){
          //描繪背景
          ctx.fillStyle = "white";
          ctx.fillRect(0,0,300,300);
    
          //繪製圓球
          ctx.beginPath();
          ctx.arc(ball.x, ball.y, 6, 0, Math.PI*2);
          ctx.fillStyle = "red";
          ctx.fill();
    
          //讓圓球動起來
          ball.x += ball.dir_x;
          ball.y += ball.dir_y;
          if (ball.x <=0 || ball.x >= 300) {
          	ball.dir_x *= -1.2;
          }
          if (ball.y <=0 || ball.y >= 300) {
          	ball.dir_y *= -1.2;
          }
        }
      </script>

    效果:

 

2.繪製待機動畫:

  <canvas width="300" height="300" id="can"></canvas>
  <script type="text/javascript">
    function getId(id){
      return typeof(id) === 'string' ? document.getElementById(id) : id;
    }

    var canvas = getId("can");
    var ctx = canvas.getContext("2d");

    var ci = 0;
    anim();

    function anim(){
    	ctx.clearRect(0,0,300,300);
      for(var i=0; i<36; i++){
        ctx.save();
        var r = (i*10)*Math.PI/180;
        ctx.translate(150,150);
        ctx.rotate(r);
        //繪製細長方形

       if (i === ci) {
         ctx.globalAlpha = 1.0;
       } else {
         ctx.globalAlpha = 0.3;
       }
       ctx.beginPath();
       ctx.fillStyle = "green";
       ctx.rect(0,0,50,6);
       ctx.fill();
       ctx.restore();
      }
      ci = (ci + 1) % 36;
      //每隔一段時間呼叫函式本身,實現動畫效果
      setTimeout(anim, 50);
    }
  </script>

效果圖:

 

注意:繪製動畫每一次迴圈都別忘了清空canvas。