Canvas的操作可以帮助我们更好的画图。
要学习Canvas的用法,可以访问Google官网,https://developer.android.google.cn/reference/android/graphics/Canvas.html
Canvas操作主要有以下几种:
操作 | 方法 | 备注 |
---|---|---|
位移(translate) | [translate](https://developer.android.google.cn/reference/android/graphics/Canvas.html#translate(float, float))(float dx, float dy) | Preconcat the current matrix with the specified translation |
缩放(scale) | [scale](https://developer.android.google.cn/reference/android/graphics/Canvas.html#scale(float, float))(float sx, float sy)/[scale](https://developer.android.google.cn/reference/android/graphics/Canvas.html#scale(float, float, float, float))(float sx, float sy, float px, float py) | Preconcat the current matrix with the specified scale. |
旋转(rotate) | rotate(float degrees)/[rotate](https://developer.android.google.cn/reference/android/graphics/Canvas.html#rotate(float, float, float))(float degrees, float px, float py) | Preconcat the current matrix with the specified rotation. |
斜切(skew) | [skew](https://developer.android.google.cn/reference/android/graphics/Canvas.html#skew(float, float))(float sx, float sy) | Preconcat the current matrix with the specified skew. |
- translate是坐标系的移动,可以为图形绘制选择一个合适的坐标系。 请注意,位移是基于当前位置移动,而不是每次基于屏幕左上角的(0,0)点移动
canvas.drawCircle(60,60,50,mPaint2);
canvas.translate(200,200);
canvas.drawCircle(60,60,50,mPaint2);
2.可以看到,缩放提供了来两个方法,这两个方法中前两个参数是相同的分别为x轴和y轴的缩放比例。而第二种方法比前一种多了两个参数,用来控制缩放中心位置的。
缩放比例(sx,sy)取值范围详解:
取值范围(n) | 说明 |
---|---|
[-∞, -1) | 先根据缩放中心放大n倍,再根据中心轴进行翻转 |
-1 | 根据缩放中心轴进行翻转 |
(-1, 0) | 先根据缩放中心缩小到n,再根据中心轴进行翻转 |
0 | 不会显示,若sx为0,则宽度为0,不会显示,sy同理 |
(0, 1) | 根据缩放中心缩小到n |
1 | 没有变化 |
(1, +∞) | 根据缩放中心放大n倍 |
- 通过缩放效果,可以看出,缩放的中心默认为坐标原点,而缩放中心轴就是坐标轴
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //将坐标移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.scale(0.5f,0.5f);
canvas.drawRect(rectF,mPaint1);
- 我们使用第二种方法让缩放中心位置稍微改变一下,如下:
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //将坐标移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.scale(0.5f,0.5f,200,0);
canvas.drawRect(rectF,mPaint1);
- 当缩放比例为负数的时候会根据缩放中心轴进行翻转,缩放还是在坐标原点
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //将坐标移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.scale(-0.5f,-0.5f);
canvas.drawRect(rectF,mPaint1);
- 如果这个时候在移动一下所放位置呢
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //将坐标移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.scale(-0.5f,-0.5f,200,0);
canvas.drawRect(rectF,mPaint1);
PS:和位移(translate)一样,缩放也是可以叠加的。
canvas.scale(0.5f,0.5f);
canvas.scale(0.5f,0.1f);
调用两次缩放则 x轴实际缩放为0.5x0.5=0.25 y轴实际缩放为0.5x0.1=0.05
下面我们利用这一特性制作一个有趣的图形。
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //将坐标移到中心
RectF rectF=new RectF(-400,-400,400,400);
canvas.drawRect(rectF,mPaint1);
for (int i=0;i<20;i++){
canvas.scale(0.9f,0.9f);
canvas.drawRect(rectF,mPaint1);
}
- 旋转(rotate)
旋转提供了两种方法:
public void rotate (float degrees)
public final void rotate (float degrees, float px, float py)
和缩放一样,第二种方法多出来的两个参数依旧是控制旋转中心点的。
默认的旋转中心依旧是坐标原点:
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //将坐标移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.rotate(180);
canvas.drawRect(rectF,mPaint1);
- 改变旋转中心位置:
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //将坐标移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.rotate(180,200,0);
canvas.drawRect(rectF,mPaint1);
当然,rotate也是可以叠加的,
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //将坐标移到中心
RectF rectF=new RectF(0,-400,400,0);
canvas.drawRect(rectF,mPaint1);
canvas.rotate(180);
canvas.rotate(50);
canvas.drawRect(rectF,mPaint1);
- 斜切(skew)
斜切只提供了一种方法:
public void skew (float sx, float sy)
参数含义:
float sx:将画布在x方向上倾斜相应的角度,sx倾斜角度的tan值,
float sy:将画布在y轴方向上倾斜相应的角度,sy为倾斜角度的tan值.
变换后:
X = x + sx * y
Y = y+sy * x
int width=getWidth();
int height=getHeight();
canvas.translate(width/2,height/2); //将坐标移到中心
RectF rectF=new RectF(0,0,200,200);
canvas.drawRect(rectF,mPaint1);
canvas.skew(1,0); //水平斜切45
canvas.drawRect(rectF,mPaint1);