查看原文
其他

Android 鬼点子 - 如此 Q 弹

2017-08-10 Greenda米 承香墨影

作者简介

本文由 Greenda米 原创并授权发布,未经原作者允许请勿转载。
依然是使用 Kotlin 实现的动画效果,希望大家会喜欢。

Greenda米 的博客地址:

http://www.jianshu.com/p/6e15f1e7edcb

uplabs 上看到一个设计师设计录音备忘录的设计。

动态图很惊艳:

自己尝试实现了一下,大约完成了50%的效果吧。

目前比较不满意的是背景气泡冒出时的粘连效果不是很理性。点击之后变成水滴向上移动的动画没有实现。另外,有的地方计算量比较大,没有优化,极少情况下出现卡顿。如果要真正运用到项目中的话,还需要继续优化。哦,对了没有实现 padding 啊什么的,还有颜色的变化都是直接写在了代码里面。

首先分析一下这个效果的各个部分。

  1. 有两坨重叠的,DuangDuang 的东西,第一层是纯色,第二层的半透明。

  2. 这两坨东西有一种蠕动的效果。

  3. 这两坨东西的大小是变化的。

  4. 时不时有气泡从背景冒出。

  5. 气泡冒出时有粘连效果。

  6. 对了,开始点击的时候有一种果冻的弹性效果。

然后完整代码如下:

下面我逐一介绍一下,每一种效果我是如何实现的。

1、有两坨重叠的,DuangDuang 的东西,第一层是纯色,第二层的半透明。

这个效果我使用的是六边形,然后过渡圆角实现的。DuangDuang 的效果是通过改变六边形每个角到圆心的距离实现蠕动的效果。为了这个效果更逼真,给这个六边形加上旋转的效果。第一层和第二层的效果是一样的,只是半径不同而已。

计算生成六边形顶点的方法是:

mPoints 存放计算后的顶点(6个),mRs 是每个顶点到圆心的半径,mRads 是每条半径的角度。

全局变量 mPoints 存放上层六边形的顶点,bPoints 存放背景六边形顶点。
onDrawa() 方法中调用了。

来更新六边形的顶点的数据。

我使用 sinX ,通过改变X的值,使 sinX 的值在 -1+1 之间呈函数变化。当 X 是匀速变化时, sinX 是非匀速变化的。当角度是随机增加的时候,sinX 的变化就更是随机的。

这里是计算基础半径,整个六边形的放大和缩小的动画是在这里实现的,变化的范围是 -0.15+0.15 之间。

实际的6个顶点的半径是在基础半径上计算的,变化范围是 -range~+range 的范围。

startRads 是当前半径的角度。用 半径 + 角度,计算出顶点的位置。

背景六边形的基础半径略大。

至此,1.2.3的效果就实现了。

2、然后是气泡冒出效果

private fun drawBubble(canvas: Canvas?) {}方法中,是实现气泡效果的。

这里是产生一个气泡的过程。气泡的半径,发射的角度,发射的速度都是随机的。

distance 是当前气泡的距离圆心的距离。x , y 是气泡的圆心坐标。

这里是在计算气泡的半径(随着气泡飞出,半径减小),计算气泡的距离,计算坐标。

移除半径小于等于 0 的气泡。

这里根据计算后的结果画出气泡。后面就是粘连效果的实现。这里使用了贝塞尔曲线。
以一个小球为例:

it.x 和 it.y 是气泡的圆心坐标,width / 2 和 height / 2 是大圆的圆心坐标。大圆的半径 var mR = getRecentR() ,这里是找出 6 个半径中最短的。

AB 的距离是气泡的 distance , ∠ABE 是气泡的角度 it.rad ,代码中计算的th 是 ∠EBC , th2 是 ∠DBE 。角度知道了,半径也知道了,就可以算出4个切点的坐标了。

cx1 , cy2 就是第三个辅助点。点4 ,c1 和 点2,三个点构成一条贝塞尔曲线。点3 ,c2 和 点1,是另一条。

至此,粘连效果完成。

3、点击时有个模仿物理效果的放大缩小动画,果冻的弹性效果

使用的是SpringAnimation,具体代码很简单,没使用过的老哥们可以看看之前的文章《Android 鬼点子-Q弹的计数器》。


推荐阅读


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存