用 HTML、CSS 和 JavaScript 实现抽奖转盘效果

顺序抽奖

前言

这段代码实现了一个简单的抽奖转盘效果。页面上有一个九宫格布局的抽奖区域,周围八个格子分别放置了不同的奖品名称,中间是一个 “开始抽奖” 的按钮。点击按钮后,抽奖区域的格子会快速滚动,颜色不断变化,模拟抽奖过程。经过一定圈数的滚动后,会随机停止在某一个格子上,弹出提示框显示中奖奖品。

效果展示

 

代码详情

HTML部分

<div class="box">
    <div class="div1">电脑</div>
    <div class="div2">手机</div>
    <div class="div3">音响</div>
    <div class="div4">冰箱</div>
    <div class="div5">空调</div>
    <div class="div6">衣柜</div>
    <div class="div7">沙发</div>
    <div class="div8">地毯</div>
    <button class="giftButton">开始抽奖</button>
</div>

CSS部分

* {
    margin: 0;
    padding: 0;
}

.box {
    background-color: lightgray;
    width: 340px;
    height: 340px;
    position: relative;
}

.box div {
    background-color: cadetblue;
    width: 100px;
    height: 100px;
    text-align: center;
    line-height: 100px;
}

.div1 {
    position: absolute;
    top: 10px;
    left: 10px;
}

/* 其他 .divX 类的样式省略,它们类似地设置了不同的 top 和 left 值来定位 */

.giftButton {
    position: absolute;
    width: 100px;
    height: 100px;
    top: 120px;
    left: 120px;
    border-radius: 10px;
    background-color: navajowhite;
}

JS部分

初始化声明
  • boxCenter:通过 document.getElementsByClassName('box')[0] 获取到类名为 box 的元素,这个元素是整个抽奖区域的容器。
  • allGift:使用 boxCenter.getElementsByTagName('div') 获取 boxCenter 内的所有 div 元素,这些 div 元素代表了各个奖品格子。
  • giftButtons:通过 document.getElementsByClassName('giftButton')[0] 获取 “开始抽奖” 按钮元素,后续会为它添加点击事件。
  • k:作为奖品的下标,用于标记当前高亮显示的奖品格子。
  • time:旋转时间间隔,初始值为 500 毫秒,后续会根据抽奖过程动态调整。
  • count:记录抽奖过程中转过的圈数,初始值为 0。
  • inter:用于存储定时器,方便后续清除和重新设置定时器。
  • random:存储随机生成的中奖下标,初始值为 0。
//获取box
let boxCenter = document.getElementsByClassName('box')[0];
//获取boxcenter里的所有的div元素
let allGift = boxCenter.getElementsByTagName('div');
//获取到抽奖按钮,后续帮点击事件
let giftButtons = document.getElementsByClassName('giftButton')[0];
//充当奖品的下标
let k = 0;
// 旋转时间间隔
let time = 500;
//圈数,就是转动的圈数
let count = 0;
//存定时器的
let inter;
//随机的数(中奖的下标)
let random = 0;
点击按钮事件
  • 为 giftButtons 按钮添加 onclick 事件处理函数。
  • 当点击按钮时,将当前 k 对应的奖品格子背景颜色设置为黄色,表示高亮显示。
  • 使用 Math.random() 生成一个 0 到 1 之间的随机数,乘以 allGift.length 得到一个随机范围在 0 到奖品数量之间的数,再使用 Math.floor() 向下取整,得到一个随机的中奖下标 random
  • 使用 setInterval() 函数设置一个定时器,每隔 time 毫秒执行一次 autoScroll 函数,开始抽奖滚动过程。
//上点击事件
giftButtons.onclick = function() {
    //奖品的下标k变颜色 
    allGift[k].style.backgroundColor = 'yellow';
    // 先生成一个随机数,然后*box里的所有div的数量,再向下取整
    random = Math.floor(Math.random() * allGift.length);
    //设定时器
    inter = setInterval(autoScroll, time);
}
滚动函数
  1. 奖品格子切换
    • 如果 k 小于 allGift.length - 1,说明还没有转到最后一个奖品格子,将 k 加 1,把上一个奖品格子的背景颜色变回 cadetblue,当前 k 对应的格子背景颜色设置为黄色。
    • 如果 k 等于或大于 allGift.length - 1,说明转到了最后一个奖品格子,将 k 重置为 0,代表开始下一圈,同时圈数 count 加 1,把上一圈最后一个奖品格子的背景颜色变回 cadetblue,当前 k 对应的格子背景颜色设置为黄色。
  2. 滚动速度调整
    • 当圈数 count 小于 3 时,每次将 time 减去 100 毫秒,让滚动速度变快,但最快不超过 100 毫秒。
    • 当圈数 count 大于等于 3 时,每次将 time 加上 100 毫秒,让滚动速度变慢,但最慢不超过 300 毫秒。
  3. 中奖判断与处理
    • 先使用 clearInterval(inter) 清除当前的定时器。
    • 如果随机生成的中奖下标 random 等于当前的 k 且圈数 count 大于 4,说明抽奖停止,弹出提示框显示中奖的奖品名称。
    • 否则,重新设置定时器,继续滚动,直到满足中奖条件。
function autoScroll() {
    //k小于长度 代表转到最后一个元素了   
    if (k < allGift.length - 1) {
        k++;
        //上一个奖品变回原色
        allGift[k - 1].style.backgroundColor = 'cadetblue';
        //当前索引下标变红
        allGift[k].style.backgroundColor = 'yellow';
        //k比长度长的话代表该转第二圈了
    } else {
        //重新让k=0下标, 下一次循环
        k = 0;
        //该转下一圈的话,圈数+1
        count++;
        //上一圈的最后一个奖品变回原色
        allGift[allGift.length - 1].style.backgroundColor = 'cadetblue';
        //当前索引下标变红
        allGift[k].style.backgroundColor = 'yellow';
    }
    if (count < 3) {
        //圈数小于5 ,每次都-100 让他变快变快
        time -= 100;
        //限制条件:最快滚动就是0.2秒
        if (time < 100) {
            time = 100;
        }
        //最外面的否则。就是圈数大于
    } else {
        //让他变慢
        time += 100;
        //限制条件:最慢就是2秒滚动一次
        if (time > 300) {
            time = 300;
        }
    }

    //判断中奖的是啥 和 确认转的圈数
    clearInterval(inter);
    if (random == k && count > 4) {
        //提示用户
        alert('🎉恭喜你,中奖的是🎉:' + '👉👉' + allGift[k].innerHTML + '👈👈');
    } else {
        //清除定时器
        //在设置一个定时器9
        inter = setInterval(autoScroll, time);
    }
}

随机抽奖

随机抽奖即为滚动的格子为随机的。

代码总览

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8">
		<title>抽奖页面</title>
		<style>
			/* 全局样式重置 */
			* {
				margin: 0;
				padding: 0;
			}

			/* 抽奖容器样式 */
			.box {
				background-color: lightgray;
				width: 340px;
				height: 340px;
				position: relative;
			}

			/* 奖品方块样式 */
			.box div {
				background-color: cadetblue;
				width: 100px;
				height: 100px;
				text-align: center;
				line-height: 100px;
			}

			/* 各个奖品方块定位样式 */
			.div1 {
				position: absolute;
				top: 10px;
				left: 10px;
			}

			.div2 {
				position: absolute;
				top: 10px;
				left: 120px;
			}

			.div3 {
				position: absolute;
				top: 10px;
				left: 230px;
			}

			.div4 {
				position: absolute;
				top: 120px;
				left: 230px;
			}

			.div5 {
				position: absolute;
				top: 230px;
				left: 230px;
			}

			.div6 {
				position: absolute;
				top: 230px;
				left: 120px;
			}

			.div7 {
				position: absolute;
				top: 230px;
				left: 10px;
			}

			.div8 {
				position: absolute;
				top: 120px;
				left: 10px;
			}

			/* 抽奖按钮样式 */
			.giftButton {
				position: absolute;
				width: 100px;
				height: 100px;
				top: 120px;
				left: 120px;
				border-radius: 10px;
				background-color: navajowhite;
			}

			#bigAlert {
				display: flex;
				position: fixed;
				/* z-index: 1; */
				/* left: 0; */
				top: 0;
				width: 100%;
				height: 100%;
				/* overflow: auto; */
				background-color: rgba(0, 0, 0, 0.4);
				align-content: center;
			}

			.alertContent {
				display: flex;
				justify-content: space-around;
				align-items: center;
				background-color: white;
				border-radius: 10px;
				/* margin: 15%; */
				/* padding: 20px; */
				/* border: 1px solid #888; */
				width: 300px;
				height: 100px;
				/* margin-left: auto;
				margin-right: auto; */
				margin: auto;

			}

			.buttonAlert {
				padding: 10px;
				color: black;
				background-color: gold;
				border: none;
				border-radius: 10px;
				cursor: pointer;

			}

			.buttonAlert:hover {
				background-color: #609EA0;
				color: blue;
				transition: 0.3s ease;
			}

			.mengban {
				background-color: rgba(0, 0, 0, 0.5);
				width: 100%;
				height: 100%;
				/* z-index: 2; */
				position: absolute;
				top: 0px;
				left: 0px;
				border-radius: 8px;
			}
		</style>
	</head>

	<body>
		<div class="box">
			<div class="div1">电脑</div>
			<div class="div2">手机</div>
			<div class="div3">音响</div>
			<div class="div4">冰箱</div>
			<div class="div5">空调</div>
			<div class="div6">衣柜</div>
			<div class="div7">沙发</div>
			<div class="div8">地毯</div>
			<button class="giftButton">
				<span class="mengban" style="display: none;" readonly></span>
				开始抽奖
			</button>
		</div>

		<div id="bigAlert" style="display: none;">
			<div class="alertContent">
				<span id="alertMessage"></span>
				<button class="buttonAlert" onclick="closeAlert()">确定</button>
			</div>
		</div>

		<script>
			// 显示弹窗的
			function showAlert(a) {
				//先获取到大的div
				let alertDiv = document.getElementById('bigAlert');
				//在获取span标签
				let messageSpan = document.getElementById('alertMessage');
				// 传参(中奖提示)
				// messageSpan.innerHTML = `<span style="color: red;">${a}</span>`;;
				//中奖提示(模板字符串)
				let startIndex = a.indexOf("中奖的是") + "中奖的是".length;
				let highlightedPart = a.slice(startIndex);
				messageSpan.innerHTML = `
				        <span>
				            ${a.slice(0, startIndex)}
				            <span style="color: red; font-weight: bold;">${highlightedPart}</span>
				        </span>
				    `;
				//上面隐藏了 现在在显示出来
				alertDiv.style.display = 'block';
			}
			showAlert('aaaaaaaaaaaa');
			//关闭弹窗的
			function closeAlert() {
				//获取到大div
				let alertDiv = document.getElementById('bigAlert');
				//隐藏
				alertDiv.style.display = 'none';
			}

			// 获取box
			let boxCenter = document.getElementsByClassName('box')[0];
			// 获取boxcenter里的所有的div元素
			let allGift = boxCenter.getElementsByTagName('div');
			// 获取到抽奖按钮,后续绑定点击事件
			let giftButtons = document.getElementsByClassName('giftButton')[0];

			// 充当所有的奖品的下标
			let giftIndex = 0;
			// 旋转时间间隔
			let time = 200;
			// 存定时器的
			let inter;
			// 本次抽奖的随机圈数
			let countTotal;

			let mengban = document.getElementsByClassName('mengban')[0];

			//闪动次数
			let bulingBuling = 0;
			// 点击事件
			giftButtons.onclick = function() {
				bulingBuling = 0;
				// 在数100-200格之间 。随机生成格数
				countTotal = Math.floor(Math.random() * 10 + 1) + 10;
				// 设定时器
				inter = setInterval(autoScroll, time);
				//蒙版显示。标签上隐藏了
				mengban.style.display = 'block';
				//清除点击事件 ,为了抽奖的时候不能再点抽奖按钮
				giftButtons.onclick = null;
			}
			//这个函数会在定时器内被反复调用
			function autoScroll() {
				//每次被调用这个函数 闪动次数+1
				bulingBuling++;
				// 随机选择下一个要变色显示的奖品索引(不按照顺序)
				let nextIndex;
				nextIndex = Math.floor(Math.random() * allGift.length);
				// 循环数组中的每一个元素 让他们颜色统一
				for (let i = 0; i < allGift.length; i++) {
					allGift[i].style.backgroundColor = 'cadetblue';
				}
				// 把 全部div 中挑出来的随机索引下标变黄
				allGift[nextIndex].style.backgroundColor = 'yellow';
				// 判断闪的格,是否等于上面要求的格数
				if (bulingBuling == countTotal) {
					mengban.style.display = 'none';
					//满足就清除定时器
					clearInterval(inter);
					// 提示用户
					showAlert('🎉恭喜你,中奖的是🎉:' + ' ' + allGift[nextIndex].innerHTML);
					//========================重新绑定点击事件============================================
					giftButtons.onclick = function() {
						bulingBuling = 0;
						// 在数100-200格之间 。随机生成格数
						countTotal = Math.floor(Math.random() * 10 + 1) + 10;
						// 设定时器
						inter = setInterval(autoScroll, time);
						mengban.style.display = 'block';
						giftButtons.onclick = null;
					}

				}
			}
		</script>
	</body>

</html>

功能实现差异

第一段代码

  • 滚动规则:奖品格子按照顺序依次滚动,从第一个格子开始,逐个向后滚动,当到达最后一个格子后,重新从第一个格子开始滚动,形成循环滚动的效果。
  • 速度控制:在抽奖开始的前几圈(圈数小于 3),滚动速度逐渐加快,最快达到每 100 毫秒滚动一次;之后滚动速度逐渐变慢,最慢为每 300 毫秒滚动一次。
  • 中奖判断:当随机生成的中奖下标与当前滚动到的格子下标相等,并且已经滚动超过 4 圈时,抽奖停止,弹出中奖提示框。
  • 提示方式:使用浏览器默认的 alert 函数弹出提示框,显示中奖信息

第二段代码

  • 滚动规则:奖品格子随机闪烁,每次闪烁时,随机选择一个奖品格子改变颜色,不按照顺序进行滚动。
  • 速度控制:滚动速度固定为每 200 毫秒闪烁一次,没有动态调整速度的过程。
  • 中奖判断:预先随机生成一个 11 - 20 之间的闪烁次数(countTotal),当闪烁次数达到这个随机值时,抽奖停止,弹出中奖提示框。
  • 提示方式:自定义了一个模态框,通过修改模态框的 display 属性来显示和隐藏,并且对中奖信息中的奖品名称进行了样式处理(红色加粗)。

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

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

相关文章

【Linux系统】计算机世界的基石:冯诺依曼架构与操作系统设计

文章目录 一.冯诺依曼体系结构1.1 为什么体系结构中要存在内存&#xff1f;1.2 冯诺依曼瓶颈 二.操作系统2.1 设计目的2.2 系统调用与库函数 一.冯诺依曼体系结构 冯诺依曼体系结构&#xff08;Von Neumann Architecture&#xff09;是计算机的基本设计理念之一&#xff0c;由…

说说Redis的内存淘汰策略?

大家好&#xff0c;我是锋哥。今天分享关于【说说Redis的内存淘汰策略?】面试题。希望对大家有帮助&#xff1b; 说说Redis的内存淘汰策略? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Redis 提供了多种内存淘汰策略&#xff0c;用于在内存达到限制时决定如何…

【python】python基于机器学习与数据分析的手机特性关联与分类预测(源码+数据集)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;专__注&#x1f448;&#xff1a;专注主流机器人、人工智能等相关领域的开发、测试技术。 python基于机器学习与数据分析的手机特性关联与分类…

Flutter_学习记录_Tab的简单Demo~真的很简单

1. Tab的简单使用了解 要实现tab(选项卡或者标签视图)需要用到三个组件&#xff1a; TabBarTabBarViewTabController 这一块&#xff0c;我也不知道怎么整理了&#xff0c;直接提供代码吧&#xff1a; import package:flutter/material.dart;void main() {runApp(MyApp());…

JavaScript中的数组方法总结+详解

在JS中,数组方法是非常重要且常用的方法.在此整理总结一番. 1. javaScript常用数组方法 2.方法详解 1.push(); 功能: 在数组最后一位添加一个或多个元素,并返回新数组的长度,改变原数组.(添加多个元素用逗号隔开) var arr [1, 2, "c"];var rel arr.push(&q…

蓝桥杯之c++入门(二)【输入输出(上)】

目录 前言1&#xff0e;getchar和 putchar1.1 getchar()1.2 putchar() 2&#xff0e;scanf和 printf2.1 printf2.1.1基本用法2.1.2占位符2.1.3格式化输出2.1.3.1 限定宽度2.1.3.2 限定小数位数 2.2 scanf2.2.1基本用法2.2.2 占位符2.2.3 scanf的返回值 2.3练习练习1&#xff1a…

[EAI-028] Diffusion-VLA,能够进行多模态推理和机器人动作预测的VLA模型

Paper Card 论文标题&#xff1a;Diffusion-VLA: Scaling Robot Foundation Models via Unified Diffusion and Autoregression 论文作者&#xff1a;Junjie Wen, Minjie Zhu, Yichen Zhu, Zhibin Tang, Jinming Li, Zhongyi Zhou, Chengmeng Li, Xiaoyu Liu, Yaxin Peng, Chao…

3.5.5 基于横盘结构的分析体系——缠论(走势类型)

走势 缠论中走势的定义如下&#xff1a; 包含一个中枢的走势——盘整 包含两个或多个中枢的走势——趋势 方向 趋势&#xff08;两中枢或多中枢&#xff09; 盘整&#xff08;一中枢&#xff09; 上涨 下跌 表1-8 盘整和趋势类型的走势理论图。 趋势和中枢 …

使用PyQt5绘制带有刻度的温度计控件

前言&#xff1a;进入学习Python开发上位机界面的第二阶段&#xff0c;学习如何开发自定义控件&#xff0c;从常用的控件入手学习&#xff0c;本期主要学习如何使用PyQt5绘制带有刻度的温度计控件。 1. 先找到一篇参考文章 参考文章&#xff1a;Qt编写自定义控件5-柱状温度计…

DIFY源码解析

偶然发现Github上某位大佬开源的DIFY源码注释和解析&#xff0c;目前还处于陆续不断更新地更新过程中&#xff0c;为大佬的专业和开源贡献精神点赞。先收藏链接&#xff0c;后续慢慢学习。 相关链接如下&#xff1a; DIFY源码解析

赛博算卦之周易六十四卦JAVA实现:六幺算尽天下事,梅花化解天下苦。

佬们过年好呀~新年第一篇博客让我们来场赛博算命吧&#xff01; 更多文章&#xff1a;个人主页 系列文章&#xff1a;JAVA专栏 欢迎各位大佬来访哦~互三必回&#xff01;&#xff01;&#xff01; 文章目录 #一、文化背景概述1.文化起源2.起卦步骤 #二、卦象解读#三、just do i…

「AI学习笔记」深度学习的起源与发展:从神经网络到大数据(二)

深度学习&#xff08;DL&#xff09;是现代人工智能&#xff08;AI&#xff09;的核心之一&#xff0c;但它并不是一夜之间出现的技术。从最初的理论提出到如今的广泛应用&#xff0c;深度学习经历了几乎一个世纪的不断探索与发展。今天&#xff0c;我们一起回顾深度学习的历史…

AIGC技术中常提到的 “嵌入转换到同一个向量空间中”该如何理解

在AIGC&#xff08;人工智能生成内容&#xff09;技术中&#xff0c;“嵌入转换到同一个向量空间中”是一个核心概念&#xff0c;其主要目的是将不同类型的输入数据&#xff08;如文本、图像、音频等&#xff09;映射到一个统一的连续向量空间中&#xff0c;从而实现数据之间的…

单细胞分析基础-第一节 数据质控、降维聚类

scRNA_pipeline\1.Seurat 生物技能树 可进官网查询 添加链接描述 分析流程 准备:R包安装 options("repos"="https://mirrors.ustc.edu.cn/CRAN/") if(!require("BiocManager")) install.packages("BiocManager",update = F,ask =…

【13】WLC HA介绍和配置

1.概述 本文对AireOS WLC的HA进行介绍,和大多数网络架构设计一样,单台的WLC是无法保证设备的冗余性的,而且WLC也不是双引擎的设备,所以需要依靠High Available的技术来为WLC提供高可用性。 2.WLC HA类型 AireOS WLC的高可用性技术可以分为N+1的SSO的HA。不是所有的设备都…

Alibaba开发规范_编程规约之命名风格

文章目录 命名风格的基本原则1. 命名不能以下划线或美元符号开始或结束2. 严禁使用拼音与英文混合或直接使用中文3. 类名使用 UpperCamelCase 风格&#xff0c;但以下情形例外&#xff1a;DO / BO / DTO / VO / AO / PO / UID 等4. 方法名、参数名、成员变量、局部变量使用 low…

【Elasticsearch 基础入门】Centos7下Elasticsearch 7.x安装与配置(单机)

Elasticsearch系列文章目录 【Elasticsearch 基础入门】一文带你了解Elasticsearch&#xff01;&#xff01;&#xff01;【Elasticsearch 基础入门】Centos7下Elasticsearch 7.x安装与配置&#xff08;单机&#xff09; 目录 Elasticsearch系列文章目录前言单机模式1. 安装 J…

Gurobi基础语法之 addConstr, addConstrs, addQConstr, addMQConstr

在新版本的 Gurobi 中&#xff0c;向 addConstr 这个方法中传入一个 TempConstr 对象&#xff0c;在模型中就会根据这个对象生成一个约束。更重要的是&#xff1a;TempConstr 对象可以传给所有addConstr系列方法&#xff0c;所以下面先介绍 TempConstr 对象 TempConstr TempC…

深度学习可视化指标方法工具

1. TensorBoard 简介&#xff1a;由TensorFlow提供的可视化工具&#xff0c;现已支持多种深度学习框架。 功能&#xff1a; 图可视化&#xff1a;展示计算图结构&#xff0c;帮助理解模型架构。 标量仪表板&#xff1a;跟踪损失和准确率等指标的变化。 直方图仪表板&#xf…

【自开发工具介绍】SQLSERVER的ImpDp和ExpDp工具01

1、开发背景 大家都很熟悉&#xff0c;Oracle提供了Impdp和ExpDp工具&#xff0c;功能很强大&#xff0c;可以进行db的导入导出的处理。但是对于Sqlserver数据库只是提供了简单的图形化的导出导入工具&#xff0c;在实际的开发和生产环境不太可能让用户在图形化的界面选择移行…