Canvas、Path及PathMeasure详解

827 阅读3分钟

Canvas概念

画布,通过画笔绘制几何图形、文本、路径和位图等

Canvas常用API类型

常用API分为绘制,变换,状态保存和恢复

1、绘制几何图形,文本,位图等
void drawBitmap(Bitmap bitmap, float left, float top, Paint paint)//在指定坐标绘制位图
void drawLine(float startX, float startY, float stopX, float stopY, Paint paint)\\根据给定的起始点和结束点之间绘制连线
void drawPath(Path path, Paint paint)\\根据给定的path,绘制连线
void drawPoint(float x, float y, Paint paint)\\根据给定的坐标,绘制点
void drawText(String text, int start, int end, Paint paint)\\根据给定的坐标,绘制文字

2、位置,形状变化等
void translate(float dx, float dy)//平移操作
void scale(float sx, float sy)//缩放操作
void rotate(float degress)//选装操作
void skew(float sx,float sy)//倾斜操作
void clipRect(int left, int top, int right, int bottom)//切割操作,参数指定区域内可以继续绘制
void clipOutRect(int left, int top, int right, int bottom)//反向切割,参数指定区域内不可以继续绘制
void setMatrix(Matrix matrix)//可通过matrix实现平移,缩放,旋转等操作

3、状态保存和恢复
Canvas调用了translate,scale,rotate,skew,clipRect等变换后,后续操作都是基于变换后的Canvas,都会收到影响,对于后续的操作很不方便。Canvas提供了save,saveLayer,saveLayerAlpha,restore,restoreToCount来保存和恢复状态。
int state = canvas.save();//保存状态1
canvas.translate(70,50);//平移
canvas.drawRect(0,0,400,400,mPaint);
canvas.save();//保存状态2
canvas.restore();//返回最新的状态(状态2)
mPaint.setColor(Color.BLUE);
canvas.drawRect(0,0,400,400,mPaint);
canvas.restoreToCount(state);//手动指定的返回到状态1

Path概念

路径,可用于绘制直线,曲线构成几何路径,还可用于根据路径绘制文字

Path常用API

常用API如移动,连线,闭合,添加图形等

        mPath.moveTo(100,70);//移动
        mPath.lineTo(140,800);//连线
        //相当于上两句
        //mPath.rLineTo(40,730);
        mPath.lineTo(250,600);
        mPath.close(); //设置曲线是否闭合
        //添加弧形
        mPath.addArc(200,200,400,400,-225,225);
        //添加矩形
        mPath.addRect(500,500,900,900, Path.Direction.CW);
        //添加圆
        mPath.addCircle(700,700,200, Path.Direction.CW);
        //添加椭圆
        mPath.addOval(0,0,500,500, Path.Direction.CW);
    
        //追加图形
        //xxxTo画线
        mPath.arcTo(400, 200, 600, 400, -180,225,false);//forceMoveTo,true,绘制时移动起点,false,绘制时连接最后一个点与圆弧起点
  
        //添加圆角矩形, CW顺时针,CCW逆时针
        RectF rectF5 = new RectF(200, 800, 700, 1200);
        mPath.addRoundRect(rectF5, 20, 20, Path.Direction.CCW);
        
        //画二阶贝塞尔曲线
        mPath.moveTo(300, 500);
        mPath.quadTo(500, 100, 500, 500);
        //参数表示相对位置,等同于上面一行代码
        //mPath.rQuadTo(200, -400, 500, 0);
        
        //画三阶贝塞尔曲线
        mPath.moveTo(300, 500);
        mPath.cubicTo(500, 100, 600, 1200, 800, 500);
        //参数表示相对位置,等同于上面一行代码
        //mPath.rCubicTo(200, -400, 300, 700, 500, 0);
        

PathMeasure概念

路径测量,一个用来测量Path的工具类

PathMeasure常用API

常用API如Path长度测量,Path跳转,Path片段获取等

        /**
         * pathMeasure需要关联一个创建好的path,forceClosed会影响Path的测量结果
         * 如果Path进行了调整,需要重新调用setPath方法进行关联
         */
        PathMeasure pathMeasure = new PathMeasure();
        pathMeasure.setPath(path,true);
        Log.e(TAG,"onDraw forceClosed = true: "+pathMeasure.getLength());
        
        //截取一部分存入dst中,并且使用moveTo方法保持截取得到的Path第一个点位置不变。
        pathMeasure.getSegment(200,1000,dst,false);
        
        //跳转到下一条曲线
        pathMeasure.nextContour();
        
        //获取当前的坐标和角度
        pathMeasure.getPosTan(pathMeasure.getLength() * mFloat,pos,tan);
        
        //获取当前的坐标和角度信息保存在mMatrix中
        pathMeasure.getMatrix(pathMeasure.getLength() * mFloat, mMatrix,
                PathMeasure.POSITION_MATRIX_FLAG | PathMeasure.TANGENT_MATRIX_FLAG);