- 画布:
Canvas平移:translate()使用来实现画布平移的,向右是X轴正方向,向下是Y轴正方向,画布的原点是(0,0)平移后的画布的左上角是新的坐标原点
void translate(float dx, float dy)
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.FILL);
canvas.translate(100, 100);
Rect rect = new Rect(0, 00, 400, 200);
canvas.drawRect(rect, paint);
}
- 屏幕和Canvas的关系:
- canvas相当于一个透明图层,每次在Canvas上画图时,都会新创建一个透明图层,然后在这个图层上画图,画完之后覆盖在屏幕上显示
- 总结:
- 每次调用drawXXX()函数来绘图时,都会产生一个全新的透明图层
- 但是如果在调用drawXXX()系列函数前,调用平移,旋转等函数对Canvas进行了操作,那么这个操作使得之后的每一个操作产生的画布都是这些操作后的位置
- 在Canvas图层与屏幕合成时,超出屏幕范围的图象是不会显示出来的
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint_green = generatePaint(Color.GREEN, Paint.Style.STROKE, 3);
Paint paint_red = generatePaint(Color.RED, Paint.Style.STROKE, 3);
Rect rect = new Rect(0, 0, 400, 200);
canvas.drawRect(rect, paint_green);
canvas.translate(100,100);
canvas.drawRect(rect, paint_red);
}
private Paint generatePaint(int color, Paint.Style style, int width){
Paint paint = new Paint();
paint.setColor(color);
paint.setStyle(style);
paint.setStrokeWidth(width);
return paint;
}
- 旋转:
- 注意是屏幕不是画布
//参数直接传入的是角度,正数表示顺时针,负数表示逆时针,旋转中心点为(0,0)
void rotate(float degrees)
//可以指定旋转中心点为(px, py)
void rotate(floatdegrees, float px, float py)
Paint paint_green = generatePaint(Color.GREEN, Paint.Style.STROKE, 3);
Paint paint_red = generatePaint(Color.RED, Paint.Style.STROKE, 3);
Rect rect = new Rect(10, 10, 200, 100);
canvas.drawRect(rect, paint_green);
canvas.drawRect(rect, paint_green);
//旋转30度canvas.rotate(30);
canvas.drawRect(rect, paint_red);
- 缩放:
//sx水平方向伸缩的比例,假设原坐标轴的比例为n, 不变时为1,变更后的X轴密度为n * sx,所以sx是小数表述的缩小整数表示的放大
// sy垂直方向的伸缩的比例,,同样sy为小数表示的缩小,sy为整数表示的放大
public void scale(flaot sx, float sy)
canvas.scale(0.5f, 1);
- 扭曲:
//sx为将画布在x轴方向上倾斜相应的较堵,sx为倾斜角度的正切值
//sy为将画布在y轴方向上倾斜相应的较堵,sy为倾斜较堵的正切值
void skew(float sx, float sy);
//x轴方向上倾斜60的正切值为1.732
canvas.skew(1.732f, 0);
canvas.drawRect(rect, paint_red);
- 裁剪画布:(一旦画布被裁减就不可恢复)使用裁剪函数的时候需要禁用硬件加速功能
canvas.drawColor(Color.RED);
canvas.clipRect(new Rect(100, 100, 200, 200));
canvas.drawColor(Color.GREEN);
- 画布的保存与恢复:
int save()
void restore()
- 画布的保存与恢复:
- save()和restore()函数:
- save():每次调用save()函数,都会先保存当前的画布状态,让后将其放入特定的栈中
- restore():每次调用restore()函数,都会把栈中顶层的画布状态取出来,并按照这个状态去恢复当前画布,然后在这个画布上面作画
super.onDraw(canvas);
canvas.drawColor(Color.RED);
//保存整屏画布
canvas.save();
//裁剪画布
canvas.clipRect(new Rect(100, 100, 800, 800));
canvas.drawColor(Color.GREEN);
//恢复画布
canvas.restore();
canvas.drawColor(Color.BLUE);
super.onDraw(canvas);
canvas.drawColor(Color.RED);
//保存整屏画布会将当前的画布状态保存到栈中
canvas.save();
//裁剪画布
canvas.clipRect(new Rect(100, 100, 800, 800));
canvas.drawColor(Color.GREEN);
canvas.save();
canvas.clipRect(new Rect(200, 200,700, 700));
canvas.drawColor(Color.BLUE);canvas.save();
canvas.clipRect(new Rect(300, 300, 600, 600));
canvas.drawColor(Color.BLACK);
canvas.save();
canvas.clipRect(new Rect(400,400,500,500));canvas.drawColor(Color.YELLOW);
canvas.restore();
canvas.restore();
canvas.restore();
canvas.drawColor(Color.WHITE);
- 因为会需要处理某一个画布,所以需要操作具体栈中某一个画布,restoreToCount(int saveCount),但是saveCount哪里来呢,save函数调用后 会返回一个整形值(画布所在栈的索引)
- restoreCount()方法时类似于启动模式中的singleTask,会将指定画布上面的画布全部弹出, 直到索引的画布出栈为止,所以在刚才的代码中将save方法的返回值保存起来即可,效果与之前相同