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 (注意addArc 和arcTo 的区别) |
是否为空 | 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
基础
moveTo
、 setLastPoint
、 lineTo
和 close
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
中。
第三类(addArc
与arcTo
)
// 第三类(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
参数值来判断,如果forceMoveTo
为true
,则将圆弧移动,将圆弧的起点和path
的终点连接起来,如果forceMoveTo
为false
,则将圆弧的起点和path
的重点连接起来。
第3组:isEmpty
、 isRect
、isConvex
、 set
和 offset
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
就是一条路径,我们可以调用Canvas
的drawPath()
方法将path
绘制到屏幕上。path
可以自己画路径,使用moveTo
、lineTo
、setLastPoint
、close
等方法。也可以addXxx
添加矩形,椭圆等图形到path
中,也可以使用addPath
添加path
到指定path
中,当然我们也可以判断path
是否为空,是否是矩形,也可以使用offset
方法对path
进行平移。
网友评论