“打工搬砖记”中吃什么的轮盘功能实现(二)

文章目录

    • 打工搬砖记
    • 转盘主要的逻辑实现
    • 转盘的素材
    • 小结

打工搬砖记

先来一个吃什么轮盘的预览图,这轮盘文案加字呈圆形铺出来,开始后旋转到指定的选项处停下来。
已上线小程序“打工人搬砖记”,可以扫码进行预览观看。
请添加图片描述
请添加图片描述

转盘主要的逻辑实现

1、通过绑定style绑定值为“prizeBoxStyle”,设置每个选项的颜色以及后续转盘转动需要操作这个值。
2、通过绑定style绑定值为“prizeStyle”,然后通过“rotateAngle()”方法计算出总共有几个选项,然后算出每个选项需要旋转的角度。
3、通过“totalRunAngle()”计算出转盘最后需要转动角度,所以说游戏在开始的一瞬间就程序就已经知道,抽中的是那一个。
4、为了使转盘有声音就使用“uni.createInnerAudioContext()”来创建音乐,这个地方需要注意的是,如果想要后续“.stop()”停下音乐,在创建的时候一定不要设置为自动播放,就是说“autoplay = false”。

具体代码如下:

<template>
	<view>
		<image src="../../static/lunch/lunchBcg.jpg" class="bcgImg" mode=""></image>
		<view class="container">
			<view class="container-title"></view>

			<view class="prize-box-relative">
				<view class="prize-box">
					<view class="prize-list" ref="prizeWrap" :style="prizeBoxStyle">
						<div class="prize-item" v-for="(item, index) in prizeList" :style="[prizeStyle(index)]">
							<text>{{ item }}</text>
						</div>
					</view>
				</view>
			</view>
			<image @click="openGame()" src="../../static/lunch/turntable.png" class="turntableImg" mode=""></image>
		</view>

		<!-- 弹框 :抽中要吃的-->
		<view v-show="tipShow" class="tip_box">
			<view class="tip_content">
				<image src="../../static/lunch/tip.png" class="tip_img" mode=""></image>
				<view class="tip_txt">
					{{prizeList[prizeId] }}
				</view>
				<view class="tip_btn" @click="tipShow = false"></view>
			</view>
		</view>
	</view>
</template>

<script>
	import {
		turnList
	} from 'config/api.js';
	export default {
		data() {
			return {
				// colorList: ['#f69602', '#f8ca41', '#ffe7c9','#afe2ec'],
				colorList: ['#fe9539', '#fadf94', '#5fcbd1', '#ffffff'],
				prizeList: ["豆浆", "胡辣汤", "韭菜鸡蛋韭菜鸡蛋", "奖品4", "奖品5", "奖品6", "奖品4", "奖品5", "奖品6"],
				isRunning: false, // 是否正在抽奖
				baseRunAngle: 360 * 5, // 总共转动角度 至少5圈
				prizeId: 0, // 中奖id
				rotatePrize: 40,
				tipShow: false,
				prizeBoxStyle: '',
				audioMusic: '',
			}
		},
		onLoad() {
			this.getPrizeList()
			uni.$on('updateTurn', (data) => {
				this.getPrizeList()
			})
		},
		methods: {
			getPrizeList() {
				turnList({
					data: {
						eatType: this.activeMenu
					},
					custom: {
						auth: true,
						toast: false,
						catch: true
					}
				}).then((res) => {
					let arr = []
					res.map(value => {
						arr.push(value.name)
					})
					this.prizeList = arr
					this.rotatePrize = 360 / arr.length
					this.prizeBoxStyle = this.bgColor()
					this.initGame()
				})
			},
			// 初始化转盘游戏
			initGame() {
				this.rotateAngle()
			},
			// 开始游戏
			openGame() {
				this.startGame()
			},
			// 开始游戏
			startGame() {
				if (!this.isRunning) {
					this.isRunning = true
					this.prizeId = this.getRandomNum()
					this.startRun()
				}
			},
			// 游戏运行
			startRun() {
				this.prizeBoxStyle = `${this.bgColor()} transform: rotate(${this.totalRunAngle()}deg);transition: all 4s ease;`

				this.audioMusic = uni.createInnerAudioContext();
				this.audioMusic.autoplay = false;
				this.audioMusic.startTime = 2;
				this.audioMusic.sessionCategory = 'ambient';
				this.audioMusic.src = '/static/lunch/music01.mp3';
				this.audioMusic.play();
				setTimeout(() => {
					this.audioMusic.stop()
					this.audioMusic.destroy()
					this.audioMusic = null
				}, 3700)


				this.playAudio()
				setTimeout(() => {
					this.tipShow = true
					this.isRunning = false
					this.prizeBoxStyle = `${this.bgColor()} transform: rotate(${this.totalRunAngle() - this.baseRunAngle}deg);`
				}, 4000)
			},
			getRandomNum() {
				const num = Math.floor(Math.random() * this.prizeList.length)
				return num
			},
			// 平均每个奖品角度
			rotateAngle() {
				this.rotatePrize = 360 / this.prizeList.length
			},
			// 奖品布局
			prizeStyle(i) {
				let _degree = this.rotatePrize
				let style = {}

				style.width = 2 * 130 * Math.sin(_degree / 2 * Math.PI / 180) + 'px'
				style.height = '130px'
				style.transform = `rotate(${_degree * i + _degree / 2}deg)`
				style.transformOrigin = '50% 100%'

				return style
			},
			// 计算绘制转盘背景
			bgColor() {
				let colorVal = ''
				for (let i = 0; i < this.prizeList.length; i++) {
					colorVal += `${this.colorList[i % 4]} ${this.rotatePrize * i}deg ${this.rotatePrize * (i + 1)}deg,`
				}
				return ` background: conic-gradient(${colorVal.slice(0, -1)});transform: rotate(-${this.rotatePrize/2}deg); `
			},

			// 要执行总转角度数
			totalRunAngle() {
				return this.baseRunAngle + 360 - this.prizeId * this.rotatePrize - this.rotatePrize / 2
			},
			// 转盘停下来时的声音
			playAudio() {
				setTimeout(() => {
					const innerAudioContext = uni.createInnerAudioContext();
					innerAudioContext.autoplay = true;
					innerAudioContext.sessionCategory = 'ambient';
					innerAudioContext.src = '/static/lunch/music.mp3';
					innerAudioContext.onPlay();
				}, 3800)
			}

		}
	}
</script>

<style lang="scss">
	.bcgImg {
		position: fixed;
		width: 750rpx;
		height: 100vh;
	}

	.container {
		position: relative;
		width: 660rpx;
		height: 660rpx;
		margin: 0 auto;
	}

	.container-title {
		font-size: 56rpx;
		font-weight: bold;
		color: #FFFFFF;
		text-align: center;
		line-height: 160rpx;
		height: 160rpx;
		letter-spacing: 20px;
	}

	.turntableImg {
		width: 100%;
		height: 100%;
		position: absolute;
		top: 160rpx;
	}



	.prize-box-relative {
		width: 100%;
		height: 100%;
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.prize-box {
		width: 300px;
		height: 300px;
		position: relative;
	}

	.prize-list {
		width: 100%;
		height: 100%;
		border-radius: 50%;
		overflow: hidden;
	}

	.prize-item {
		/*border: 2px solid red;*/
		position: absolute;
		left: 0;
		right: 0;
		top: 20px;
		margin: auto;
		text-align: center;
	}

	.prize-item text {
		display: flex;
		align-items: center;
		writing-mode: vertical-rl;
		color: #333333;
		font-size: 26rpx;
		font-weight: bold;
		text-align: center;
		line-height: 20px;
		width: 100%;
	}

	.tip_box {
		z-index: 10;
		position: fixed;
		top: 0;
		width: 100%;
		height: 100vh;
		background: rgba(0, 0, 0, 0.5);
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.tip_content {
		position: relative;
	}

	.tip_img {
		width: 640rpx;
		height: 480rpx;
	}

	.tip_txt {
		position: absolute;
		top: 160rpx;
		width: 600rpx;
		text-align: center;
		font-weight: bold;
		font-size: 38rpx;
	}

	.tip_btn {
		position: absolute;
		bottom: 60rpx;
		left: 210rpx;
		width: 200rpx;
		height: 100rpx;
	}


	.food_menu_list {
		position: fixed;
		bottom: 100rpx;
		width: 710rpx;
		padding: 50rpx 20rpx;
		display: flex;
		flex-wrap: wrap;
		font-size: 26rpx;
		color: #999999;
		font-weight: bold;

		.menu_box {
			margin: 0 10rpx;
			width: 174rpx;
			background: rgba(244, 244, 244, 0.6);
			box-shadow: 0 0 10rpx #FFFFFF;
			display: flex;
			align-items: center;
			padding: 20rpx;
			border-radius: 10rpx;
			margin-bottom: 30rpx;

			.menu_img {
				width: 40rpx;
				height: 40rpx;
				margin-right: 10rpx;
			}
		}

		.menu_active {
			color: #53851b;
			background: #f4f4f4;
			box-shadow: 0 0 10rpx #f4f4f4;
		}


		.menu_btn {
			font-size: 36rpx;
			color: #ffffff;
			line-height: 80rpx;
			text-align: center;
			width: 100%;
			border-radius: 10rpx;
			border: 2rpx #FFFFFF solid;
		}
	}
</style>

转盘的素材

我发现穿上后好像就成为了jpg格式了,注意转盘哪个一定要是png格式的,不然会把转盘的内容给覆盖住,音乐和背景图的话就自己找找吧!
请添加图片描述
请添加图片描述

小结

总的来说实现过程不难,难的是思路以及行动力。加油打工人!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/626235.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Unity Shader入门精要 第7章】基础纹理补充内容:MipMap原理

1.纹理采样 我们对纹理采样进行显示的过程&#xff0c;可以理解为将屏幕上的一个像素&#xff08;下文用像素表示&#xff09;映射到纹理上的一个像素&#xff08;下文用纹素表示&#xff09;&#xff0c;然后用纹理上的这个像素的颜色进行显示。 理想情况下&#xff0c;屏幕…

AcqKnowledge 5.0使用方法

Biopac 数据导入 matlab 处理方法 第一步&#xff1a;在 AcqKnowledge 软件中&#xff0c;将数据通道的 mark 信息导入到 Graph&#xff0c;并将数据存储为 acq3 的格式 第二步&#xff1a;MATLAB中读取acq3文件脚本 clc clear %%%所有被试这一层路径 pathsub fullfile(file…

【JavaEE】HTTP 协议

文章目录 一、HTTP 协议1、HTTP 是什么2、理解 "应用层协议"3、理解 HTTP 协议的工作过程4、HTTP 协议格式5、HTTP 请求 (Request)5.1 认识 URL 6、 二、HTTPS1、HTTPS是什么2、"加密" 是什么3、HTTPS 的工作过程3.1 对称加密3.2 非对称加密3.3 证书3.4 完…

iOS——消息传递和消息转发

消息传递&#xff08;Message Passing&#xff09;&#xff1a; 在 iOS 中&#xff0c;消息传递机制是基于 Objective-C 语言的动态性质的一种编程方式。这种机制主要涉及到两个概念&#xff1a;发送者&#xff08;即消息的发送对象&#xff09;和接收者&#xff08;即消息的接…

RS422一主多从MAX3490

RS422一主多从MAX3490 最近项目用到了RS422一主多从&#xff0c;一个主机4个从机。芯片用的MAX3490&#xff0c;几经折腾&#xff0c;最终只能从一拖4改为一拖2。 主机发送端&#xff0c;从机4个接收端都是正常的&#xff0c;没有问题。波形非常完美&#xff0c;没有太大变形 …

matlab使用2-基础绘图

matlab使用2-基础绘图 文章目录 matlab使用2-基础绘图1. 二维平面绘图2. 三维立体绘图3. 图形窗口的分割 1. 二维平面绘图 % 创建一些二维数据 x 0:0.01:10; % x轴的数据点&#xff0c;从0到10&#xff0c;间隔为0.01 y sin(x); % y轴的数据点&#xff0c;是x的正弦…

版本控制:软件开发的基石(一文读懂版本控制)

未经允许&#xff0c;禁止转载&#xff01; 在现代软件开发中&#xff0c;版本控制是不可或缺的工具。它帮助开发者跟踪和管理代码的变化&#xff0c;协作完成项目&#xff0c;并确保代码的完整性和安全性。本文将基于Git官网的视频“什么是版本控制”来深入探讨版本控制的基本…

pyqt QComboBox下拉列表框控件

pyqt QComboBox下拉列表框控件 QComboBox效果代码 QComboBox QComboBox 是 PyQt&#xff08;中的一个控件&#xff0c;它允许用户从下拉列表中选择一个选项。这个控件在需要用户从预定义选项中进行选择时非常有用。 效果 代码 import sys from PyQt5.QtWidgets import QAppl…

转发_重定向

1.Servlet/JSP单独使用的弊端 当我们用Servlet或者JSP单独处理请求的时候 Servlet&#xff1a;拼接大量的html字符串 造成可读性差、难以维护JSP&#xff1a;使得html和Java代码互相交织 也造成了可读性差、难以维护的后果 最合适的做法就是两者结合使用 2.ServletJSP处理请…

宿舍管理系统代码详解(主页面)

本篇将对管理系统的主页面的代码进行详细的介绍。 目录 一、主页面前端代码 1.样式展示 2.代码详解 &#xff08;1&#xff09;template部分 &#xff08;2&#xff09;script部分 &#xff08;3&#xff09;路由导航守卫 &#xff08;4&#xff09;在vue中引用vue 一、主页…

数据库的三大范式!!!初学者必看

数据库的三大范式&#xff01;&#xff01;&#xff01;初学者必看 三大范式是 Mysql数据库设计表结构所遵循的规范和指导方法目的是为了减少冗余&#xff0c;建立结构合理的数据库&#xff0c;从而提高数据存储和使用的性能。 三大范式之间是具有依赖关系的&#xff0c;比如第…

java 并发线程应用

java 并发线程相关 线程状态 新建(NEW): 创建后尚未启动。可运行(RUNABLE): 正在 Java 虚拟机中运行。但是在操作系统层面,它可能处于运行状态,也可能等待资源调度(例如处理器资源),资源调度完成就进入运行状态。所以该状态的可运行是指可以被运行,具体有没有运行要看底层…

对关系型数据库管理系统的介绍

1.数据库的相关介绍 关系型数据库管理系统&#xff1a;&#xff08;英文简称&#xff1a;RDBMS&#xff09; 为我们提供了一种存储数据的特定格式&#xff0c;所谓的数据格式就是表&#xff0c; 在数据库中一张表就称为是一种关系. 在关系型数据库中表由两部分组成&#xf…

【NodeMCU实时天气时钟温湿度项目 7】和风天气API返回JSON数据信息的解压缩实现——ArduinoUZlib功能库

今天是第七专题&#xff0c;主要内容是&#xff1a;导入ArduinoUZlib功能库&#xff0c;借助该库把从【和风天气】官网返回的经过Gzip压缩的JSON数据&#xff0c;进行解压缩和t解析&#xff0c;在串口监视器上输出解析后的JSON信息。 如您需要了解其它专题的内容&#xff0c;请…

物联网应用开发--STM32与新大陆云平台通信(云平台控制开发板上蜂鸣器、LED)

实现目标 1、掌握云平台执行器的创建 2、熟悉STM32 与ESP8266模块之间的通信 3、具体实现目标&#xff1a;&#xff08;1&#xff09;创建5个执行器&#xff1a;蜂鸣器&#xff0c;LED1&#xff0c;LED2&#xff0c;ED3&#xff0c;LED4;&#xff08;2&#xff09;执行器能对…

CodeGeeX 智能编程助手 6 项功能升级,在Visual Studio插件市场霸榜2周!

CodeGeeX是支持适配Visual Studio 2019的唯一一款国产智能辅助编程工具&#xff0c;已经在Visual Studio趋势上霸榜2周&#xff01; CodeGeeX v1.0.4版本上线Visual Studio插件市场&#xff0c;带来了多项新功能和性能优化&#xff0c;提升编程体验。 新功能亮点速览&#xf…

用面向对象的思想编写实时嵌入式C程序

实时嵌入式系统的软件一般由C语言编写&#xff0c;程序结构基本上都是这样的&#xff1a; // 主程序 int main(void) {init(); // 初始化while(1){tick(); // 业务逻辑}return 0; }// 计时器 static unsigned int g_timer_tick_cnt 0; // 时钟中断回调 void isr_time…

Docker 基础认识

文章目录 概念铺垫&#xff08;1&#xff09;概念铺垫&#xff08;2&#xff09;概念铺垫 &#xff08;3&#xff09;概念铺垫&#xff08;4&#xff09;Docker 定义Docker 特点Docker 架构 概念铺垫&#xff08;1&#xff09; 虚拟化相关概念 物理机&#xff1a;实际的服务器…

【前端】CSS基础(2)

文章目录 前言1、CSS选择器1.1选择器的功能1.2 选择器的种类1.2.1 基础选择器1.2.1.1 标签选择器1.2.1.2 类选择器1.2.1.3 id选择器1.2.1.4 通配符选择器1.2.1.5 伪类选择器 1.2.2 复合选择器1.2.2.1 后代选择器1.2.2.2 子选择器1.2.2.3 并集选择器 前言 这篇博客仅仅是对CSS的…

vue3自定义指令​(通过指令钩子获得dom和钩子参数)

实现文本框自动获得焦点 Index.vue: <script setup> import { ref, onMounted } from vue import ./index.cssconst vFocus {mounted: (el, binding) > {el.focus()console.log(binding)} }onMounted(() > {}) </script><template><div class&qu…