在上一篇Canvas之图片文字中我们了解了如何使用Canvas中绘制图片文字,结合前几篇文章,Canvas的基本操作已经差不多完结了,然而Canvas不仅仅具有这些基本的操作,还可以更加炫酷,本次会了解到path(路径)这个Canvas中的神器,有了这个神器,就能创造出更多炫(zhuang)酷(B)的东东了。
一.Path常用方法表
为了兼容性(偷懒) 本表格中去除了部分API21(即安卓版本5.0)以上才添加的方法。
作用 | 相关方法 | 备注 |
---|---|---|
移动起点 | 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详解
请关闭硬件加速,以免引起不必要的问题!
请关闭硬件加速,以免引起不必要的问题!
请关闭硬件加速,以免引起不必要的问题!
在AndroidMenifest文件中application节点下添上 android:hardwareAccelerated=”false”以关闭整个应用的硬件加速。
更多请参考这里:Android的硬件加速及可能导致的问题
Path作用
本次特地开了一篇详细讲解Path,为什么要单独摘出来呢,这是因为Path在2D绘图中是一个很重要的东西。
在前面我们讲解的所有绘制都是简单图形(如 矩形 圆 圆弧等),而对于那些复杂一点的图形则没法去绘制(如绘制一个心形 正多边形 五角星等),而使用Path不仅能够绘制简单图形,也可以绘制这些比较复杂的图形。另外,根据路径绘制文本和剪裁画布都会用到Path。
关于Path的作用先简单地说这么多,具体的我们接下来慢慢研究。
Path含义
官方介绍:
The Path class encapsulates compound (multiple contour) geometric paths consisting of straight line segments, quadratic curves, and cubic curves. It can be drawn with canvas.drawPath(path, paint), either filled or stroked (based on the paint’s Style), or it can be used for clipping or to draw text on a path.
嗯,没错依旧是拿来装逼的,如果你看不懂的话,不用担心,其实并没有什么卵用。
通俗解释(sloop个人版):
Path是封装了由直线和曲线(二次,三次贝塞尔曲线)构成的几何路径。你能用Canvas中的drawPath来把这条路径画出来(同样支持Paint的不同绘制模式),也可以用于剪裁画布和根据路径绘制文字。我们有时会用Path来描述一个图像的轮廓,所以也会称为轮廓线(轮廓线仅是Path的一种使用方法,两者并不等价)
另外路径有开放和封闭的区别。
图像 | 名称 | 备注 |
---|---|---|
封闭路径 | 首尾相接形成了一个封闭区域 | |
开放路径 | 没有首位相接形成封闭区域 |
这个是我随便画的,仅为展示一下区别,请无视我灵魂画师一般的绘图水准。
与Path相关的还有一些比较神奇的概念,不过暂且不说,等接下来需要用到的时候再详细说明。
Path使用方法详解
前面扯了一大堆概念性的东西。接下来就开始实战了,请诸位看官准备好瓜子、花生、爆米花,坐下来慢慢观看。
第1组: moveTo、 setLastPoint、 lineTo 和 close
由于Path的有些知识点无法单独来讲,所以本次采取了一次讲一组方法。
按照惯例,先创建画笔:
1 2 3 4 |
Paint mPaint = new Paint(); // 创建画笔 mPaint.setColor(Color.BLACK); // 画笔颜色 - 黑色 mPaint.setStyle(Paint.Style.STROKE); // 填充模式 - 描边 mPaint.setStrokeWidth(10); // 边框宽度 - 10 |
lineTo:
方法预览:
1 |
public void lineTo (float x, float y) |
首先讲解的的LineTo,为啥先讲解这个呢?
是因为moveTo、 setLastPoint、 close都无法直接看到效果,借助有具现化效果的lineTo才能让这些方法现出原形。
lineTo很简单,只有一个方法,作用也很容易理解,line嘛,顾名思义就是一条线。
俗话(数学书上)说,两点确定一条直线,但是看参数明显只给了一个点的坐标吧(这不按常理出牌啊)。
再仔细一看,这个lineTo除了line外还有一个to呢,to翻译过来就是“至”,到某个地方的意思,lineTo难道是指从某个点到参数坐标点之间连一条线?
没错,你猜对了,但是这某个点又是哪里呢?
前面我们提到过Path可以用来描述一个图像的轮廓,图像的轮廓通常都是用一条线构成的,所以这里的某个点就是上次操作结束的点,如果没有进行过操作则默认点为坐标原点。
那么我们就来试一下:
1 2 3 4 5 6 7 8 |
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 |
在示例中我们调用了两次lineTo,第一次由于之前没有过操作,所以默认点就是坐标原点O,结果就是坐标原点O到A(200,200)之间连直线(用蓝色圈1标注)。
第二次lineTo的时候,由于上次的结束位置是A(200,200),所以就是A(200,200)到B(200,0)之间的连线(用蓝色圈2标注)。
moveTo 和 setLastPoint:
方法预览:
1 2 3 4 5 |
// moveTo public void moveTo (float x, float y) // setLastPoint public void setLastPoint (float dx, float dy) |
这两个方法虽然在作用上有相似之处,但实际上却是完全不同的两个东东,具体参照下表:
方法名 | 简介 | 是否影响之前的操作 | 是否影响之后操作 |
---|---|---|---|
moveTo | 移动下一次操作的起点位置 | 否 | 是 |
setLastPoint | 设置之前操作的最后一个点位置 | 是 | 是 |
废话不多说,直接上代码:
1 2 3 4 5 6 7 8 9 10 11 |
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 |
؍仅仅具有这些基本的操作,还可以更加炫酷,本次会了解到path(路径)这个Canvas中的神器,有了这个神器,就能创造出更多炫(zhuang)酷(B)的东东了。
一.Path常用方法表
为了兼容性(偷懒) 本表格中去除了部分API21(即安卓版本5.0)以上才添加的方法。
作用 | 相关方法 | 备注 |
---|---|---|
移动起点 | 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详解
请关闭硬件加速,以免引起不必要的问题!
请关闭硬件加速,以免引起不必要的问题!
请关闭硬件加速,以免引起不必要的问题!
在AndroidMenifest文件中application节点下添上 android:hardwareAccelerated=”false”以关闭整个应用的硬件加速。
更多请参考这里:Android的硬件加速及可能导致的问题
Path作用
本次特地开了一篇详细讲解Path,为什么要单独摘出来呢,这是因为Path在2D绘图中是一个很重要的东西。
在前面我们讲解的所有绘制都是简单图形(如 矩形 圆 圆弧等),而对于那些复杂一点的图形则没法去绘制(如绘制一个心形 正多边形 五角星等),而使用Path不仅能够绘制简单图形,也可以绘制这些比较复杂的图形。另外,根据路径绘制文本和剪裁画布都会用到Path。
关于Path的作用先简单地说这么多,具体的我们接下来慢慢研究。
Path含义
官方介绍:
The Path class encapsulates compound (multiple contour) geometric paths consisting of straight line segments, quadratic curves, and cubic curves. It can be drawn with canvas.drawPath(path, paint), either filled or stroked (based on the paint’s Style), or it can be used for clipping or to draw text on a path.
嗯,没错依旧是拿来装逼的,如果你看不懂的话,不用担心,其实并没有什么卵用。
通俗解释(sloop个人版):
Path是封装了由直线和曲线(二次,三次贝塞尔曲线)构成的几何路径。你能用Canvas中的drawPath来把这条路径画出来(同样支持Paint的不同绘制模式),也可以用于剪裁画布和根据路径绘制文字。我们有时会用Path来描述一个图像的轮廓,所以也会称为轮廓线(轮廓线仅是Path的一种使用方法,两者并不等价)
另外路径有开放和封闭的区别。
图像 | 名称 | 备注 |
---|---|---|
封闭路径 | 首尾相接形成了一个封闭区域 | |
开放路径 | 没有首位相接形成封闭区域 |
这个是我随便画的,仅为展示一下区别,请无视我灵魂画师一般的绘图水准。
与Path相关的还有一些比较神奇的概念,不过暂且不说,等接下来需要用到的时候再详细说明。
Path使用方法详解
前面扯了一大堆概念性的东西。接下来就开始实战了,请诸位看官准备好瓜子、花生、爆米花,坐下来慢慢观看。
第1组: moveTo、 setLastPoint、 lineTo 和 close
由于Path的有些知识点无法单独来讲,所以本次采取了一次讲一组方法。
按照惯例,先创建画笔:
1 2 3 4 |
Paint mPaint = new Paint(); // 创建画笔 mPaint.setColor(Color.BLACK); // 画笔颜色 - 黑色 mPaint.setStyle(Paint.Style.STROKE); // 填充模式 - 描边 mPaint.setStrokeWidth(10); // 边框宽度 - 10 |
lineTo:
方法预览:
1 |
public void lineTo (float x, float y) |
首先讲解的的LineTo,为啥先讲解这个呢?
是因为moveTo、 setLastPoint、 close都无法直接看到效果,借助有具现化效果的lineTo才能让这些方法现出原形。
lineTo很简单,只有一个方法,作用也很容易理解,line嘛,顾名思义就是一条线。
俗话(数学书上)说,两点确定一条直线,但是看参数明显只给了一个点的坐标吧(这不按常理出牌啊)。
再仔细一看,这个lineTo除了line外还有一个to呢,to翻译过来就是“至”,到某个地方的意思,lineTo难道是指从某个点到参数坐标点之间连一条线?
没错,你猜对了,但是这某个点又是哪里呢?
前面我们提到过Path可以用来描述一个图像的轮廓,图像的轮廓通常都是用一条线构成的,所以这里的某个点就是上次操作结束的点,如果没有进行过操作则默认点为坐标原点。
那么我们就来试一下:
1 2 3 4 5 6 7 8 |
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 |
在示例中我们调用了两次lineTo,第一次由于之前没有过操作,所以默认点就是坐标原点O,结果就是坐标原点O到A(200,200)之间连直线(用蓝色圈1标注)。
第二次lineTo的时候,由于上次的结束位置是A(200,200),所以就是A(200,200)到B(200,0)之间的连线(用蓝色圈2标注)。
moveTo 和 setLastPoint:
方法预览:
1 2 3 4 5 |
// moveTo public void moveTo (float x, float y) // setLastPoint public void setLastPoint (float dx, float dy) |
这两个方法虽然在作用上有相似之处,但实际上却是完全不同的两个东东,具体参照下表:
方法名 | 简介 | 是否影响之前的操作 | 是否影响之后操作 |
---|---|---|---|
moveTo | 移动下一次操作的起点位置 | 否 | 是 |
setLastPoint | 设置之前操作的最后一个点位置 | 是 | 是 |
废话不多说,直接上代码:
1 2 3 4 5 6 7 8 9 10 11 |
canvas.translate(mWidth / 2, mHeight / 2); // 移动坐标系到屏幕中心 Path path = new Path(); // 创建Path path.lineTo(200, 200); // lineTo path.moveTo(200,100); // moveTo |