坐标转换
默认情况下,画布坐标的原点就是绘图区的左上角,向左为负,向右为正,向上为负,向下为正,但是通过 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();
}
}
结果: