HTMLcss实现网站抽奖

代码由 HTML、CSS 和 JavaScript 三部分组成,HTML 负责页面的结构搭建,CSS 负责页面的样式设计,JavaScript 负责实现抽奖的交互逻辑。

HTML 部分

复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./assets/global.css">
    <!-- 内联样式 -->
    <style>
        /* 样式规则 */
    </style>
</head>

<body>
    <div class="prize-container">
        <!-- 奖品项 -->
        <div class="prize-item" style="left: 0;top: 0;"></div>
        <!-- ... 其他奖品项 ... -->
        <div class="prize-turn" style="left: 200px;top: 200px;">开始转动</div>
    </div>

    <script type="module"> 
        // JavaScript 代码
    </script>
</body>

</html>
  • <!DOCTYPE html>:声明文档类型为 HTML5。
  • <html> :根元素,lang="en" 表示页面语言为英语。
  • <head> :包含页面的元数据,如字符编码、兼容性设置、视口设置,还引入了外部样式表 ./assets/global.css,并定义了内联样式。
  • <body> :页面的主体部分,包含一个 prize-container 容器,其中有 8 个 prize-item 元素表示奖品项,一个 prize-turn 元素作为开始转动的按钮。
  • <script> :引入 JavaScript 代码,type="module" 表示使用 ES6 模块语法。

CSS 部分

复制代码
.prize-container {
    position: relative;
}

.prize-container .prize-item,
.prize-container .prize-turn {
    position: absolute;
    width: 200px;
    height: 200px;
    display: flex;
    align-items: center;
    justify-content: center;
    user-select: none;
    box-sizing: border-box;
}

.prize-container .prize-turn {
    background-color: #fff;
    cursor: pointer;
    border-radius: 50%;
    border: 1px solid rgb(209, 92, 92);
    font-size: 30px;
    transform: scale(.5, .5);
    color: rgb(209, 92, 92);
    transition: all .4s ease-in;
}

.prize-container .prize-item {
    border: 4px solid transparent;
}

.prize-container .prize-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: .9;
}

.prize-container .prize-item>div {
    position: absolute;
    width: 100%;
    text-align: center;
    left: 0;
    font-weight: bold;
    color: beige;
    line-height: 30px;
    bottom: 0;
    background-color: rgba(0, 0, 0, .3);
}

.prize-container .prize-turn:active {
    background-color: rgb(209, 92, 92);
    color: #fff;
}

.prize-container .prize-item.active {
    border-color: #eb9c26;
}
  • .prize-container:设置为相对定位,作为奖品项和转动按钮的父容器。
  • .prize-item.prize-turn:设置为绝对定位,固定宽度和高度,使用 flex 布局使其内容居中,禁止用户选择文本。
  • .prize-turn:设置为白色背景,圆形,有边框和文字颜色,点击时背景和文字颜色会发生变化。
  • .prize-item:初始边框为透明。
  • .prize-item img:设置图片宽度和高度为 100%,保持图片比例并覆盖整个容器,透明度为 0.9。
  • .prize-item > div:设置奖品名称的样式,位于图片底部,有半透明背景。
  • .prize-item.active :当奖品项处于激活状态时,边框颜色变为 #eb9c26

JavaScript 部分

复制代码
import { Maths, Randoms, Animation } from "https://unpkg.com/@3r/tool"
// 获取所有的奖品项和转动按钮
let prizeDomList = document.querySelectorAll('.prize-item')
let prizeTurnDom = document.querySelector('.prize-turn')
let startIndex = 0;
// 奖品列表
let prizes = [
    {
        name: '苹果13',
        weight: 1,
        imgSrc: './assets/prizes/1.jpg'
    },
    // ... 其他奖品 ...
]

// 展示奖品信息
for (let i = 0; i < prizeDomList.length; i++) {
    const prizeItem = prizeDomList[i];
    const prizeText = document.createElement('div')
    const prizeImage = document.createElement('img')

    prizeText.textContent = prizes[i].name
    prizeImage.setAttribute("src", prizes[i].imgSrc)

    prizeItem.appendChild(prizeImage)
    prizeItem.appendChild(prizeText)
}

// 等待时间函数
let waitTime = function (time) {
    return {
        then: function (resolve) {
            setTimeout(resolve, time)
        }
    }
}

// 转动函数
let turn = async function () {
    let offset = 1 / (prizes.length * 10) // 执行次数
    let interval = 200; // 延迟
    let minInterval = 50; // 最小延迟
    let endIndex = Randoms.getRandomIndexByWeight(prizes) // 随机结束奖品
    let lastDom = null
    for (let i = 0; i <= 1; i += offset) {
        // 延迟时间
        await waitTime(Math.max(Animation.easeIn(i) * interval, minInterval))
        lastDom?.classList?.remove('active');
        lastDom = prizeDomList.item(startIndex % prizeDomList.length)
        lastDom.classList.add('active')
        if (i > .9 && (startIndex % prizeDomList.length === endIndex)) break;
        startIndex++;
    }
    let name = prizes[endIndex].name

    setTimeout(() => {
        if (name == "再来一次")
            alert(`请${name}吧~`)
        else
            alert(`您获得了${name}`)
    }, interval);
}

// 点击事件监听
prizeTurnDom.addEventListener("click", turn)    
  • 导入模块 :从 https://unpkg.com/@3r/tool 导入 MathsRandomsAnimation 模块。
  • 获取元素 :使用 querySelectorAllquerySelector 获取所有奖品项和转动按钮。
  • 奖品列表:定义了一个包含 8 个奖品的数组,每个奖品有名称、权重和图片路径。
  • 展示奖品信息:遍历奖品项,为每个奖品项创建图片和名称元素,并添加到对应的奖品项中。
  • 等待时间函数waitTime 函数返回一个对象,包含 then 方法,用于实现异步延迟。
  • 转动函数turn 函数实现了抽奖的转动逻辑,通过 Randoms.getRandomIndexByWeight 方法根据权重随机选择一个奖品,然后循环遍历奖品项,逐渐增加激活状态的奖品项,直到达到随机选择的奖品项。
  • 点击事件监听 :为转动按钮添加点击事件监听器,点击时调用 turn 函数。

效果展示

相关推荐
电商api接口开发2 小时前
ASP.NET MVC 入门指南二
前端·c#·html·mvc
Senar3 小时前
Web端选择本地文件的几种方式
前端·javascript·html
我爱吃朱肉5 小时前
HTMLCSS模板实现水滴动画效果
前端·css·css3
全栈老李技术面试5 小时前
【高频考点精讲】async/await原理剖析:Generator和Promise的完美结合
前端·javascript·css·vue·html·react·面试题
街尾杂货店&7 小时前
HTML word属性
前端·html
工呈士7 小时前
HTML与安全性:XSS、防御与最佳实践
前端·html·xss
土豆12507 小时前
构建高级半圆形进度条:SVG 与 纯 CSS 方案深度解析与完整代码
css·react.js·svg
土豆12508 小时前
Tailwind CSS 精通指南:提升效率、可维护性与最佳实践
前端·css
kooboo china.10 小时前
Tailwind CSS 实战:基于 Kooboo 构建企业官网页面(一)
前端·css·编辑器