我们开发活动中抽奖相关功能时,可以直接使用第三方插件;在碰到产品要求的样式与插件大相径庭或者存在兼容性问题时,也可以尝试自己手写对应的功能代码。
lucky-canvas插件
链接:100px.net/
基本上lucky-canvas插件可以满足大部分的抽奖活动需求,但是之前在开发小程序时出现了一些兼容性问题,所以决定自己封装一下功能代码。
vue项目封装对应hook
开发转盘功能,关键点是控制转速。让功能更加流畅。
import { ref } from 'vue';
export default function useLucky() {
// 用不到的变量,没有定义响应式数据
let prize = ''; // 速度开始变化(变缓)的位置
let prizeId = ''; // 中奖位置
const cycle = 50; // 基本转动次数
let speed = 30; // 转动速度
let times = 0; // 转动次数
let timer = null; // 定时器ID
let click = false; // 是否正在抽奖
let activeIndex = ref(-1);
// 点击开始
const start = ()=> {
// 如果正在抽奖则直接return
if (click) {
return false;
}
click = true;
speed = 100;
// 中奖的位置,应该从服务端取到
prizeId = Math.floor(Math.random() * 8);
console.log('中奖位置:', prizeId)
roll();
};
// 转动
const roll = () => {
times += 1;
// 如果activeIndex是最后一个,则赋值0
activeIndex.value = activeIndex.value >= 7 ? 0 : activeIndex.value + 1
if (times > cycle + 10 && activeIndex.value === prizeId) {
// 最后滚动到中奖位置,停止滚动
clearTimeout(timer);
prize = -1;
times = 0;
click = false;
} else {
if (times < cycle) {
// 一开始速度增加(speed越小速度越快)
speed -= 20;
} else if (times === cycle) {
// 确定一个速度变化的位置,下一次滚动到此位置,速度明显变缓
prize = Math.random() * 8 | 0;
} else {
// 滚动次数大于基本滚动次数并且到达上面确定的位置时,速度明显变缓
if (times > cycle + 10 && ((prize === 0 && this.data.activeIndex === 7) || prize === this.data.activeIndex + 1)) {
speed += 90;
} else {
// 滚动次数大于基本滚动次数,速度逐渐变缓
speed += 30;
}
}
// 控制速度在30
if (speed < 30) {
speed = 30;
}
timer = setTimeout(this.roll, speed);
}
};
return {
activeIndex,
start,
roll,
};
}