关于网页抽奖,在UI方面主要有方框奖品跳动、翻牌抽奖、或者圆盘转动等大体几种形式。曾经在网上看到一个”点击抽奖”直接切换gif动画图的,这会不会有点欺骗用户之嫌,哈哈。

方框类抽奖可以通过不断改变某定位元素的left和top值。翻牌抽奖则可以在点击后给当前牌加相应的class,class设置对应的背景。当然可能你有更好的思路。

至于圆盘抽奖,在css3之前,转盘类抽奖基本上都是基于flash。而此篇文章主要讲述的是利用css3中transform里rotate属性来转动指针抽奖;

抽奖的本质都是一样,概率性事件。这个我们大可使用随机数来求取某个数值范围内的数,再根据活动需求控制中奖几率。其实在用户点完按钮,抽奖的结果就也立即出来了。当然,这些都不是本篇文章的重点,所谓方框奖品跳动、纸牌翻转、指针转动都只是给用户看的。

本篇的重点,如何让转盘指针根据点击后的随机数最终停到对应的奖区?

我们分析转盘的过程:一个转盘抽奖,用户点击”开始抽奖”,首先指针应该先快速转动,一定时间后,再逐渐减速,最后指针停留在对应的奖区中央。

于是我开始了第一种思路:

在指针转动过程中,随时间变化,逐渐增大animation的duration,最后通过判断旋转的角度来控制指针停止。但结果无效。并不是不能改变duration,而是元素在动画过程中,如果keyframes相同的话,无论duration是否改变,元素只执行最初的duration动画直到停止。

于是第一种思路被判了死刑。

然后我有了第二种思路:

根据随机数值,然后通过设置不同时间的延时定时器(setTimeout),让指针在某个点自动停止(animation-play-state:paused)。
但这个方法需要计算每个延迟的时间点,而且既然是定时停止,必然不能用变速动画,只能线性匀速的(linear)。

<style>
.ele-stop{-webkit-animation-play-state:paused;animation-play-state:paused;}
</style>
...

<script>
timer=setTimeout(funciton(){
  ele.className+=" ele-stop";
},time)
</script>

因此这种思路太过牵强,其一指针停止前并非减速动画,其二计算每个延迟点也显得颇于麻烦,所以第二种思路也被枪毙了。

最终第三种思路:

因为指针最后停留的几个角度都是固定的,所以我们可以为每个奖区设定对应的动画帧和调用它的class,再结合减速动画(ease-out)。最后通过获取的随机数来给指针添加相应的class。此方法虽css代码太多,但却能很好的达到转盘的抽奖效果。

<style>
.ele-move02{-webkit-animation:rorate02 10s 0s ease-out 1 forwards normal; animation:rorate02 10s 0s ease-out 1 forwards normal; }
.ele-move03{-webkit-animation:rorate02 10s 0s ease-out 1 forwards normal; animation:rorate02 10s 0s ease-out 1 forwards normal; }
@keyframes rorate02{ 0% { transform: rotate(0deg);} 100% { transform: rotate(3300deg);} }

@keyframes rorate03{ 0% { transform: rotate(0deg);} 100% { transform: rotate(3360deg); } }
</style>

...

<script>
ele.className +=" ele-move" + iVal;
</script>

另外,需要注意的点:

  1. 页面防止刷新
  2. 抽奖转动过程中按钮不可点

最后,来试试下手气吧: 欢乐大转盘