今天看一个网页版大转盘抽奖:

css animation大转盘抽奖 gif css animation大转盘抽奖

这个转盘和一般的转盘实现方式不太一样,一般的转盘都是利用js去控制转盘的旋转的角度,然后利用canvas绘制或者直接操作DOM元素控制,再配上一些缓动动画,我之前写过一篇 小程序抽奖转盘的文章,那里面就是利用js控制角度配合缓动动画去实现的转盘。

这个转盘主要是利用transition,animation去实现,因为css的animation比js控制旋转更加流畅,主要难点就是如何利用transition,animation来达到转盘的目的。

主要思路

我之前写过一篇 小程序抽奖转盘的文章,这里的思路和那里类似,也是把转盘的转动分成三个部分,加速,匀速,减速。与那个不同的是,这里要用css的transition和animation来替代用js控制旋转角度。

加速,匀速:

加速过程我们可以定义一个过渡效果为easeIn的transition,耗时1s,从0度转到360度。

上面的加速过程最后达到了一个最大速度,之前说过在匀速过程我们是要请求数据的,这个过程可能很长也可能很短,因此我们要做一个无限循环的animation,每圈耗时.6s,为什么加速的时候,一圈耗时1s,这里耗时.6s呢?因为匀速的速度相当于最大速度,因此每圈耗时肯定比加速的时候更少。

上面用到的关键css代码如下:

在匀速旋转的时候请求数据,如果数据到了现在就要减速了,因为匀速的时候我们已经添加了一个animation,因此减速的时候我们只能用另一个animation来替换当前的animation,不过这里有问题就是得到当前转盘转了多少度了。

我之前写过一篇 transform之不规则形变的文章,里面说了在transform中旋转θ角度后,得到的结果和θ的关系为:matrix(cos(θ),sin(θ),-sin(θ),cos(θ),0,0);也就是说拿matrix的第一个参数进行Math.acos操作就可以求出真正的度数了:

不过要注意一些特殊情况,在90度和270度的时候,Math.cos理论上得到的结果为0,但是matrix计算的结果是一个很小的数字,不是0,并且用科学计数法表示,需要注意。

matrix的第一个参数用来获取角度,但是这个角度似乎有些“问题”,就是如果角度大于180度,那么就是补角大小了,例如本来是280度,但是第一个参数得到为80度,因此要配合matrix第二个参数来看现在到底是多少度。第二个参数大于0,表示没有超过180度,如果第二个参数小于0,表示超过180度了。

生成动态的animation

刚才在讲减速的时候,说到了用另一个animation来替代匀速的animation,但是实际上减速的animation是不固定的,因为你无法知道什么时候停止,停在哪里。因此对于减速,你需要动态创建animation。

动态创建style,可以用insertRule和deleteRule,这两个可以增加样式规则和删除样式规则,关键代码如下:

知道了如何动态创建style规则,那么减速的时候创建一个简单的easeOut动画就好了,开始旋转角度就是得到数据那个时候的角度,最终角度就是根据结果得到的角度。

最后的代码在加速的时候也用到了动态animation技术,因为多次旋转,不一定每次都是从0度开始旋转,而是从上一次最后的停止的位置开始旋转。

两个animation卡顿优化

本来到上面基本上就结束了,但是这里其实有一个小卡顿的地方,就是从匀速animation到减速animation的时候,因为匀速animation是高速旋转的,然后减速的animation是突然从匀速animation停止的位置开始减速,这样会有一个卡顿的效果。

匀速旋转的时候是.6s旋转了360度,而一般浏览器绘制间隔为16.7ms,因此为了让两个animation过度的时候不至于太“生硬”,我们减速运动开始的角度上加上(167/600)*360=100.2度,虽然这样无法消除卡顿,但是可以缓解一下这种卡顿效果。

DEMO下载

点击下载 [0积分]一共下载0

其他文章

0
我要评论

评论

返回
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

提交
还可以输入500个字