Canvas入門基礎(chǔ)(五):變形

2018-06-19 14:39 更新
在了解變形之前,我先介紹一下兩個(gè)在你開始繪制復(fù)雜圖形就必不可少的方法。

save()

restore()

save 和 restore 方法是用來保存和恢復(fù) canvas 狀態(tài)的,都沒有參數(shù)。Canvas 的狀態(tài)就是當(dāng)前畫面應(yīng)用的所有樣式和變形的一個(gè)快照。
Canvas 狀態(tài)是以堆(stack)的方式保存的,每一次調(diào)用 save 方法,當(dāng)前的狀態(tài)就會被推入堆中保存起來。這種狀態(tài)包括: 1.當(dāng)前應(yīng)用的變形(即移動,旋轉(zhuǎn)和縮放) 2.strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation 的值. 3.當(dāng)前的裁切路徑(clipping path) 你可以調(diào)用任意多次 save 方法。 每一次調(diào)用 restore 方法,上一個(gè)保存的狀態(tài)就從堆中彈出,所有設(shè)定都恢復(fù)。

例子:

cxt.fillStyle="red"; cxt.fillRect(10,10,50,50); cxt.save(); cxt.fillStyle="blue"; cxt.fillRect(20,20,30,30); cxt.restore(); cxt.fillRect(30,30,10,10);


我們第一步先設(shè)置了填充色為紅色,畫了一個(gè)大正方形,然后保存狀態(tài);第二步將填充色設(shè)置為藍(lán)色,畫了一個(gè)小一點(diǎn)正方形;跟著調(diào)用restore()恢復(fù)狀態(tài),也就是恢復(fù)填充色為紅色的狀態(tài),再畫了一個(gè)更小的正方形。

到目前為止所做的動作和前面章節(jié)的都很類似。不過一旦我們調(diào)用 restore,狀態(tài)堆中最后的狀態(tài)會彈出,并恢復(fù)所有設(shè)置。如果不是之前用 save 保存了狀態(tài),那么我們就需要手動改變設(shè)置來回到前一個(gè)狀態(tài),這個(gè)對于兩三個(gè)屬性的時(shí)候還是適用的,一旦多了,我們的代碼將會猛漲。

變形
在Canvas中,變形包括移動、旋轉(zhuǎn)、縮放、變形,跟CSS3中的2D轉(zhuǎn)換類似。
注意:原有內(nèi)容不會受變形的影響,變形只是坐標(biāo)變換,新繪制的圖形就是在變換后的坐標(biāo)軸里繪制的。)
下面我們來逐一的認(rèn)識。

一、移動(translate)
canvas的移動是指移動 canvas 和它的原點(diǎn)到一個(gè)不同的位置。

translate(x, y)

translate 方法接受兩個(gè)參數(shù)。x 是左右偏移量,y 是上下偏移量,如右圖所示。
例子:

cxt.fillRect(0,0,100,100); cxt.save(); cxt.translate(60,60); cxt.fillStyle="red"; cxt.fillRect(0,0,100,100); cxt.restore();



二、旋轉(zhuǎn)(rotate)
用于以原點(diǎn)為中心旋轉(zhuǎn) canvas。

rotate(angle)

這個(gè)方法只接受一個(gè)參數(shù):旋轉(zhuǎn)的角度(angle),它是順時(shí)針方向的,以弧度為單位的值。

cxt.beginPath(); cxt.moveTo(0,50); cxt.lineTo(100,50); cxt.stroke(); cxt.save(); cxt.rotate(Math.PI/12); cxt.strokeStyle="red"; cxt.beginPath(); cxt.moveTo(0,50); cxt.lineTo(100,50); cxt.stroke(); cxt.restore();



三、縮放(scale)

scale(x, y)

scale 方法接受兩個(gè)參數(shù)。x,y 分別是橫軸和縱軸的縮放因子,它們都必須是正值。值比 1.0 小表示縮小,比 1.0 大則表示放大,值為 1.0 時(shí)什么效果都沒有。
例子:

cxt.fillRect(20,20,50,50); cxt.save(); cxt.scale(.5,.5); cxt.fillStyle="red"; cxt.fillRect(20,20,50,50);



四、變形

區(qū)別: transform()方法的行為相對于由 rotate(),scale(), translate(), or transform() 完成的其他變換。例如:如果我們已經(jīng)將繪圖設(shè)置為放到兩倍,則 transform() 方法會把繪圖放大兩倍,那么我們的繪圖最終將放大四倍。這一點(diǎn)和之前的變換是一樣的。 但是setTransform()不會相對于其他變換來發(fā)生行為。它的參數(shù)也是六個(gè),context.setTransform(a,b,c,d,e,f),與transform()一樣。

transform(m11, m12, m21, m22, dx, dy)

參數(shù):
m11 水平縮放繪圖。 默認(rèn)值1
m12 水平傾斜繪圖。 默認(rèn)值0
m21 垂直傾斜繪圖。 默認(rèn)值0
m22 垂直縮放繪圖。 默認(rèn)值1
dx 水平移動繪圖。 默認(rèn)值0
dy 垂直移動繪圖。 默認(rèn)值0

這個(gè)方法必須將當(dāng)前的變形矩陣乘上下面的矩陣:

m11 m21 dx m12 m22 dy 0 0 1


注意:該變換只會影響 transform() 方法調(diào)用之后的繪圖。

setTransform(m11, m12, m21, m22, dx, dy)

參數(shù): m11 水平縮放繪圖。 默認(rèn)值1 m12 水平傾斜繪圖。 默認(rèn)值0 m21 垂直傾斜繪圖。 默認(rèn)值0 m22 垂直縮放繪圖。 默認(rèn)值1 dx 水平移動繪圖。 默認(rèn)值0 dy 垂直移動繪圖。 默認(rèn)值0

矩陣


五、transform和translate、scale、rotate

5.1 translate

cxt.translate(dx,dy)

cxt.transform (1,0,0,1,dx,dy)代替cxt.translate(dx,dy)。 也可以使用 cxt.transform(0,1,1,0.dx,dy)代替。

5.2 scale
cxt.scale(m11, m22):

也即是說可以使用 cxt.transform(m11,0,0,m22,0,0)代替cxt.scale(m11,m22); 也可以使用cxt.transform (0,m22,m11,0, 0,0);

5.3 rotate
rotate(θ)

也即是說可以用 cxt.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(θ)。 也可以使用 cxt.transform(-Math.sin(θ*Math.PI/180),Math.cos(θ*Math.PI/180), Math.cos(θ*Math.PI/180),Math.sin(θ*Math.PI/180), 0,0)替代。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號