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进行平移。












网友评论