有赞加载进度条
四个正方形的运动可以分解成两个分运动,一个是平移运动,一个是自身的旋转运动。在实现这个动画上有两个思路:
- 一个是通过Android提供的Animation或者Animator操作视图,让一个正方形的视图在translate动画的同时进行rotate动画,只需要设置rotate动画的pivot坐标为视图的中心点就可以了。
- 另一个是直接在canvas上绘制正方形,通过canvas的坐标变换实现动画。
下面主要说第二种方式的原理:
平移:平移canvas,在平行与手机屏幕的平面坐标系中,水平向右方向为X轴,竖直向下方向为Y轴,把原点平移到视图的中心点,只需要在水平和竖直的正方向平移就可以了。
1
canvas.translate(mBounds.width() / 2, mBounds.height() / 2);
旋转:想要完成一个矩形围绕其中心点顺时针旋转一个角度,首先要意识到旋转的过程中,只改变了坐标系的方向并没有改变坐标系的原点位置。换句话说,如果你需要围绕坐标系原点做旋转,那么你只需要旋转操作,如果你需要围绕除了原点以外的另外一个点(比如当前现在正方形的中心点),那么你需要先做平移操作,先把坐标系平移到一个正确的点在做旋转操作。如图所示:
1 | canvas.translate((float) (x + (1 - 1.414f * Math.sin((45 - degree) / 180f * Math.PI)) * halfLength),(float) (y - (1.414f * Math.cos((45 - degree) / 180f * Math.PI) - 1) * halfLength)); |
- 动画插值:可以看到,每个正方形的平移运动周期是从起始点回到起始点,在时间的中点上达到平移的最大值。反应在平面坐标中的情况就是,一条通过(0, 0), (0.5, 1),(1, 0)三点,在(0.5, 1)达到最大值的一元二次方程。可以间接得到这个插值器是:
1 | // 过(0,0),(0.5,1),(1,0)的一元二次方程 |
网易邮箱大师加载进度条
圆弧的动画需要分解成四个分动画:
- 画笔宽度变化:绘制圆弧的画笔宽度在动画
- 圆弧长度变化:绘制圆弧的长度在动画
- 旋转变化:绘制每段圆弧的起点在动画
- 圆弧半径变化:绘制圆弧的半径在动画
1 | public ObjectAnimator[] getAtomAnimator(Atom atom, Rect bound) { |
Canvas图形变换原理
2.1、平移
设图形上点P(x, y),在x轴和y轴方向分别移动Tx和Ty,结果生成新的点P’(x’, y’),则:
用矩阵形式可表示为:
平移变换矩阵为:
2.2、缩放
设图形上的点P(x, y)在x轴和y轴方向分别作Sx倍和Sy倍的缩放,结果生成新的点坐标P’(x’, y’),则:
用矩阵表示为:
比例变换矩阵为:
![ ](/res/android_animation2/suofang 3.png)
2.3、旋转
设点P(x, y)绕原点旋转变换θ角度(假设按逆时针旋转为正角),生成的新的点坐标P’(x’, y’),则:
用矩阵表示为:
旋转变换矩阵为: