轉自:http://www.cnblogs.com/xqxacm/p/6667739.html
Canvas 畫布
從前面我們已經知道了 Canvas 類可以繪出 各種形狀。
這裏學習一下Canvas 類的變換效果(平移,旋轉等)
首先需要了解一下Canvas 畫布, 我們用Canvas.DrawXXX()方法的時候並不是在一張畫布上進行繪製。而是每次調用.DrawXXX()方法,都會生成一個新的畫布並在上面繪製,這就類似於PS中的圖層。
從下面會看到解釋。
一、偏移(.translate)
即讓畫布平移,之後上面的繪製操作也會跟着平移
public void translate(float dx, float dy) ; //畫布偏移
float dx:水平方向平移的距離,正數指向正方向(向右)平移的量,負數爲向負方向(向左)平移的量 flaot dy:垂直方向平移的距離,正數指向正方向(向下)平移的量,負數爲向負方向(向上)平移的量
Paint paint = new Paint(); paint.setStyle(Paint.Style.FILL); paint.setColor(Color.RED); paint.setStrokeWidth(2); //先繪製一個 左上角座標(100,100) 寬300 高200 的矩形 canvas.drawRect(100,100,400,300,paint); //對畫布進行平移操作 canvas.translate(120,120); paint.setColor(Color.BLACK); //繪製一個寬300 高200 的矩形 ,因爲畫布向右平移了120px,向下平移了120px, // 所以這時距屏幕左上角的距離爲(100+120,100+120) canvas.drawRect(100,100,400,300,paint);
從下可見綠色框的是平移(100,100)後的新畫布的位置,多出界面的部分不再顯示
黑色的矩形是在新的畫布位置(綠色框)左上角爲原點,(100,100)位置繪製的
注意這時候,每次drawXXX 繪製的畫布位置都以新的畫布爲準,比如我再繪製一個矩形
Paint paint = new Paint(); paint.setStyle(Paint.Style.FILL); paint.setColor(Color.RED); paint.setStrokeWidth(2); //先繪製一個 左上角座標(100,100) 寬300 高200 的矩形 canvas.drawRect(100,100,400,300,paint); //對畫布進行平移操作 canvas.translate(120,120); paint.setColor(Color.BLACK); //繪製一個寬300 高200 的矩形 ,因爲畫布向右平移了120px,向下平移了120px, // 所以這時距屏幕左上角的距離爲(100+120,100+120) canvas.drawRect(100,100,400,300,paint); //再繪製一個藍色的矩形 ,看看這個矩形是以平移前的畫布左上角爲原點還是以平移後的畫布左上角爲原點 paint.setColor(Color.BLUE); canvas.drawRect(200,200,500,400,paint);
可見當畫布進行轉換(平移、旋轉等)操作之後,往後drawXXX的時候都以新的畫布位置爲準
那麼,比如我只想讓第二個矩形所在的畫布平移,而往後的都是以原來的畫布爲準,怎麼辦,難道還需要逆向操作,怎麼平移出去的再怎麼平移回來麼
其實Canvas類還有 兩個方法:
canvas.save(); //把畫布的狀態(位置等)保存到棧中 canvas.restore(); //把棧中最頂層的畫布狀態取出來,並按照這個狀態恢復當前的畫布
舉例:
Paint paint = new Paint(); paint.setStyle(Paint.Style.FILL); paint.setColor(Color.RED); paint.setStrokeWidth(2); //先繪製一個 左上角座標(100,100) 寬300 高200 的矩形 canvas.drawRect(100,100,400,300,paint); canvas.save(); //保存當前畫布狀態 //對畫布進行平移操作 canvas.translate(120,120); paint.setColor(Color.BLACK); //繪製一個寬300 高200 的矩形 ,因爲畫布向右平移了120px,向下平移了120px, // 所以這時距屏幕左上角的距離爲(100+120,100+120) canvas.drawRect(100,100,400,300,paint); canvas.restore(); //恢復成棧頂保存的畫布狀態 //再繪製一個藍色的矩形 ,看看這個矩形是以平移前的畫布左上角爲原點還是以平移後的畫布左上角爲原點 paint.setColor(Color.BLUE); canvas.drawRect(200,200,500,400,paint);
可以看到,紅色矩形是在原始畫布上繪製的,然後保存原始畫布的狀態,
將畫布平移(100,100) 繪製一個黑色的矩形,繪製之後將畫布狀態恢復到棧頂保存的狀態
這時候再繪製一個藍色的矩形,會發現這個藍色矩形是在原狀態畫布上繪製的。
二、旋轉(.rotate)
public void rotate(float degrees) public void rotate (float degrees, float px, float py)
第一個構造函數直接輸入旋轉的度數,正數是順時針旋轉,負數指逆時針旋轉,它的旋轉中心點是原點(0,0)
第二個構造函數除了度數以外,還可以指定旋轉的中心點座標(px,py)
Paint paint = new Paint(); paint.setStyle(Paint.Style.FILL); paint.setColor(Color.RED); paint.setStrokeWidth(2); //先繪製一個 左上角座標(100,100) 寬300 高200 的矩形 canvas.drawRect(200,200,400,300,paint); //對畫布進行旋轉操作 canvas.rotate(15); // 控制旋轉的角度,順時針 paint.setColor(Color.BLACK); //繪製一個寬300 高200 的矩形 ,因爲畫布向右平移了120px,向下平移了120px, // 所以這時距屏幕左上角的距離爲(100+120,100+120) canvas.drawRect(200,200,400,300,paint);
三、縮放(.scale)
public void scale (float sx, float sy) sx : 水平縮放的程度
sy : 垂直縮放的程度
單位float, >1 表示擴大, <1 表示縮小 =1表示不變化
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setStrokeWidth(2);
//先繪製一個 左上角座標(100,100) 寬300 高200 的矩形
canvas.drawRect(0,0,400,300,paint);
//對畫布進行縮放操作
canvas.scale(0.5f,0.5f); //縮小一半
paint.setColor(Color.BLACK);
//繪製一個寬300 高200 的矩形 ,因爲畫布向右平移了120px,向下平移了120px,
// 所以這時距屏幕左上角的距離爲(100+120,100+120)
canvas.drawRect(0,0,400,300,paint);
四、傾斜(.skew)
public void skew (float sx, float sy) float sx:將畫布在x方向上傾斜相應的角度,sx傾斜角度的tan值, float sy:將畫布在y軸方向上傾斜相應的角度,sy爲傾斜角度的tan值,
注意:傾斜角度的tan值,比如傾斜60度,tan60=根號3,小數對應1.732,那麼參數就是1.732
Paint paint = new Paint(); paint.setStyle(Paint.Style.FILL); paint.setColor(Color.RED); paint.setStrokeWidth(2); //先繪製一個 左上角座標(100,100) 寬300 高200 的矩形 canvas.drawRect(0,0,400,300,paint); //對畫布進行縮放操作 canvas.skew(1.732f,0); //縮小一半 paint.setColor(Color.BLACK); canvas.drawRect(0,0,400,300,paint);