本文结合一个数字滚动摇奖效果,谈谈微信小程序中动画实现的一般方式。
实例上要显示四位数字,根据后台返回金额,比如15.69元,处理成数字从00:00快速翻动到15:69的效果。
思考:数字翻动的动画样式,0-9似乎每个数字都要写,好在不多具有可实现性。为了过渡平滑,四个数组多塞几组0-9数字,比如0-9+0-9+0-9+1+2..+5,这是数字5的数组。由于是下翻动效果,注意是0-9+0-9+0-9+1+2..+5的倒序,但这样一开始就把金额显示出来了,下面的都隐藏了,我们在最上边再补一个0。运行动画时先瞬间切换到最下边的0,也是0%动画时的位置,之后自下而上运动到那个摇奖数字就行了。实现以下的程序:
1.四个数字的数组容器,做好排布,设置超出隐藏。
2.每组数字为纵向排列,把得到的获奖金额,分解成四个数字,调用对应的数字动画。
3.这里四组数字动画需要设置不同的延迟启动。
4.class名称的统一性,与数字关联比较好,方便调用。
实现步骤:
拿到后台数据分解数字:
var cash = (res.data.data) ? Number(res.data.data) : 0;
cash = cash == NaN ? 0 : cash;
var cashStr = "000"+Math.round(cash * 100) ;
cashStr = cashStr.substr(-4, 4);
var cash4, cash1, cash2, cash3;
cash1 = parseInt(cashStr.charAt(0));
cash2 = parseInt(cashStr.charAt(1));
cash3 = parseInt(cashStr.charAt(2));
cash4 = parseInt(cashStr.charAt(3));
准备四个数组放数字:
var draw1, draw2, draw3, draw4;
draw1 = [];
for (var i = 0; i < 5; i++) {
for (var j = 0; j <= 9; j++) {
draw1.unshift(j);
}
}
draw2 = [...draw1];
draw3 = [...draw1];
draw4 = [...draw1];
拿到摇奖的数字后,继续塞:
for (let i = 0; i <= cash1; i++) {
draw1.unshift(i);
};
for (let j = 0; j <= cash2; j++) {
draw2.unshift(j);
};
for (let m = 0; m <= cash3; m++) {
draw3.unshift(m);
};
for (let n = 0; n <= cash4; n++) {
draw4.unshift(n);
};
draw1.unshift(0); //最上边塞0
draw2.unshift(0);
draw3.unshift(0);
draw4.unshift(0);
四组数字哪个先动,让它有一定随机性:
var d1,d2,d3,d4
var dArr=[1,2,3,4]
for(var i=0;i<4;i++){
for(var j=3;j>i;j--){
if(Math.round(Math.random())==0){
var temp=dArr[i]
dArr[i]=dArr[j]
dArr[j]=temp
}
}
}
d1=dArr[0]
d2=dArr[1]
d3=dArr[2]
d4=dArr[3]
不同延迟的css:
.draw-num text{
position: absolute;
left: 0;
width: 100%;
height: auto;
top: 0;
animation-duration:3.5s;
animation-timing-function:linear;
animation-fill-mode: forwards;
}
.draw-num-1{
animation-delay:0s;
}
.draw-num-2{
animation-delay:0.1s;
}
.draw-num-3{
animation-delay:0.3s;
}
.draw-num-4{
animation-delay:0.4s;
}
动画css:这里只贴一个数字0的:
.translatey-0{ //数字0动画
top:-4968rpx;
animation-name: translatey0;
}
@keyframes translatey0{
0%{
transform: translateY(-4968rpx);
}
10%{
transform: translateY(-4860rpx);
}
75%{
transform: translateY(-324rpx);
}
100%{
transform: translateY(-108rpx);
}
}
调用动画:
vm.setData({
drawNum1: draw1.join(''), //页面上载入数字数组
drawNum2: draw2.join(''),
drawNum3: draw3.join(''),
drawNum4: draw4.join(''),
translatey_1: 'translatey-' + cash1 +' draw-num-' + d1, //动画样式
translatey_2: 'translatey-' + cash2 +' draw-num-' + d2,
translatey_3: 'translatey-' + cash3 +' draw-num-' + d3,
translatey_4: 'translatey-' + cash4 +' draw-num-' + d4,
shareCash:cash
});
var chanceNum = _this.data.chanceNum;
var chanceTotal = _this.data.chanceTotal;
var drawState = 2;
if (chanceNum == chanceTotal) drawState = 3;
setTimeout(() => {
vm.setData({
sd: 1, // 4秒后显示一个中奖金额的遮罩层
drawState: drawState
})
}, 4000)