画布裁剪
裁剪涉及到一个Region.Op区域组合的问题:
假设用region A 去组合region B public enum Op { DIFFERENCE(0), //A和B的差集范围,即A - B,只有在此范围内的绘制内容才会被显示; INTERSECT(1), // 即A和B的交集范围,只有在此范围内的绘制内容才会被显示 UNION(2), //即A和B的并集范围,即两者所包括的范围的绘制内容都会被显示; XOR(3), //A和B的补集范围,此例中即A除去B以外的范围,只有在此范围内的绘制内容才会被显示; REVERSE_DIFFERENCE(4), //B和A的差集范围,即B - A,只有在此范围内的绘制内容才会被显示; REPLACE(5); //不论A和B的集合状况,B的范围将全部进行显示,如果和A有交集,则将覆盖A的交集范围; }clipPath( ),clipRect( ),clipRegion( );通过Path,Rect,Region的不同组合,几乎可以支持任意形状的裁剪区域!
这里演示一个Region.Op.DIFFERENCE,将画笔改为FILL,然后:
canvas.clipRect(10, 10, 110, 110); //第一个 canvas.clipRect(50, 50, 150, 150, Region.Op.DIFFERENCE); //第二个 canvas.drawRect(0, 0, 200, 200, paint_green);
画布状态
画布变换
画布变换主要包括translate(位移)、scale(缩放)、rotate(旋转)、skew(倾斜),画布操作可以帮助我们更加容易的方式制作图形。
【位移translate】
public void translate(float dx, float dy)基于当前坐标系的移动,并不是屏幕左上角的原点位置:
//构造一个矩形 Rect rect1 = new Rect(0, 0, 200, 100); canvas.translate(50, 50); //在平移画布前用绿色画下边框 canvas.drawRect(rect1, paint_green); //平移画布后,再用红色边框重新画下这个矩形 canvas.translate(50, 50); canvas.drawRect(rect1, paint_red);
【缩放scale】
public void scale (float sx, float sy),分别是x,y轴的缩放比例 public final void scale (float sx, float sy, float px, float py),x.y轴的缩放比例,px,py表示缩放中心位置其中当缩放比例为负数时候,会根据缩放中心轴进行翻转。
套用网上一个经典的例子(画笔要设置粗一点,不然会有部分显示不全):
canvas.translate(mWidth/2,mHeight/2); RectF rectf = new RectF(-300,-300,300,300); for (int i=0;i<15;i++){ canvas.scale(0.8f,0.8f); canvas.drawRect(rectf,paint_red); }
【旋转 rotate】
public void rotate (float degrees),旋转角度(顺时针) public final void rotate (float degrees, float px, float py),旋转角度和控制点这个在画表盘啥的很常用。同样跟位移一样,旋转度数也是可以叠加的。
【错切 skew】
public void skew (float sx, float sy) float sx:将画布在x方向上倾斜相应的角度,sx倾斜角度的tan值, float sy:将画布在y轴方向上倾斜相应的角度,sy为倾斜角度的tan值. Rect rect1 = new Rect(10,10,200,100); canvas.drawRect(rect1, paint_green); canvas.skew(1,0);//X轴倾斜45度,Y轴不变 canvas.drawRect(rect1, paint_red);
绘制文本
普通水平绘制drawText
这个比较简单,但是需要注意绘制text绘制精确位置使用FontMetrics,主要包含四个参数:
ascent = ascent线的y坐标 - baseline线的y坐标; descent = descent线的y坐标 - baseline线的y坐标; top = top线的y坐标 - baseline线的y坐标; bottom = bottom线的y坐标 - baseline线的y坐标;
指定每个文字位置
void drawPosText (char[] text, int index, int count, float[] pos, Paint paint) void drawPosText (String text, float[] pos, Paint paint)