原来是用css动画,切换类名的方式来控制页面,但一直都很僵硬,切换类名的时候很突兀
uniapp demo
再mounted里获得指针元素
mounted() {
// 获得指针节点
this.pointerElement = document.querySelector('.pointer');
}
再点击抽奖时调用 this.startDraw()
// 点击抽奖
startDraw() {
if (this.drawTimes <= 0) return;
if (!this.canClick) return;
this.canClick = false;
this.drawTimes--;
// 接口请求返回中奖信息
springFestivalUserDraw().then(res => {
let resData = res.data;
this.resultImagUrl = resData.icon;
this.resGiftType = resData.isWinner;
this.rotatePointer();
// 与之前请求的奖品列表匹配获得指针停止的位置索引
this.GiftArr.forEach((item, index) => {
if (item.id == resData.winnerId) {
this.rouletteActive = true;
setTimeout(() => {
this.dealResult(index);
}, 2000);
}
});
});
},
调用 this.rotatePointer() 开始转动指针,
// 指针旋转
rotatePointer() {
cancelAnimationFrame(this.tickAnimation);
let speed = 1.5; // 单位: 圈/秒 1圈360度 一秒60帧 一帧 6 度
let fps = 60; // 每秒传输帧数(Frames Per Second)
let now;
let then = Date.now();
let interval = 1000 / fps;
let delta;
let self = this; // 传入this
function tick() {
self.tickAnimation = requestAnimationFrame(tick);
now = Date.now();
delta = now - then;
if (delta > interval) {
then = now - (delta % interval);
// 绘制逻辑
self.pointerDeg += (360 / fps) * speed; // 控制速度
if (self.pointerDeg >= 360) {
self.pointerDeg = 0;
}
self.pointerElement.style.transform = `rotate(${self.pointerDeg}deg)`;
}
}
tick();
},
然后请求接口获得结果,设置延时定时器,再两秒钟后
// 处理结果
dealResult(n) {
cancelAnimationFrame(this.tickAnimation);
let speed = 0.5;
let fps = 60;
let now;
let then = Date.now();
let interval = 1000 / fps;
let delta;
// 指针位置随机,同时保留一些安全区间防止UI图片不准确,指针中心没对齐导致的区间超出
let randomDeg = n * 45 + Math.floor(Math.random() * (42 - 3)) + 3; // 随机区间 3~42
let onceFlag = true; // 确保一圈转完
let self = this;
function tick2() {
self.tickAnimation = requestAnimationFrame(tick2);
now = Date.now();
delta = now - then;
if (delta > interval) {
then = now - (delta % interval);
if (self.pointerDeg >= randomDeg && onceFlag) {
if (self.pointerDeg >= 360) {
self.pointerDeg = 0;
onceFlag = false;
}
} else {
// 指针停止条件和处理
if (self.pointerDeg >= randomDeg) {
self.$refs.popdown.open();
self.canClick = true;
self.rouletteActive = false;
cancelAnimationFrame(self.tickAnimation);
return;
}
}
self.pointerDeg += (360 / fps) * speed;
self.pointerElement.style.transform = `rotate(${self.pointerDeg}deg)`;
}
}
tick2();
},
通过调节speed的值控制指针转速