文章目录
简介
本文会了解到 path
(路径)这个 Canvas
中的神器,有了这个神器,就能创造出更多炫酷的东东。
使用 Path
不仅能够绘制简单图形,也可以绘制这些比较复杂的图形。另外,根据路径绘制文本和剪裁画布都会用到 Path
。
常用方法
Path 使用方法详解
1. moveTo、 setLastPoint、 lineTo 和 close
首先创建画笔:
Paint mPaint = new Paint(); // 创建画笔
mPaint.setColor(Color.BLACK); // 画笔颜色 - 黑色
mPaint.setStyle(Paint.Style.STROKE); // 填充模式 - 描边
mPaint.setStrokeWidth(10); // 边框宽度 - 10
lineTo
public void lineTo (float x, float y)
lineTo
很简单,只有一个方法,作用也很容易理解,就是一条线。
canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心(宽高数据在onSizeChanged中获取)
Path path = new Path(); // 创建Path
path.lineTo(200, 200); // lineTo
path.lineTo(200,0);
canvas.drawPath(path, mPaint); // 绘制Path
第一次由于之前没有过操作,所以默认点就是坐标原点O,结果就是坐标原点O到A(200,200)之间连直线(用蓝色圈1标注)。
第二次lineTo的时候,由于上次的结束位置是A(200,200),所以就是A(200,200)到B(200,0)之间的连线(用蓝色圈2标注)。
- moveTo
方法预览
// moveTo
public void moveTo (float x, float y)
示例
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
moveTo 只改变下次操作的起点,在执行完第一次 LineTo 的时候,本来的默认点位置是A(200,200),但是 moveTo将其改变成为了C(200,100),所以在第二次调用 lineTo 的时候就是连接C(200,100) 到 B(200,0)之间的直线(用蓝色圈2标注)。
- setLastPoint
方法预览:
// setLastPoint
public void setLastPoint (float dx, float dy)
示例
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
setLastPoint 是重置上一次操作的最后一个点,在执行完第一次的lineTo的时候,最后一个点是A(200,200),而 setLastPoint 更改最后一个点为C(200,100),所以在实际执行的时候,第一次的lineTo就不是从原点O到A(200,200)的连线了,而变成了从原点O到C(200,100)之间的连线了。
在执行完第一次 lineTo 和 setLastPoint后,最后一个点的位置是C(200,100),所以在第二次调用lineTo的时候就是C(200,100) 到 B(200,0)之间的连线(用蓝色圈2标注)。
- close
方法预览
public void close ()
close方法用于连接当前最后一个点和最初的一个点(如果两个点不重合的话),最终形成一个封闭的图形。
canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心
Path path = new Path(); // 创建Path
path.lineTo(200, 200); // lineTo
path.lineTo(200,0); // lineTo
path.close(); // close
canvas.drawPath(path, mPaint); // 绘制Path
注意:close的作用是封闭路径,与连接当前最后一个点和第一个点并不等价。如果连接了最后一个点和第一个点仍然无法形成封闭图形,则close什么 也不做。
2. addXxx与arcTo
- 基本形状
方法预览
// 圆形
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 : 方向,趋势。
示例
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);
3. Path
方法预览
// 第二类(Path)
// path
public void addPath (Path src)
public void addPath (Path src, float dx, float dy)
public void addPath (Path src, Matrix matrix)
示例:
canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心
canvas.scale(1,-1); // <-- 注意 翻转y坐标轴
Path path = new Path();
Path src = new Path();
path.addRect(-200,-200,200,200, Path.Direction.CW);
src.addCircle(0,0,100, Path.Direction.CW);
path.addPath(src,0,200);
mPaint.setColor(Color.BLACK); // 绘制合并后的路径
canvas.drawPath(path,mPaint);
4. 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)
参数说明:
- oval 圆弧的外切矩形。
- startAngle 开始角度
- sweepAngle 扫过角度(-360 <= sweepAngle <360)
- forceMoveTo 是否强制使用 MoveTo
两者区别:
示例
canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心
canvas.scale(1,-1); // <-- 注意 翻转y坐标轴
Path path = new Path();
path.lineTo(100,100);
RectF oval = new RectF(0,0,300,300);
path.addArc(oval,0,270);
// path.arcTo(oval,0,270,true); // <-- 和上面一句作用等价
canvas.drawPath(path,mPaint);
5. isEmpty、 isRect、isConvex、 set 和 offset
- isEmpty
方法预览:public boolean isEmpty ()
判断path中是否包含内容。
Path path = new Path();
Log.e("1",path.isEmpty()+"");
path.lineTo(100,100);
Log.e("2",path.isEmpty()+"");
输出结果:
true
false
- isRect
方法预览:public boolean isRect (RectF rect)
判断 path 是否是一个矩形,如果是一个矩形的话,会将矩形的信息存放进参数 rect 中。
示例
path.lineTo(0,400);
path.lineTo(400,400);
path.lineTo(400,0);
path.lineTo(0,0);
RectF rect = new RectF();
boolean b = path.isRect(rect);
Log.e("Rect","isRect:"+b+"| left:"+rect.left+"| top:"+rect.top+"| right:"+rect.right+"| bottom:"+rect.bottom);
输出结果:
isRect:true| left:0.0| top:0.0| right:400.0| bottom:400.0
- set
方法预览:public void set (Path src)
canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心
canvas.scale(1,-1); // <-- 注意 翻转y坐标轴
Path path = new Path(); // path添加一个矩形
path.addRect(-200,-200,200,200, Path.Direction.CW);
Path src = new Path(); // src添加一个圆
src.addCircle(0,0,100, Path.Direction.CW);
path.set(src); // 大致相当于 path = src;
canvas.drawPath(path,mPaint);
- offset
方法预览
public void offset (float dx, float dy)
public void offset (float dx, float dy, Path dst)
这个的作用也很简单,就是对path进行一段平移,它和Canvas中的translate作用很像,但Canvas作用于整个画布,而path的offset只作用于当前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