Canvas的操作可以幫助我們更好的畫圖。
要學習Canvas的用法,可以訪問Google官網,https://developer.android.google.cn/reference/android/graphics/Canvas.html
Canvas操作主要有以下幾種:
操作 | 方法 | 備註 |
---|---|---|
位移(translate) | translate(float dx, float dy) | Preconcat the current matrix with the specified translation |
縮放(scale) | scale(float sx, float sy)/scale(float sx, float sy, float px, float py) | Preconcat the current matrix with the specified scale. |
旋轉(rotate) | rotate(float degrees)/rotate(float degrees, float px, float py) | Preconcat the current matrix with the specified rotation. |
斜切(skew) | skew(float sx, float sy) | Preconcat the current matrix with the specified skew. |
1. translate是座標系的移動,可以爲圖形繪製選擇一個合適的座標系。 請注意,位移是基於當前位置移動,而不是每次基於屏幕左上角的(0,0)點移動
canvas.drawCircle(60,60,50,mPaint2);
canvas.translate(200,200);
canvas.drawCircle(60,60,50,mPaint2);
2.可以看到,縮放提供了來兩個方法,這兩個方法中前兩個參數是相同的分別爲x軸和y軸的縮放比例。而第二種方法比前一種多了兩個參數,用來控制縮放中心位置的。
縮放比例(sx,sy)取值範圍詳解:
取值範圍(n) | 說明 |
---|---|
[-∞, -1) | 先根據縮放中心放大n倍,再根據中心軸進行翻轉 |
-1 | 根據縮放中心軸進行翻轉 |
(-1, 0) | 先根據縮放中心縮小到n,再根據中心軸進行翻轉 |
0 | 不會顯示,若sx爲0,則寬度爲0,不會顯示,sy同理 |
(0, 1) | 根據縮放中心縮小到n |
1 | 沒有變化 |
(1, +∞) | 根據縮放中心放大n倍 |
- 通過縮放效果,可以看出,縮放的中心默認爲座標原點,而縮放中心軸就是座標軸
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //將座標移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.scale(0.5f,0.5f);
canvas.drawRect(rectF,mPaint1);
- 我們使用第二種方法讓縮放中心位置稍微改變一下,如下:
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //將座標移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.scale(0.5f,0.5f,200,0);
canvas.drawRect(rectF,mPaint1);
- 當縮放比例爲負數的時候會根據縮放中心軸進行翻轉,縮放還是在座標原點
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //將座標移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.scale(-0.5f,-0.5f);
canvas.drawRect(rectF,mPaint1);
- 如果這個時候在移動一下所放位置呢
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //將座標移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.scale(-0.5f,-0.5f,200,0);
canvas.drawRect(rectF,mPaint1);
PS:和位移(translate)一樣,縮放也是可以疊加的。
canvas.scale(0.5f,0.5f);
canvas.scale(0.5f,0.1f);
調用兩次縮放則 x軸實際縮放爲0.5x0.5=0.25 y軸實際縮放爲0.5x0.1=0.05
下面我們利用這一特性製作一個有趣的圖形。
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //將座標移到中心
RectF rectF=new RectF(-400,-400,400,400);
canvas.drawRect(rectF,mPaint1);
for (int i=0;i<20;i++){
canvas.scale(0.9f,0.9f);
canvas.drawRect(rectF,mPaint1);
}
- 旋轉(rotate)
旋轉提供了兩種方法:
public void rotate (float degrees)
public final void rotate (float degrees, float px, float py)
和縮放一樣,第二種方法多出來的兩個參數依舊是控制旋轉中心點的。
默認的旋轉中心依舊是座標原點:
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //將座標移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.rotate(180);
canvas.drawRect(rectF,mPaint1);
- 改變旋轉中心位置:
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //將座標移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.rotate(180,200,0);
canvas.drawRect(rectF,mPaint1);
當然,rotate也是可以疊加的,
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //將座標移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.rotate(180);
canvas.rotate(50);
canvas.drawRect(rectF,mPaint1);
- 斜切(skew)
斜切只提供了一種方法:
public void skew (float sx, float sy)
參數含義:
float sx:將畫布在x方向上傾斜相應的角度,sx傾斜角度的tan值,
float sy:將畫布在y軸方向上傾斜相應的角度,sy爲傾斜角度的tan值.
變換後:
X = x + sx * y
Y = y+sy * x
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //將座標移到中心
RectF rectF=new RectF(0,0,200,200);
canvas.drawRect(rectF,mPaint1);
canvas.skew(1,0); //水平斜切45
canvas.drawRect(rectF,mPaint1);