最近工作中需要做一个曲线的动画,记录下学习的过程。
1. 贝塞尔曲线介绍
1.1百度百科介绍如下:
贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。贝塞尔曲线是计算机图形学中相当重要的参数曲线,在一些比较成熟的位图软件中也有贝塞尔曲线工具,如PhotoShop等。在Flash4中还没有完整的曲线工具,而在Flash5里面已经提供出贝塞尔曲线工具。
贝塞尔曲线于1962,由法国工程师皮埃尔·贝塞尔(Pierre Bézier)所广泛发表,他运用贝塞尔曲线来为汽车的主体进行设计。贝塞尔曲线最初由Paul de Casteljau于1959年运用de Casteljau演算法开发,以稳定数值的方法求出贝兹曲线。
1.2 贝塞尔曲线的公式
线性公式
给定点P0、P1,线性贝兹曲线只是一条两点之间的直线。公式如下:
二次方贝塞尔曲线
二次方贝塞尔曲线的路径由给定点P0、P1、P2的函数B(t)追踪,公式如下:
三次方贝塞尔曲线
P0、P1、P2、P3四个点在平面或在三维空间中定义了三次方贝兹曲线。曲线起始于P0走向P1,并从P2的方向来到P3。一般不会经过P1或P2;这两个点只是在那里提供方向资讯。P0和P1之间的间距,决定了曲线在转而趋进P3之前,走向P2方向的“长度有多长”。公式如下:
一般参数公式
阶贝兹曲线可如下推断。给定点P0、P1、…、Pn,其贝兹曲线即:
这个一般就用不到了,三次放贝塞尔曲线一般可以满足多数情况。
2. Android 自定义View中的方法
首先看一下Android自带的绘制曲线的方式:
在自定义View中,经常会用到moveTo, lineTo等一些方法,先设定好path以后再使用canvas进行线条的绘制,那么就来看一下这些方法。
2.1 moveTo
moveTo用来移动画笔,即确定绘制的初始坐标点。
2.2 lineTo
lineTo用于绘制直线
|
|
默认从(0, 0)开始绘制,结束点为(300,300)的一条直线。
首先使用moveTo移动画笔,再使用lineTo
|
|
2.3 quadTo
quadTo用于绘制二阶贝塞尔曲线
|
|
默认起始点为(0, 0),前两个参数为贝塞尔曲线的控制点,后两个参数为结束点。效果如图:
也可以先使用moveTo方法来确定起始点位置
|
|
效果如下:
2.4 cubicTo
cubicTo用于绘制三阶贝塞尔曲线,其实就是比二阶贝塞尔曲线多了一个控制点,默认也是以(0, 0)为起始点。
|
|
其中1,2两个参数是第一个控制点,3,4两个参数是第二个控制点,最后两个参数是结束点。效果如下:
2. Android动画实现
了解了贝塞尔曲线的基础知识后,开始实现用代码实现动画的路径。主要思想就是自定义一个估值器,实现对于每个点的计算,然后根据AnimatorUpdateListener这个监听,实时更新View的位置。
2.1 PathPoint
首先构建一个PathPoint类,用来描述View的位置。代码如下:
|
|
以上就是PathPoint的代码,定义了4中不同类型的type,通过构造函数分别实现起始点、直线、二阶贝塞尔曲线以及三阶贝塞尔曲线的实现,最后通过静态方法直接返回PathPoint的实例。
2.2 AnimatorPath
构建一个AnimatorPath类,内部维护一个集合,用来记录下所有的PathPoint,即动画的移动路径。代码如下:
|
|
2.3 PathEvaluator
自定义的估值器类,用来计算坐标点,根据之前PathPoint中不同的type,返回Path Point,即view的坐标。代码如下:
|
|
以上就是关键部分的代码,接下来看MainActivity的代码
2.4 MainActivity
|
|
2.5 PathView
为了看清楚view的移动轨迹,我们写一个自定义view来显示view的运动轨迹,代码如下:
|
|
至此,代码就写完了。总结一下,主要思想就是通过估值器来不断计算view的位置,然后通过AnimatorUpdateListener来不断的改变view的位置,从而实现view的动画,其实不光是可以实现贝塞尔曲线,在估值器内输入不同的函数,可以让view随着各种函数路径来移动。