自定義View-座標轉換
阿新 • • 發佈:2018-12-23
座標轉換
預設情況下,畫布座標的原點就是繪圖區的左上角,向左為負,向右為正,向上為負,向下為正,但是通過 Canvas ᨀ供的方法可以對座標進行轉換。轉換的方式主要有 4 種:平移、旋轉、縮放和拉斜:
程式碼段 1:
成:canvas.skew(1, 0)。
座標轉換後,後面的圖形繪製功能將跟隨新座標,轉換前已經繪製的圖形不會有任何的變化。另外,為了能恢復到座標變化之前的狀態,Canvas 定義了兩個方法用於儲存現場和恢復現場:
結果:
預設情況下,畫布座標的原點就是繪圖區的左上角,向左為負,向右為正,向上為負,向下為正,但是通過 Canvas ᨀ供的方法可以對座標進行轉換。轉換的方式主要有 4 種:平移、旋轉、縮放和拉斜:
1)平移:
public void translate(float dx,float dy)
座標平移,在當前原點的基礎上水平移動 dx 個距離,垂直移動 dy 個距離,正負符號決定方向。座標原點改變後,所有的座標都是以新的原點為參照進行定位。下面兩段程式碼是等效的:
程式碼段 1:
canvas.drawPoint(10, 10, paint);
程式碼段 2:
canvas.translate(10, 10); canvas.drawPoint(0, 0, paint);
2)旋轉:
public void rotate(float degrees)
將畫布的座標以當前原點為中心旋轉指定的角度,如果角度為正,則為順時針旋轉,否則為逆時針旋轉。
public final void rotate(float degrees,float px,float py)
以點(px,
py)為中心對畫布座標進行旋轉 degrees 度,為正表示順時針,為負表示逆時針。
3)縮放:
public void scale(float sx,float sy)
縮放畫布的座標,sx、sy 分別是 x 方向和 y 方向的縮放比例,小於 1 表示縮小,等於1 表示不變,大於 1 表示放大。畫布縮放後,繪製在畫布上的圖形也會等比例縮放。
縮放的單位是倍數,比如 sx 為 0.5 時,就是在 x 方向縮小 0.5 倍。
public final void scale(float sx,float sy,float px,float py)
以(px,py)為中心對畫布進行縮放。
4)拉斜:
public void skew(float sx,float sy)
將畫布分別在 x 方向和 y 方向拉斜一定的角度,sx 為 x 方向傾斜角度的 tan 值,sy 為y 方向傾斜角度的 tan 值,比如我們打算在 X 軸方向上傾斜 45 度,則 tan45=1,寫
成:canvas.skew(1, 0)。
座標轉換後,後面的圖形繪製功能將跟隨新座標,轉換前已經繪製的圖形不會有任何的變化。另外,為了能恢復到座標變化之前的狀態,Canvas 定義了兩個方法用於儲存現場和恢復現場:
public int save ()
儲存現場。
public void restore ()
恢復現場到 save()執行之前的狀態。
MainActivity:
public class CoordinateView extends View {
public CoordinateView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.RED);
paint.setStrokeWidth(2);//設定邊的寬度
paint.setStyle(Paint.Style.STROKE);//設定畫筆的樣式為描邊
//儲存現場
canvas.save();
for (int i = 0; i < 5; i++) {
canvas.drawRect(0, 0, 150, 150, paint);
canvas.translate(30, 30);
}
//恢復現場
canvas.restore();//恢復現場到 save()執行之前的狀態。
//平移座標,讓接下來的圖形繪製在上一次圖形的下面
canvas.translate(0, 300);
canvas.save();
for (int i = 0; i < 5; i++) {
canvas.drawRect(0, 0, 400, 400, paint);
canvas.scale(0.9f, 0.9f, 200, 200);
}
canvas.restore();//恢復現場到 save()執行之前的狀態。 也就是在矩形的下面
//平移座標,讓接下來的圖形繪製在上一次圖形的下面
canvas.translate(0, 450);
canvas.save();
canvas.drawCircle(200, 200, 200, paint);
for (int i = 0; i < 12; i++) {
canvas.drawLine(350, 200, 400, 200, paint);
canvas.rotate(30, 200, 200);
}
canvas.restore();
}
}
結果: