美文网首页自定义View
自定义View(六)Path基础

自定义View(六)Path基础

作者: 光羽隼 | 来源:发表于2018-11-14 16:26 被阅读0次

    Path(路径)这个知识点GcsSloop大神写了大概三篇文章进行了详细的讲解,是一个挺重要的知识点。
    先解释一下Path(路径)这个词,Path这个词解释为路径,也就是我们画在屏幕上的图像,之前我们见到的Canvas中都是画一些固定的形状,现在我们能用Path对象进行一些复杂图形的绘制了,路径可以随便画,不必再被特殊的图形所限制。

    Path封装了由直线和曲线(二次,三次贝塞尔曲线)构成的几何路径。你能用Canvas中的drawPath来把这条路径画出来(同样支持Paint的不同绘制模式),也可以用于剪裁画布和根据路径绘制文字。我们有时会用Path来描述一个图像的轮廓,所以也会称为轮廓线(轮廓线仅是Path的一种使用方法,两者并不等价)

    Path 常用方法表

    作用 相关方法 备注
    移动起点 moveTo 移动下一次操作的起点位置
    设置终点 setLastPoint 重置当前path中最后一个点位置,如果在绘制之前调用,效果和moveTo相同
    连接直线 lineTo 添加上一个点到当前点之间的直线到Path
    闭合路径 close 连接第一个点连接到最后一个点,形成一个闭合区域
    添加内容 addRect, addRoundRect, addOval, addCircle, addPath, addArc,arcTo 添加(矩形, 圆角矩形, 椭圆, 圆, 路径, 圆弧) 到当前Path (注意addArcarcTo的区别)
    是否为空 isEmpty 判断Path是否为空
    是否为矩形 isRect 判断path是否是一个矩形
    替换路径 set 用新的路径替换到当前路径所有内容
    偏移路径 offset 对当前路径之前的操作进行偏移(不会影响之后的操作)
    贝塞尔曲线 quadTo, cubicTo 分别为二次和三次贝塞尔曲线的方法
    rXxx方法 rMoveTo, rLineTo,rQuadTo, rCubicTo 不带r的方法是基于原点的坐标系(偏移量), rXxx方法是基于当前点坐标系(偏移量)
    填充模式 setFillType, getFillType, isInverseFillType, toggleInverseFillType 设置,获取,判断和切换填充模式
    提示方法 incReserve 提示Path还有多少个点等待加入(这个方法貌似会让Path优化存储结构)
    布尔操作(API19) op 对两个Path进行布尔运算(即取交集、并集等操作)
    计算边界 computeBounds 计算Path的边界
    重置路径 reset,rewind 清除Path中的内容 reset不保留内部数据结构,但会保留FillType.rewind会保留内部的数据结构,但不保留FillType
    矩阵操作 transform 矩阵变换

    Path基础

    moveTosetLastPointlineToclose

    path.moveTo(10,10);
    path.lineTo(20,20);
    moveTo()方法是指定从哪一点开始走路经,仅仅制定了路径的起点。既然moveTo()指定了路径的起点,那么lineTo()这个方法就是指定下一步往哪走。万一提前没有moveTo()方法,那么默认的起始点就是坐标系原点。
    setLastPoint();方法是改变上一个点的位置:

    canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心
    
    Path path = new Path();                     // 创建Path
    
    path.lineTo(200, 200);                      // lineTo
    
    path.setLastPoint(200,100);                 // setLastPoint
    
    path.lineTo(200,0);                         // lineTo
    
    canvas.drawPath(path, mPaint);              // 绘制Path
    
    image.png
    这个例子是从默认点出发,走到(200,200),然后调用setLastPoint(200,100)这个方法将路径从上一个点改变到这一个点上,然后继续走到(200,0)
    如果在linTo()之后调用moveTo()方法会怎样呢?
    canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心
    
    Path path = new Path();                     // 创建Path
    
    path.lineTo(200, 200);                      // lineTo
    
    path.moveTo(200,100);                       // moveTo
    
    path.lineTo(200,0);                         // lineTo
    
    canvas.drawPath(path, mPaint);              // 绘制Path
    
    image.png
    lineTo()方法之后调用moveTo(),相当于重新开始了一个路径,重新设置了新路径的起点。并不会连接上一个点。
    close()方法作用是连接起始点(moveTo()方法指定的点,如果没有moveTo()方法指定,那就是坐标系原点。)和终点。
            canvas.translate(mWidth/2,mHeight/2);
            Path path = new Path();
            path.lineTo(200,200);
            path.lineTo(300,200);
            path.moveTo(200,100);
            path.lineTo(200,0);
            path.lineTo(300,0);
            path.close();
            canvas.drawPath(path,paint);
    
    close()
    上边我们看到,close()只作用在了moveTo()方法开始的路径,前边的路径没有被闭合。说明moveTo()是新开了一条路径。

    addXxx()

    第一类添加基本图形。

    这类方法主要是往path中添加图形。

    // 第一类(基本形状)
    
    // 圆形
    public void addCircle (float x, float y, float radius, Path.Direction dir)
    // 椭圆
    public void addOval (RectF oval, Path.Direction dir)
    // 矩形
    public void addRect (float left, float top, float right, float bottom, Path.Direction dir)
    public void addRect (RectF rect, Path.Direction dir)
    // 圆角矩形
    public void addRoundRect (RectF rect, float[] radii, Path.Direction dir)
    public void addRoundRect (RectF rect, float rx, float ry, Path.Direction dir)
    

    主要是添加矩形,椭圆等图形,跟前面的操作区别不大。我们主要注意Path.Direction 这个参数,

    类型 解释 翻译
    CW clockwise 顺时针
    CCW counter-clockwise 逆时针

    这个参数主要是定义了图形的闭合路径,从左上角开始,是顺时针闭合还是逆时针闭合。一个正常的矩形,不论顺时针还是逆时针都没什么区别,但是如果是不规则多边形,顺时针和逆时针就不同了。

    canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心
    
    Path path = new Path();
    
    path.addRect(-200,-200,200,200, Path.Direction.CW);
    
    path.setLastPoint(-300,300);                // <-- 重置最后一个点的位置
    
    canvas.drawPath(path,mPaint);
    
    顺时针
    canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心
    
    Path path = new Path();
    
    path.addRect(-200,-200,200,200, Path.Direction.CCW);
    
    path.setLastPoint(-300,300);                // <-- 重置最后一个点的位置
    
    canvas.drawPath(path,mPaint);
    
    逆时针
    上边两个例子是一个相同路径的顺时针和逆时针的两种表现形式。
    Path.Direction不仅影响图形的形状,还会影响图形的填充效果。下边会讲到。

    第二类(addPath

    // 第二类(Path)
    // path
    public void addPath (Path src)
    public void addPath (Path src, float dx, float dy)
    public void addPath (Path src, Matrix matrix)
    

    这个方法其实就是将两个路径合并到一块。
    第二个方法后边两个参数作用是将src进行位移之后添加到指定path中。
    第三个方法是将src进行matrix变换之后添加到指定的path中。

    第三类(addArcarcTo)

    // 第三类(addArc与arcTo)
    
    // addArc
    public void addArc (RectF oval, float startAngle, float sweepAngle)
    // arcTo
    public void arcTo (RectF oval, float startAngle, float sweepAngle)
    public void arcTo (RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
    

    这是在当前path添加圆弧的方法。

    参数 摘要
    oval 圆弧的外切矩形。
    startAngle 开始角度
    sweepAngle 扫过角度(-360 <= sweepAngle <360)
    forceMoveTo 是否强制使用MoveTo

    addArc()方法直接添加一个圆弧到指定path中,而arcTo()是将圆弧添加到path中,根据forceMoveTo参数值来判断,如果forceMoveTotrue,则将圆弧移动,将圆弧的起点和path的终点连接起来,如果forceMoveTofalse,则将圆弧的起点和path的重点连接起来。

    第3组:isEmptyisRectisConvexsetoffset

    isEmpty

    判断path中是否有内容

    isRect(RectF rect)

    判断path是不是一个矩形,如果是矩形,则将矩形信息存储到rect

    set(Path path1)

    将新的path复制给老的path

    path.set(path1);
    //等价于
    path=path1;
    

    offset

    public void offset (float dx, float dy)
    public void offset (float dx, float dy, Path dst)
    

    这个方法就是将path进行位移

    dst状态 效果
    dst不为空 将当前path平移后的状态存入dst中,不会影响当前path
    dst为空(null) 平移将作用于当前path,相当于第一种方法
    canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心
    canvas.scale(1,-1);                         // <-- 注意 翻转y坐标轴
    
    Path path = new Path();                     // path中添加一个圆形(圆心在坐标原点)
    path.addCircle(0,0,100, Path.Direction.CW);
    
    Path dst = new Path();                      // dst中添加一个矩形
    dst.addRect(-200,-200,200,200, Path.Direction.CW);
    
    path.offset(300,0,dst);                     // 平移
    
    canvas.drawPath(path,mPaint);               // 绘制path
    
    mPaint.setColor(Color.BLUE);                // 更改画笔颜色
    
    canvas.drawPath(dst,mPaint);                // 绘制dst
    
    offset

    本来感觉没多少内容的,写着写着就变得那么多。。。。
    总结:

    path就是一条路径,我们可以调用CanvasdrawPath()方法将path绘制到屏幕上。path可以自己画路径,使用moveTolineTosetLastPointclose等方法。也可以addXxx添加矩形,椭圆等图形到path中,也可以使用addPath添加path到指定path中,当然我们也可以判断path是否为空,是否是矩形,也可以使用offset方法对path进行平移。

    相关文章

      网友评论

        本文标题:自定义View(六)Path基础

        本文链接:https://www.haomeiwen.com/subject/dsidfqtx.html