Path:
Path类封装复合(多轮廓)几何路径由直线段、二次曲线和三次曲线组成。它可以用画布绘制。drawPath(路径、绘制),填充或笔划(基于绘画的样式),或者可以用于剪裁或绘制路径上的文本。
Path属于路径,路径走多了就变成一种套路,只要我们会解套,那这种套路就是高速公路。路径走完形成闭环,最终形成一个图形。
path的合作伙伴是Paint
Paint:
paint.setAntiAlias(true);
// 设置画笔的style (Paint.Style.FILL填充,Paint.Style.STROKE描边 Paint.Style.FILL_AND_STROKE填充加描边)
paint.setStyle(Paint.Style.STROKE);
// 设置画笔的颜色
paint.setColor(Color.RED);
//设置描边宽度
paint.setStrokeWidth(10f);
关于setStyle:
1.有人会发现不同的填充效果不一样,比如绘制路径,三个点,描边出来的效果是两条线,而填充模式下是一个三角形的色块。
Paint.Style.FILL_AND_STROKE:会出现角有缺陷,在使用需要注意
paint.setStyle(Paint.Style.STROKE);
paint.setStyle(Paint.Style.FILL);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
一、Path的使用
1.构造一个path对象
1.1:构造一个空对象
public Path() 1.2 拷贝一个对象 public Path(Path src)
二、Path的方法介绍
2.1:moveTo(x,y);
path默认的起始坐标是0,0;如果想改变起始坐标,通过moveTo来设置
private void moveTo(Path path) {
path.moveTo(x, y);
path.lineTo(0, 1000);
path.lineTo(500, 500);
}
图一是没设置moveTo,默认(0,0)坐标,图二是moveTo(100,100)新的坐标点
2.2rLineTo
与lineTo相同,但坐标被视为相对于最后一个此轮廓上的点。如果没有上一个点,则将moveTo(0,0)将自动插入。
说明:这里有三个点A(0,0)B(0,1000)C(1000,0)
rLineTo:从A点到B点,C点的坐标以B点为起点,也就是后一个点以前一个坐标为起点
LineTo:直接将A、B、C三个点按顺序在view中连起来
private void rLineTo(Path path) {
path.rLineTo(0, 1000);
path.rLineTo(1000, 0);
}
rLineTo
LineTo
2.3贝塞尔曲线:quadTo
public void quadTo(float x1, float y1, float x2, float y2)
一般曲线是由三个点完成,开始,顶点,结束。在而塞尔曲线中,
(x1,y1)为曲线的顶点
(x2,y2)为曲线的结束点
开始默认是(0,0),可以通过moveTo来改变
private void quadTo(Path path) {
path.moveTo(100, 0);
path.quadTo(100, 1000, 1000, 0);
}
2.4贝塞尔曲线:rQuadTo
与quadTo相同,但坐标被视为相对于最后一个此轮廓上的点。如果没有上一个点,则将moveTo(0,0)将自动插入。
可参考上方
2.5立方贝塞尔:cubicTo
public void cubicTo(float x1, float y1, float x2, float y2,float x3, float y3)
从接近控制点的最后一点添加一个立方贝塞尔(x1,y1)和(x2,y2),并在(x3,y3)处结束。如果没有moveTo()调用对于此轮廓,第一个点自动设置为(0,0)
private void cubicTo(Path path) {
int width=getWindowSize(0)/2;
int height=getWindowSize(1)/2;
path.cubicTo(0, height, width, height, width, 0);
}
2.6圆弧:arcTo
public void arcTo(RectF oval, float startAngle, float sweepAngle, boolean forceMoveTo)
将指定的圆弧作为新轮廓附加到路径。如果开始路径与路径的当前最后一点不同,则添加了automatic lineTo()以将当前轮廓连接到弧的起点。但是,如果路径为空,则调用moveTo()弧的第一点
oval:扇形图形view大小
startAngle:开始角度
sweepAngle:扇形角度
forceMoveTo:如果为真,则始终以圆弧开始新轮廓
private void arcTo(Path path) {
paint.setStyle(Paint.Style.FILL);
RectF rectF=new RectF(0,0,500,500);
path.arcTo(rectF,startAngle,sweepAngle,true);
}
paint.setStyle(Paint.Style.STROKE)
paint.setStyle(Paint.Style.FILL)
2.7关闭当前轮廓 :close
关闭当前轮廓。如果当前点不等于轮廓的第一个点,自动添加线段。
没有调用close()之前:三个点确定两条线
private void close(Path path) {
path.moveTo(100,100);
path.lineTo(100,500);
path.lineTo(500,500);
}
未调用close()
调用close():三个点,首位相连
private void close(Path path) {
path.moveTo(100,100);
path.lineTo(100,500);
path.lineTo(500,500);
path.close();
}
调用close()
2.8将闭合矩形轮廓添加到路径:addRect
public void addRect(RectF rect, Direction dir)
rect:矩形区域
dir:缠绕矩形轮廓的方向,CW=顺时针,CCW=逆时针
private void addRect(Path path)
{
RectF rect=new RectF(0,0,500,500);
path.addRect(rect, Path.Direction.CCW);
}
2.9绘制椭圆:addOval
public void addOval(RectF oval, Direction dir)
private void addOval(Path path) {
RectF rect = new RectF(0, 0, 1000, 500);
path.addOval(rect, Path.Direction.CCW);
}
注意:如果矩形是正方形绘制出来的图形是圆形
2.10绘制圆形:addCircle
public void addCircle(float x, float y, float radius, Direction dir)
(x ,y):圆心的坐标
radius:半径
private void addCircle(Path path) {
path.addCircle(100, 100, 100, Path.Direction.CCW);
}
2.11在矩形区域画弧度:addArc
public void addArc(RectF oval, float startAngle, float sweepAngle)
如果这个矩形是一个正方形,那么画出来的弧度是半圆形,否则是一个不规则的股弧度
private void addArc(Path path) {
paint.setStyle(Paint.Style.STROKE);
RectF rect = new RectF(0, 0, 500, 500);
path.addArc(rect,0,180);
}
private void addArc(Path path) {
paint.setStyle(Paint.Style.FILL);
RectF rect = new RectF(0, 0, 500, 500);
path.addArc(rect,0,180);
}
private void addArc(Path path) {
paint.setStyle(Paint.Style.FILL);
RectF rect = new RectF(0, 0, 1000, 500);
path.addArc(rect,0,180);
}
private void addArc(Path path) {
paint.setStyle(Paint.Style.STROKE);
RectF rect = new RectF(0, 0, 1000, 500);
path.addArc(rect,0,180);
}
2.12在矩形中绘制一个圆形:addRoundRect
public void addRoundRect(RectF rect, float rx, float ry, Direction dir)
(rx,ry)代表圆形在矩形中的中心坐标,如果这个坐标正在矩形的正中心,那绘制出来的正好是圆形,否则距离中心远近代表角度的大小
注意:这里面rx或者ry中,只要有一个角的坐标为0,都无法生效。
rx和ry其实看成到各个顶点的角度百分比。
rx=ry,四个角大小是一致,否则不一样
private void addRoundRect(Path path) {
RectF rect = new RectF(0, 0, 1000, 500);
path.addRoundRect(rect,500,100, Path.Direction.CW);
}
private void addRoundRect(Path path) {
RectF rect = new RectF(0, 0, 1000, 500);
path.addRoundRect(rect,rect.right/2,rect.bottom/2, Path.Direction.CW);
}
private void addRoundRect(Path path) {
RectF rect = new RectF(0, 0, 1000, 500);
path.addRoundRect(rect,100,100, Path.Direction.CW);
}
private void addRoundRect(Path path) {
RectF rect = new RectF(0, 0, 1000, 500);
path.addRoundRect(rect,0,0, Path.Direction.CW);
}
2.13在path中添加新的path :addPath
1.public void addPath(Path src, Matrix matrix)
2.public void addPath(Path src)
3.public void addPath(Path src, float dx, float dy)
matrix和(dx,dy)可以指定src在path中的坐标,类似View在viewGroup的坐标。如果没有,默认覆盖在父path的view上,坐标dx=dy=0;
private void addPath(Path path) {
RectF rect = new RectF(0, 0, 1000, 500);
path.addRoundRect(rect,0,0, Path.Direction.CW);
Path path1=new Path(path);
Matrix matrix=new Matrix();
matrix.setTranslate(200,200);
path.addPath(path1,100,100);
path.addPath(path1,matrix);
}
2.14整体偏移 :offset
offset是针对整个path来完成偏移的,而不是某个点,MoveTo是针对起始坐标点
如下:起始坐标是0,0。通过偏移来完成整体的下移
private void offset(Path path) {
RectF rect = new RectF(0, 0, 1000, 500);
path.addRoundRect(rect,0,0, Path.Direction.CW);
path.offset(100,100);
}
2.15重置最后一个点的位置:setLastPoint
正常如下:
private void setLastPoint(Path path) {
path.lineTo(0,1000);
path.lineTo(500,1000);
// path.setLastPoint(500,500);
}
正常
path.setLastPoint(500,500)
2.16 path的控制:transform
通过Matrix对path的路径进行控制和操控,比offset更灵活,只要操作Matrix即可完成当前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 | 矩阵变换 |