Android Canvas 平移、縮放、旋轉的理解

自己用了很久對這個幾個方法,用了好多次了,但對它們的原理概念都還是沒仔細理解清楚,真是太菜了。
View和canvas並不是同一個東西,可以這樣想象,我們的View是固定的,相當於與一個畫框,畫框範圍就是View的矩形範圍,canvas是畫布,透過畫框可以看到canvas。一開始View和Canvas是對齊的,也就是畫布的右上角就是畫框的右上角,四條邊都是對齊的,透過畫框看到整個畫布。然後canvas是可以變換的,我們平移canvas dx,dy,然後draw畫圖,就相當於把畫布拖動一段距離,然後作畫,作畫的時候座標系是按着畫布來的,跟View沒有關係。最後,透過畫框看到的圖就是移動了的圖像。同樣的旋轉就相當於把畫圖上的圖轉動了,默認原點,也可設置點。 對於縮放,要理解一下,就是畫的圖以某個點爲中心放大或者縮小。

重點的地方:我們思考這幾個變換效果的時候,總是容易按照api的順序,先思考畫布變化之後,圖像怎麼畫上去,很難像,感覺這是Android api先變畫布,在作畫這種順序設置的侷限吧,應該倒過來想纔對,是圖像畫上去之後,把畫布進行變化,這樣想起來簡單多了

值得一提的是,canvas的變換是影響後面draw的圖,不影響前面畫好的的圖,也是是canva調用draw之後,相當於畫框把畫取走了,後面的canvas是一張白布。所有的圖像在View這個畫框上面疊加,畫框外的圖是看不到的。

canvas多次變化,比如平移,縮放,旋轉,就相當於帶着所畫的圖平移,縮放,旋轉
以下內容轉載別人的:

protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);

//translate  平移,即改變座標系原點位置

Paint paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStyle(Style.FILL);

// canvas.translate(100, 100);
Rect rect1 = new Rect(0,0,400,220);
canvas.drawRect(rect1, paint);
}

在這裏插入圖片描述在這裏插入圖片描述
旋轉:
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);

Paint paint_green = generatePaint(Color.GREEN, Style.FILL, 5);
Paint paint_red   = generatePaint(Color.RED, Style.STROKE, 5);

Rect rect1 = new Rect(300,10,500,100);
canvas.drawRect(rect1, paint_red); //畫出原輪廓

canvas.rotate(30);//順時針旋轉畫布
canvas.drawRect(rect1, paint_green);//畫出旋轉後的矩形

}

效果圖是這樣的:在這裏插入圖片描述
縮放:

Paint mPaint = new Paint();
canvas.drawColor(Color.BLUE);
mPaint.setColor(Color.GRAY);
canvas.drawRect(new Rect(0, 0, 400, 400), mPaint);

// 保存畫布狀態
canvas.save();
canvas.scale(0.5f, 0.5f, 200, 200);
mPaint.setColor(Color.RED);
canvas.drawRect(new Rect(0, 0, 400, 400), mPaint);
在這裏插入圖片描述

Canvas.scale (float sx, float sy, float px, float py) 源碼如下:

/**

  • Preconcat the current matrix with the specified scale.
  • @param sx The amount to scale in X
  • @param sy The amount to scale in Y
  • @param px The x-coord for the pivot point (unchanged by the scale)
  • @param py The y-coord for the pivot point (unchanged by the scale)
    /
    public final void scale(float sx, float sy, float px, float py) {
    translate(px, py);
    scale(sx, sy);
    translate(-px, -py);
    }
    translate(px, py)移動的物理距離分別是px和py,經過scale(sx, sy)縮放後再通過translate(-px, -py)位移,移動的物理距離就是-px
    sx和-py*sy。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章