抽奖动画
之前写过一篇 按概率抽取 文章,今天来讲讲当你拿到后端返回的中奖信息将如果以动画的形式展现给用户。
1、素材选取
此处用到的图片素材是出自组里视觉大大之手,我只是将图片改了一下。在此感谢视觉大大。
2、页面搭建
根据视觉大大给的视觉稿先搭建一个页面,如下:
<style>
html, body{
width: 100%;
height: 100%;
margin: 0;
background: linear-gradient(#22a29d, #0d6964)
}
.g-wrap{
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.card-box{
display: inline-block;
position:relative;
}
</style>
<div class="g-wrap">
<div class='u-cards J_cards'>
<div class="card-box">
<img src="./static/images/card1.png">
</div>
<div class="card-box">
<img src="./static/images/card2.png">
</div>
<div class="card-box">
<img src="./static/images/card3.png">
</div>
<div class="card-box">
<img src="./static/images/card4.png">
</div>
<div class="card-box">
<img src="./static/images/card5.png">
</div>
</div>
</div>
整体的页面效果如下:
挑剔的视觉大大,看了我的还原说我牌周边的光圈不太明显(png图片带的)。好吧,那我给你加一下。
使用 css 伪元素来添加光圈,光圈使用 box-shadow
来实现。
.card-box.card-normal:after {
position: absolute;
left: 7px;
top: 1px;
display: block;
width: 193px;
height: 263px;
content: '';
transition: all 0.5s ease; // 为后面动画做准备
border-radius: 7px;
box-shadow: 0 3px 10px 5px #3cdad4;
}
添加完光圈后如下图:
效果是比之前明显了。同理添加,蒙层和选中的状态:
.card-box.card-mask:after{
position: absolute;
left: 7px;
top: 1px;
display: block;
width: 193px;
height: 263px;
background-color: rgba(0, 0, 0, 0.3);
content: '';
transition: all 0.5s ease;
border-radius: 7px;
}
.card-box.card-checked:after{
position: absolute;
left: 7px;
top: 1px;
display: block;
width: 193px;
height: 263px;
content: '';
transition: all 0.5s ease;
border-radius: 7px;
box-shadow: 0 0 8px 8px #f9f5e9;
}
说有情况页面效果如下:
至此,页面勉强过了视觉大大的法眼,接下来我们实现最重要的动画部分。
3、动画制作
一般抽奖动画为,开始时速度很快,然后变慢。我们可以是使用定时器 setTimeout
来实现动画,速度调节可以通过增加定时时长来降低速度。每次通过定时给元素添加 class name
来实现动画效果,为了不让每次添加 class name
时看着很生硬,前面给每个伪元素添加了 transition
属性。
-
定初始速时长和每次增加时长
var startTimeout = 100; // 初始定时器时长 var _breakTime = 10, // 每次增加的时长
-
何时停止动画,定义要滚动的轮数
var _circleTimes = 3; // 需要转几轮 var _allNum = 5; // 总共有几个奖品 // id 为后端传回来的用户抽到的奖品,_stepNum 为动画总共执行多少次。 var _stepNum = _allNum * _circleTimes + id; var lotteryNum = 0; // 当前位置(每执行一次,会加1,也可理解当前执行次数) if (lotteryNum >=_stepNum) {停止动画}
-
动画开始时为所有卡片添加蒙层,去掉正常态
card-normal
、选中态card-checked
类名,添加蒙层card-mask
类名。$('.J_cards .card-box') .removeClass('card-normal') .removeClass('card-checked') .addClass('card-mask');
-
为当前元素添加选中态,去掉蒙层
card-mask
类名,添加选中态card-checked
类名$('.card-box' + (lotteryNum % _allNum)) .removeClass('card-mask') .addClass('card-checked');
-
定时启动动画
scrollTimeout = setTimeout(function(){ lottery(id, callback); }, startTimeout+_breakTime); // 定时为卡片改变 类名,来模拟动画 lotteryNum++; // 当前位置加1 , startTimeout+=_breakTime; // 增加定时时长,来降低速度。
-
当执行次数等于总次数时,清除定时器即可停止动画。
if(lotteryNum >=_stepNum){ clearTimeout(scrollTimeout); lotteryNum = 0; startTimeout = 100; if(callback){ callback(); } }
-
代码大致如下:
var lotteryNum = 0; startTimeout = 100, _circleTimes = 3, _breakTime = 10, _allNum = 5; function lottery(id, callback){ var _stepNum = _allNum * _circleTimes + id; // 加蒙层 $('.J_cards .card-box').removeClass('card-normal').removeClass('card-checked').addClass('card-mask'); // 让当前元素为选中态 $('.card-box' + (lotteryNum % _allNum)).removeClass('card-mask').addClass('card-checked'); scrollTimeout = setTimeout(function(){ lottery(id, callback); }, startTimeout+_breakTime); lotteryNum++; startTimeout+=_breakTime; if(lotteryNum >=_stepNum){ clearTimeout(scrollTimeout); lotteryNum = id; startTimeout = 100; if(callback){ callback(); } } }
-
模拟抽奖
添加一个按钮 <div class="gf-ft"> <a href="javascript:void(0)" class="gf-btn J_getGf">立即翻牌 ></a> </div> 添加事件 $('.J_getGf').on('click', getGift); 事件处理 function getGift(){ // 请求抽奖 fetch('getGift',function(_data){ var giftId = _data.data; lottery(giftId, function(){}); }) }