1. 实现效果
2. 实现过程
话不多说,直接上代码
/**index.wxml */
<view class="title">旋转大转盘</view>
<view class="rote-box fcc">
<view class="box fcc">
<image class="bg" src="/static/bg.png" animation="{{animationRotate}}"/>
<image class="btn {{isTurnOver2?'':'grayscale'}}" src="/static/btn.png" bindtap="onRotateClick" />
</view>
</view>
Page({
/**
* 页面的初始数据
*/
data: {
isTurnOver2: true, //抽奖状态 是否旋转完(旋转大转盘)
animationRotate: null,
// 转的总圈数,最后一圈可能不满
num_total: 20,
},
onRotateClick() {
if (this.data.isTurnOver2) {
this.setData({
isTurnOver2: false,
});
//正常,奖品结果提前从后端接口拿回来,这里模拟获取随机
// 随机奖品效果
const rand = (m, n) => {
return Math.ceil(Math.random() * (n - m + 1) + m - 1);
};
let prizeId = rand(1, 6);
this.onRotate(prizeId);
} else {
showTextToast('请勿重复点击');
}
},
onRotate(prizeId) {
console.log('中奖id', prizeId);
let _duration = 10000;
let animationRotate = wx.createAnimation({
duration: _duration,
timingFunction: 'ease', //动画以低速开始,然后加快,在结束前变慢
});
//解决二次点击不旋转问题
animationRotate.rotate(0).step({
duration: 1,
});
let num_total = this.data.num_total;
/*
* angle 旋转的角度
* 这转盘有6个奖项,所以一个奖项的度数为:360除以6等于60、
* 要转完一圈 → 60 * 6
* 为了让动画看起来舒服我设置了20圈 → 60 * 6 * 20
* 又因为需要连贯抽取非第一次,所以二次抽奖时会在原来的圈数上自加,
* 也就成了60 * 6 * num_total,num_total每转完一次都会叠加上自身
* 又因为转盘是顺时针旋转的,默认指定奖品1
* 所以需要减去 → 60 * (prize_id - 1) 方可在最后一圈转到对应的位置
* 可以根据自己的设计稿奖品的个数进行调整
* */
let angle = 60 * 6 * num_total - 60 * (prizeId - 1);
animationRotate.rotate(angle).step();
this.setData({
animationRotate: animationRotate.export(),
});
setTimeout(() => {
this.setData({
isTurnOver2: true,
num_total: num_total + num_total,
});
}, _duration);
},
});
//index.less
.rote-box {
padding-bottom: 20rpx;
.box {
width: 600rpx;
height: 600rpx;
position: relative;
.bg {
width: 100%;
height: 100%;
position: absolute;
top: 0rpx;
left: 0rpx;
}
.btn {
position: absolute;
top: 160rpx;
width: 200rpx;
height: 249rpx;
}
}
}
.grayscale {
filter: grayscale(70%);
}
3.资源获取
九宫格抽奖请移步这边