基于javascript的可以自定义设置圆几等份的抽奖示例

news2024/11/26 23:27:52

基于javascript的可以自定义设置圆几等份的抽奖示例

    • 效果示例图
    • 代码示例
    • 使用class

效果示例图

在这里插入图片描述

代码示例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			* {
				padding: 0px;
				margin: 0px;
				box-sizing: border-box;
			}

			.cricle-wrap {
				border: 1px solid red;
				border-radius: 50%;
				width: 400px;
				height: 400px;
				margin: 50px auto;
				position: relative;
			}

			.min-cricle {
				border-radius: 50%;
				width: 10px;
				height: 10px;
				background-color: red;
				position: absolute;
				top: 50%;
				left: 50%;
				transform: translate(-50%, -50%);
			}

			.cricle-line {
				width: 50%;
				height: 1px;
				background-color: red;
				position: absolute;
				top: 50%;
				left: 50%;
				/*
				* 默认情况下,元素的动作参考点为元素盒子的中心 
				* 使用transform-origin改变元素原点位置
				* :center center (正中)它以我的线的中间为圆点,进行旋转
				* :left center (靠左居中) 它以我的线的左边为圆点,进行旋转,即我的线的最左点是固定的,来旋转
				* :right center (靠右居中) 它以我的线的左右边为圆点,进行旋转,即我的线的最右点是固定的,来旋转
				*/
				transform-origin: left center;
			}

			.cricle-angle {
				width: 50%;
				height: 0;
				position: absolute;
				top: 50%;
				left: 50%;
				transform-origin: left center;
			}

			.cricle-angle-children {
				width: 100%;
				height: 100%;
				position: relative;
			}

			.grandson {
				border: 1px solid red;
				width: 50px;
				height: 30px;
				position: absolute;
				top: 50%;
				transform: translateY(-50%) rotate(90deg);
				text-align: center;
				line-height: 30px;
				font-size: 12px;
			}

			.arrow {
				border: 1px solid red;
				border-radius: 50%;
				width: 60px;
				height: 60px;
				position: absolute;
				top: 50%;
				left: 50%;
				transform: translate(-50%, -50%) rotate(0deg);
				line-height: 60px;
				text-align: center;
				z-index: 1;
				background-color: #fff;
				background-image: url("img/arrow.png");
				background-position: center;
				background-repeat: no-repeat;
				background-size: 100% 100%;
			}

			.add-transition {
				transition: all 3s ease-in-out;
			}

			#draw {
				display: block;
				width: 100px;
				height: 40px;
				margin: 12px auto;
			}
		</style>
	</head>
	<body>
		<div class="cricle-wrap" id="cricle">
			<!-- 圆点 -->
			<div class="min-cricle"></div>
			<!-- 箭头 -->
			<div class="arrow"></div>
		</div>
		<button id="draw">抽检</button>

	</body>
	<script type="text/javascript">
		const options = {
			cricleBox: document.querySelector("#cricle"), //获取当前圆
			count: 9, //圆被均等分成n份
			radius: 200, //圆的半径
			prizeDisc: 10, //奖品所在位置0-50,值越小,距离圆心越远
		}
		turntable();

		function turntable() {

			//每一块的弧度
			const angle = 360 / options.count;
			for (let i = 0; i < options.count; i++) {
				let rotateAngle = i * angle;
				const scaleMark = createScaleMark(rotateAngle)
				options.cricleBox.appendChild(scaleMark);
				const prize = createPrize(rotateAngle, angle, i);
				options.cricleBox.appendChild(prize);
			}
			/**
			 * 创建刻度线
			 * **/
			function createScaleMark(rotateAngle) {
				const divs = document.createElement("div");
				divs.classList.add("cricle-line");
				divs.style.transform = `rotate(${rotateAngle-90}deg)`
				return divs
			}
			/**
			 * 创建奖品块
			 * **/
			function createPrize(rotateAngle, skewAngle, i) {
				const prizes = document.createElement("div");
				prizes.classList.add("cricle-angle");

				const childrenDIvs = document.createElement("div");
				childrenDIvs.classList.add("cricle-angle-children");

				const grandson = document.createElement("div");
				grandson.classList.add("grandson");
				grandson.style.right = `${options.prizeDisc}%`
				grandson.innerText = (i + 1) + '等奖';

				childrenDIvs.appendChild(grandson)

				prizes.appendChild(childrenDIvs)
				prizes.style.transform = `rotate(${rotateAngle-90+(skewAngle/2)}deg)`
				return prizes
			}

		}
		//中奖号码
		let winningNumber = 0;
		//箭头旋转的角度
		let rotate = 0;
		//点击抽奖按钮
		const arrow = document.querySelector(".arrow");
		document.querySelector("#draw").addEventListener("click", () => {
			winningNumber = Math.floor(Math.random() * options.count) + 1;
			rotateTurntable(winningNumber);
		})

		function rotateTurntable(n) {
			//每一块的弧度
			const angle = 360 / options.count;
			const skewAngle = angle / 2;
			rotate += n * angle - skewAngle + 360 * 10 + (360 - rotate % 360);
			arrow.classList.add("add-transition");
			arrow.style.transform = `translate(-50%, -50%) rotate(${rotate}deg)`;
		}
		//监听动画是否结束
		arrow.addEventListener("transitionend", () => {
			console.log("[动画结束]")
			console.log("[中奖号码]", winningNumber)
			arrow.classList.remove("add-transition");
			arrow.style.transform = `translate(-50%, -50%) rotate(${rotate}deg)`;
		})
	</script>
</html>

使用class

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			* {
				padding: 0px;
				margin: 0px;
				box-sizing: border-box;
			}

			.cricle-wrap {
				border: 1px solid red;
				border-radius: 50%;
				width: 400px;
				height: 400px;
				margin: 50px auto;
				position: relative;
			}

			.min-cricle {
				border-radius: 50%;
				width: 10px;
				height: 10px;
				background-color: red;
				position: absolute;
				top: 50%;
				left: 50%;
				transform: translate(-50%, -50%);
			}

			.cricle-line {
				width: 50%;
				height: 1px;
				background-color: red;
				position: absolute;
				top: 50%;
				left: 50%;
				/*
				* 默认情况下,元素的动作参考点为元素盒子的中心 
				* 使用transform-origin改变元素原点位置
				* :center center (正中)它以我的线的中间为圆点,进行旋转
				* :left center (靠左居中) 它以我的线的左边为圆点,进行旋转,即我的线的最左点是固定的,来旋转
				* :right center (靠右居中) 它以我的线的左右边为圆点,进行旋转,即我的线的最右点是固定的,来旋转
				*/
				transform-origin: left center;
			}

			.cricle-angle {
				width: 50%;
				height: 0;
				position: absolute;
				top: 50%;
				left: 50%;
				transform-origin: left center;
			}

			.cricle-angle-children {
				width: 100%;
				height: 100%;
				position: relative;
			}

			.grandson {
				border: 1px solid red;
				width: 50px;
				height: 30px;
				position: absolute;
				top: 50%;
				transform: translateY(-50%) rotate(90deg);
				text-align: center;
				line-height: 30px;
				font-size: 12px;
			}

			.arrow {
				border: 1px solid red;
				border-radius: 50%;
				width: 60px;
				height: 60px;
				position: absolute;
				top: 50%;
				left: 50%;
				transform: translate(-50%, -50%) rotate(0deg);
				line-height: 60px;
				text-align: center;
				z-index: 1;
				background-color: #fff;
				background-image: url("img/arrow.png");
				background-position: center;
				background-repeat: no-repeat;
				background-size: 100% 100%;
			}

			.add-transition {
				transition: all 3s ease-in-out;
			}

			#draw {
				display: block;
				width: 100px;
				height: 40px;
				margin: 12px auto;
			}
		</style>
	</head>
	<body>
		<div class="cricle-wrap" id="cricle">
			<!-- 圆点 -->
			<div class="min-cricle"></div>
			<!-- 箭头 -->
			<div class="arrow"></div>
		</div>
		<button id="draw">抽检</button>
	</body>
	<script type="text/javascript">
		class Turntable {
			//中奖号码
			winningNumber = 0;
			//箭头旋转的角度
			rotate = 0;
			static OPTIONS = {
				cricleBox: document.querySelector("#cricle"), //获取当前圆
				arrow: document.querySelector(".arrow"), //箭头的按钮
				prizeBtn: document.querySelector("#draw"), //抽奖按钮
				count: 5, //圆被均等分成n份
				radius: 200, //圆的半径
				prizeDisc: 10, //奖品所在位置0-50,值越小,距离圆心越远
				success: null
			}
			constructor(options) {
				this.options = Object.assign({}, Turntable.OPTIONS, options);
				this.init();
			}

			init() {
				//每一块的弧度
				const angle = 360 / this.options.count;
				for (let i = 0; i < this.options.count; i++) {
					let rotateAngle = i * angle;
					const scaleMark = this.createScaleMark(rotateAngle)
					this.options.cricleBox.appendChild(scaleMark);
					const prize = this.createPrize(rotateAngle, angle, i);
					this.options.cricleBox.appendChild(prize);
				}
				this.clickEvent();
			}
			/**
			 * 创建刻度线
			 * rotateAngle :旋转的角度
			 * **/
			createScaleMark(rotateAngle) {
				const divs = document.createElement("div");
				divs.classList.add("cricle-line");
				divs.style.transform = `rotate(${rotateAngle-90}deg)`
				return divs
			}
			/**
			 * 创建奖品块
			 * rotateAngle :旋转的角度
			 * skewAngle:偏移量的角度
			 * **/
			createPrize(rotateAngle, skewAngle, i) {
				const prizes = document.createElement("div");
				prizes.classList.add("cricle-angle");

				const childrenDIvs = document.createElement("div");
				childrenDIvs.classList.add("cricle-angle-children");

				const grandson = document.createElement("div");
				grandson.classList.add("grandson");
				grandson.style.right = `${this.options.prizeDisc}%`
				grandson.innerText = (i + 1) + '等奖';

				childrenDIvs.appendChild(grandson)

				prizes.appendChild(childrenDIvs)
				prizes.style.transform = `rotate(${rotateAngle-90+(skewAngle/2)}deg)`
				return prizes
			}
			/**
			 * 点击抽奖,事件处理
			 * **/
			clickEvent() {
				this.options.prizeBtn.addEventListener("click", () => {
					this.winningNumber = Math.floor(Math.random() * this.options.count) + 1;
					this.rotateTurntable(this.winningNumber);
				})

				//监听动画是否结束
				this.options.arrow.addEventListener("transitionend", () => {
					console.log("[动画结束]")
					this.options.arrow.classList.remove("add-transition");
					this.options.arrow.style.transform = `translate(-50%, -50%) rotate(${this.rotate}deg)`;

					this.options.success && this.options.success(this.winningNumber)
				})
			}
			/**
			 * 转动箭头到指定奖品
			 * **/
			rotateTurntable(n) {
				//每一块的弧度
				const angle = 360 / this.options.count;
				const skewAngle = angle / 2;
				this.rotate += n * angle - skewAngle + 360 * 10 + (360 - this.rotate % 360);
				this.options.arrow.classList.add("add-transition");
				this.options.arrow.style.transform = `translate(-50%, -50%) rotate(${this.rotate}deg)`;
			}
		}
		new Turntable({
			cricleBox: document.querySelector("#cricle"), //获取当前圆
			arrow: document.querySelector(".arrow"), //箭头的按钮
			prizeBtn: document.querySelector("#draw"), //抽奖按钮
			count: 9, //圆被均等分成n份
			radius: 200, //圆的半径
			prizeDisc: 10, //奖品所在位置0-50,值越小,距离圆心越远
			success: (response) => {
				console.log(`${response}等奖`)
			}
		});
	</script>
</html>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

声音合成——Foley Sound——DECASE项目——多模态智能感知与应用——论文复现(4)

文章目录 下载对应的代码attributeerror: adam object has no attribute get_updatesNameError: name _calculate_reconstruction_loss is not defined 下载对应的代码 论文下载链接安装tensorflow环境&#xff0c;这里需要一些前奏&#xff0c;比如说如何安装cuda&#xff0c…

【04golang中各种运算符优先级的讲解代码和注释】

在Golang中&#xff0c;不同的运算符具有不同的优先级&#xff0c;这会影响表达式的计算顺序。了解运算符的优先级是编写正确和可读性高的代码的关键。本文将对Golang中常见运算符的优先级进行讲解&#xff0c;并提供一些示例代码和注释。 以下是Golang中常见运算符的优先级从…

谷粒商城篇章4 ---- P102-P172【分布式高级篇】

目录 1. Elasticsearch 1.1 基本概念 1.1.1 Index&#xff08;索引&#xff09; 1.1.2 Type&#xff08;类型&#xff09; 1.1.3 Document&#xff08;文档&#xff09; 1.1.4 倒排索引机制 1.2 Docker安装 ES 1.2.1 下载镜像文件 1.2.2 运行 Elasticsearch 1.3 初步…

面向个人的免费组态软件:摩尔信使MThings

产品官网 现代工业自动化各行各业中均广泛应用工控上位机软件&#xff0c;但同时也面临着一系列挑战和复杂性。 多样化设备组网&#xff1a;工控系统包含不同厂家的各类硬件和设备&#xff0c;如传感器、执行器、PLC等。工控上位机软件需要与不同类型的设备进行集成和通信&am…

疑似俄罗斯黑客用二手宝马广告诱骗西方驻乌外交官

Bleeping Computer 网站披露&#xff0c;疑似具有俄罗斯背景的黑客组织 APT29&#xff08;又名 Nobelium&#xff0c;Cloaked Ursa&#xff09;正在使用二手宝马汽车广告等非常规性”诱饵“&#xff0c;引诱西方驻乌克兰外交官点击带有恶意软件的链接。 过去两年&#xff0c;AP…

1.9 用整合Swagger2文档api

步骤1&#xff1a;在顶级工程的pom.xml下添加依赖 <!-- swagger2 配置 --> <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.4.0</version> </dependency> <de…

【html】生成聊天记录网页能导出图片

例如有一段有趣的对话&#xff0c;需要通过聊天记录形式展现出来分享&#xff0c;想到通过网页设计是可以实现的&#xff0c;那么如何生成出来呢&#xff0c;在这里给具体讲一讲吧。 网页布局 创建一个网页文件index.html&#xff0c;代码如下 <!DOCTYPE html> <ht…

Mysql之窗口函数学习

聚合是分组后,聚合到一行 而窗口函数,既可以聚合到一行,也可以不聚合 1.序号函数 分组排序并添加序号 row_number rank dense_rank 1.row_number() 按照部门名称进行分组,然后按照薪资进行排序,但是,我们要注意 1.这里分组,但是并没有进行聚合 2.序号排序,是根据num的组进行…

驱动开发-day10

驱动代码&#xff1a; #include <linux/cdev.h> #include <linux/device.h> #include <linux/fs.h> #include <linux/gpio.h> #include <linux/init.h> #include <linux/interrupt.h> #include <linux/mod_devicetable.h> #include …

Oracle语句优化 (汇总)

大部分写sql语句都是为了实现而实现&#xff0c;如果最后在投入使用的过程中没有很难接受的性能&#xff0c;基本不怎么去考虑其性能。最近刚好有点时间&#xff0c;对优化方面进修进修&#xff0c;以备不时之需。 选择最有效率的表名顺序 Oracle的解析器按照从右到左的顺序处…

【PHP面试题29】什么是PHP-FPM?它与PHP和Nginx有什么关系

文章目录 一、前言二、什么是PHP-FPM&#xff1f;三、PHP-FPM的生命周期3.1 启动阶段3.2 初始化阶段3.3 请求处理阶段3.4 关闭阶段 四、PHP-FPM与PHP的关系五、PHP-FPM与Nginx的通信方式六、总结 一、前言 本文已收录于PHP全栈系列专栏&#xff1a;PHP面试专区。 计划将全覆盖P…

JavaScript 判断 null 、undefined、NaN的可靠方法、验证以及注意事项

索引 判断方法判断undefined判断null判断NaN 注意事项undefined和null和比较NaN和自己比较 有些时候需要判断类型是否为null、undefined或者NaN&#xff0c;常用的方法有以下&#xff1a; 判断方法 判断undefined 使用typeof typeof xxx undedfined注意&#xff1a;typeof…

Python+”多技术融合在蒸散发与植被总初级生产力估算

熟悉蒸散发ET及其组分&#xff08;植被蒸腾Ec、土壤蒸发Es、冠层截留Ei&#xff09;、植被总初级生产力GPP的概念和碳水耦合的基本原理&#xff1b;掌握利用Python与ArcGIS工具进行课程相关的操作&#xff1b;熟练掌握国际上流行的Penman-Monteith模型&#xff0c;并能够应用该…

低代码自动化解析:企业所需要了解的一切

根据2020年以来与低代码技术相关的积极趋势&#xff0c;Gartner预测到2023年低代码开发技术市场将增长20%。此外&#xff0c;他们还预计&#xff0c;到2026年&#xff0c;非正式IT部门的开发人员将占低代码开发工具用户群至少80%的比例&#xff0c;而这一比例在2021年为60%。基…

基本概念【变量和数据类型和运算符、二进制和十进制、十进制转二进制 、二进制转十进制 】(一)-全面详解(学习总结---从入门到深化)

目录 变量和数据类型和运算符 二进制和十进制的转化 十进制转二进制 二进制转十进制 注释 标识符和关键字 关键字/保留字 变量(variable) 变量的分类和作用域 常量(Constant) 基本数据类型(primitive data type) 整型 浮点型(Floating Point Number) 字符型 …

网工内推 | 坐标长沙,CKA、红帽、华为认证均可

01 上海海典软件 招聘岗位&#xff1a;运维工程师 职责描述&#xff1a; 1、负责和支撑业务系统日常运维工作&#xff1b; 2、负责公司机房网络设备、服务器的日常管理和维护&#xff1b; 3、负责公司电脑软件、硬件的安装及维护&#xff1b; 4、领导交办的其它事务。 任职要求…

行业内对低代码开发是什么看法?低代码/aPaaS未来将走向何方?

有人觉得低代码只是个概念&#xff0c;一无是处&#xff1b; 有人将低代码吹上了天&#xff0c;将其送上神坛&#xff1b; 我们先来看看低代码是什么。 低代码&#xff08;Low-Code&#xff09;顾名思义&#xff0c;是以少量的代码完成项目的开发。广义的低代码也包括零代码&a…

Shell第三章——循环语句与函数(2)

while循环&#xff1a;满足条件才会执行循环&#xff0c;不满足就结束&#xff0c;用于不知道循环次数&#xff0c;需要主动结束循环或者达到条件循环的场景 语法结构&#xff1a; while [ 条件判断 ] do 命令序列 done 例&#xff1a; 先在循环外把变量起好 let i 防止…

Python入门基础知识总结(赶紧收藏)

一&#xff1a;简介&#xff1a; Python 是一种解释型、面向对象的语言 Python的语法和动态类型&#xff0c;以及解释性语言的本质&#xff0c;使它成为多数平台上写脚本和快速开发应用的编程语言 二&#xff1a;Python基础语法 2.1.字面量 字面量&#xff1a;在代码中&am…