0
点赞
收藏
分享

微信扫一扫

使用requestAnimationFrame,控制转盘指针

驚鴻飛雪 2022-01-16 阅读 82

原来是用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的值控制指针转速

举报

相关推荐

0 条评论