canvas之圖形的變化(平移,縮放,旋轉)

一、保存與恢復canvas狀態javascript

ctx.save();暫時將當前的狀態保存到堆中css

ctx.restore();該方法用於將上一個保存的狀態從堆中再次取出,恢復該狀態的全部設置。html

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta charset="utf-8">
 5 <title></title>
 6 <style type="text/css">
 7 *{padding: 0;margin:0;}
 8 body{background: #1b1b1b;}
 9 #div1{margin:50px auto; width:300px; height: 300px;}
10 canvas{background: #fff;}
11 </style>
12 <script type="text/javascript">
13 window.onload = function(){
14     var c = document.getElementById('myCanvas');
15     var context = c.getContext('2d');
16     
17     //開始繪製矩形
18     context.fillStyle = '#f0f';
19     context.strokeStyle = 'blue';
20     context.fillRect(20,20,100,100);
21     context.strokeRect(20,20,100,100);
22     context.fill();
23     context.stroke();
24     
25     //保存當前canvas狀態
26     context.save();    
27     
28     //繪製另一個矩形
29     context.fillStyle = '#f00';
30     context.strokeStyle = 'green';
31     context.fillRect(140,20,100,100);
32     context.strokeRect(140,20,100,100);
33     context.fill();
34     context.stroke();
35     
36     //恢復第一個矩形的狀態
37     context.restore();
38     
39     //繪製兩個矩形
40     context.fillRect(20,140,50,50);
41     context.strokeRect(80,140,50,50);
42     
43 };
44 </script>
45 </head>
46 <body>
47     <div id="div1">
48         <canvas id="myCanvas" width="300" height="200"></canvas>
49     </div>
50 </body>
51 </html>

效果展現:java

 

 

二、移動座標空間canvas

context.translate(dx,dy); dx,dy分別表示座標原點沿水平和垂直兩個方向的偏移量。(在圖形變換以前,最好使用save()方法保存當前狀態的好習慣。使用restore()方法恢復原來的狀態)。spa

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta charset="utf-8">
 5 <title></title>
 6 <style type="text/css">
 7 *{padding: 0;margin:0;}
 8 body{background: #1b1b1b;}
 9 #div1{margin:50px auto; width:300px; height: 300px;}
10 canvas{background: #fff;}
11 </style>
12 <script type="text/javascript">
13 window.onload = function(){
14     draw();    
15 };
16 function drawTop(ctx,fillStyle){
17     ctx.fillStyle = fillStyle;
18     ctx.beginPath();
19     ctx.arc(0,0,30,0,Math.PI,true);
20     ctx.closePath();
21     ctx.fill();
22 }
23 
24 function drawGrip(ctx){
25     ctx.save();
26     ctx.fillStyle = 'blue';
27     ctx.fillRect(-1.5,0,1.5,40);
28     ctx.beginPath();
29     ctx.arc(-5,40,4,Math.PI,Math.PI*2,true);
30     ctx.stroke();
31     ctx.closePath();
32     ctx.restore();
33 }
34 
35 function draw(){
36     
37     var ctx = document.getElementById('myCanvas').getContext('2d');
38     ctx.translate(80,80);
39     
40     for(var i=0; i<10; i++){
41         ctx.save();
42         ctx.translate(60*i,0);
43         drawTop(ctx,'rgb('+(30*i)+','+(255-30*i)+',255)');
44         drawGrip(ctx);
45         ctx.restore();
46     }
47     
48 }
49 </script>
50 </head>
51 <body>
52     <div id="div1">
53         <canvas id="myCanvas" width="700" height="300"></canvas>
54     </div>
55 </body>
56 </html>

效果展現:rest

 

三、旋轉座標空間code

context.rotate(angle);  該方法只有一個參數 旋轉角度angle,旋轉角度以順時針方向爲正方向,以弧度爲單位,旋轉中心爲canvas的原點orm

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta charset="utf-8">
 5 <title></title>
 6 <style type="text/css">
 7 *{padding: 0;margin:0;}
 8 body{background: #1b1b1b;}
 9 #div1{margin:50px auto; width:300px; height: 300px;}
10 canvas{background: #fff;}
11 </style>
12 <script type="text/javascript">
13 window.onload = function(){
14     draw();    
15 };
16 function drawTop(ctx,fillStyle){
17     ctx.fillStyle = fillStyle;
18     ctx.beginPath();
19     ctx.arc(0,0,30,0,Math.PI,true);
20     ctx.closePath();
21     ctx.fill();
22 }
23 function drawGrip(ctx){
24     ctx.save();
25     ctx.fillStyle = 'blue';
26     ctx.fillRect(-1.5,0,1.5,40);
27     ctx.beginPath();
28     ctx.strokeStyle = 'blue';
29     ctx.arc(-5,40,4,Math.PI,Math.PI*2,true);
30     ctx.stroke();
31     ctx.closePath();
32     ctx.restore();
33 }
34 function draw(){
35     var c = document.getElementById('myCanvas');
36     var ctx = c.getContext('2d');
37     ctx.translate(150,150);
38     
39     for(var i=0; i<8; i++){
40         ctx.save();
41         ctx.rotate(Math.PI*(2/4+i/4));
42         ctx.translate(0,-100);
43         drawTop(ctx,'rgb('+(30*i)+','+(255-30*i)+',255)');
44         drawGrip(ctx);
45         ctx.restore();
46     }
47 }
48 </script>
49 </head>
50 <body>
51     <div id="div1">
52         <canvas id="myCanvas" width="300" height="300"></canvas>
53     </div>
54 </body>
55 </html>

效果展現:htm

 

 

四、縮放圖形

ctx.scale(x,y); 其中x爲x軸的縮放,y爲y軸的縮放,若是要縮小,值爲小於1的數值,若是要放大,值爲大於1的數值。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta charset="utf-8">
 5 <title></title>
 6 <style type="text/css">
 7 *{padding: 0;margin:0;}
 8 body{background: #1b1b1b;}
 9 #div1{margin:50px auto; width:300px; height: 300px;}
10 canvas{background: #fff;}
11 </style>
12 <script type="text/javascript">
13 window.onload = function(){
14     draw();    
15 };
16 
17 function draw(){
18     var c = document.getElementById('myCanvas');
19     var ctx = c.getContext('2d');
20     ctx.translate(180,20);
21     
22     for(var i=0; i<80; i++){
23         ctx.save();
24         ctx.translate(30,30);
25         ctx.scale(0.95,0.95);
26         ctx.rotate(Math.PI/12);
27         ctx.beginPath();
28         ctx.fillStyle = 'red';
29         ctx.globalAlpha = '0.4';
30         ctx.arc(0,0,50,0,Math.PI*2,true);
31         ctx.closePath();
32         ctx.fill();
33     }
34 }
35 </script>
36 </head>
37 <body>
38     <div id="div1">
39         <canvas id="myCanvas" width="300" height="300"></canvas>
40     </div>
41 </body>
42 </html>

效果展現:

 

 

五、矩陣變換

transform方法用於直接對變形矩陣做修改,即進行矩陣變形。

context.transform(m11,m12,m21,m22,dx,dy);   該方法必須將當前的變換矩陣與下面的矩陣進行乘法運算。

即:

m11(默認爲1) m21(默認爲0) dx
m12(默認爲0) m22(默認爲1) dy
0 0 1

 

 

 

也就是說假設A(x,y)要變換成B(x’,y’)能夠經過乘以上述矩陣便可獲得。

 

一:平移(translate), translate能夠用下面的方法替代

 

如上圖所示:

x’=x+dx

y’=y+dy

即:

其中dx爲原點沿着x軸移動的數值,y爲原點沿着y軸移動的數值。

context.translate(x,y)能夠用下面的transform方法來替代:

context.transform(0,1,1,0,dx,dy); 或 context.transform(1,0,0,1,dx,dy);

 

2、縮放:  scale(x,y) 

x’=m11*x

y’=m22*y

x'=m12*x

y'=m21*y 

(其中,m十一、m22 和m十二、m21分別表示在x軸和y軸上的縮放倍數)

則:scale(x,y); 能夠經過下面的transform發放來替代:

context.transform(m11,0,0,m22,0,0);  或 context.transform(0,m12,m21,0,0,0);

 


3、旋轉: rotate(angle);

能夠用下面的transform方法來替代:

context.transform(cosΘ,sinΘ,-sinΘ,cosΘ,0,0);

其中Θ爲旋轉的角度,dx,dy都爲0表示座標原點不變。

如圖:x' = x*cosΘ - y*sinΘ

        y' = x*sinΘ + y*cosΘ

也便是[轉載]Html5 <wbr>Canvas <wbr>變換矩陣與座標變形之間的關係(

 

則:

context.transform(Math.cos(θ*Math.PI/180),Math.sin(θ*Math.PI/180),

-Math.sin(θ*Math.PI/180),Math.cos(θ*Math.PI/180),0,0)能夠替代context.rotate(θ)。

也可使用

context.transform(-Math.sin(θ*Math.PI/180),Math.cos(θ*Math.PI/180),

Math.cos(θ*Math.PI/180),Math.sin(θ*Math.PI/180), 0,0)替代。

eg: context.transform(0.95,0,0,0.95,30,30); 能夠替代 context.translate(30,30); context.scale(0.95.0.95);

 

setTransform方法用於將當前的變化矩陣 重置 爲最初的矩陣,而後以相同的參數調用transform方法,即先set(重置),再transform(變換)

用法: context.setTransform(m11,m12,m21,m22,dx,dy);

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4 <meta charset="utf-8">
 5 <title></title>
 6 <style type="text/css">
 7 *{padding: 0;margin:0;}
 8 body{background: #1b1b1b;}
 9 #div1{margin:50px auto; width:300px; height: 300px;}
10 canvas{background: #fff;}
11 </style>
12 <script type="text/javascript">
13 window.onload = function(){
14     draw();    
15 };
16 
17 function draw(){
18     var c = document.getElementById('myCanvas');
19     var ctx = c.getContext('2d');
20     ctx.translate(200,20);
21     
22     for(var i=0; i<80; i++){
23         ctx.save();
24         ctx.transform(0.95,0,0,0.95,30,30);
25         ctx.rotate(Math.PI/12);
26         ctx.beginPath();
27         ctx.fillStyle = 'red';
28         ctx.globalAlpha = '0.4';
29         ctx.arc(0,0,50,0,Math.PI*2,true);
30         ctx.closePath();
31         ctx.fill();
32     }
33     
34     ctx.setTransform(1,0,0,1,10,10);    //將前面的矩陣恢復爲最初的矩陣,即恢復最初的原點,而後將座標原點改成(10,10),並以新的座標繪製一個藍色的矩形
35     ctx.fillStyle = 'blue';
36     ctx.fillRect(0,0,50,50);
37     ctx.fill();
38     
39 }
40 </script>
41 </head>
42 <body>
43     <div id="div1">
44         <canvas id="myCanvas" width="700" height="300"></canvas>
45     </div>
46 </body>
47 </html>

 效果顯示:

相關文章
相關標籤/搜索