发布于2026-07-23 阅读(0)
扫一扫,手机访问
在Web应用里,积分抽奖活动一直是提升用户活跃度和留存率的有效手段。接下来就来看看,如何用HTML、CSS和Ja vaScript,实现一个带流畅动画和良好体验的九宫格积分抽奖系统。
这个抽奖系统采用了经典的九宫格布局,中间是抽奖按钮,周围的八个格子展示不同的奖品。用户点击“开始抽奖”后,系统会扣除100积分,然后启动动画,最终高亮显示中奖结果,并通过弹窗展示奖励详情。



页面采用居中布局,主体容器 container 包含了标题、积分信息和抽奖区域三个主要部分。
积分抽奖
当前积分:1000
那么,这个九宫格是怎么布局的呢?答案是使用CSS Grid,实现3×3的网格结构,中心位置则放置了抽奖按钮。
10积分参与奖50积分幸运奖100积分三等奖500积分特等奖20积分鼓励奖200积分二等奖谢谢参与再接再厉30积分安慰奖
中奖结果的展示,则通过一个模态框 result-modal 来实现。
系统通过几个关键变量来管理整个抽奖状态:
let currentPoints = 1000;let drawCost = 100;let isDrawing = false;let prizes = [ { name: '10积分', points: 10, probability: 25, desc: '恭喜获得参与奖!' }, // ...其他奖品配置];
startDraw 函数是抽奖的总控制台。它首先用 isDrawing 标志位防止重复点击,然后检查积分是否足够,接着扣除积分、更新界面,清理上一次的高亮状态,最后启动核心的动画逻辑 startLotteryAnimation。
function startDraw() { if (isDrawing) return; if (currentPoints < drawCost) { showResult('积分不足', `当前积分:${currentPoints},需要${drawCost}积分才能抽奖!`); return; } isDrawing = true; currentPoints -= drawCost; updatePointsDisplay(); updateDrawButtonState(true); // 清除之前选中状态并启动动画 document.querySelectorAll('.lottery-item').forEach(item => { item.classList.remove('active'); }); startLotteryAnimation();}
startLotteryAnimation 函数负责实现九宫格循环高亮的动画效果。它先确定总共有8个奖项格子,设定基础转动圈数为3圈,然后通过 getRandomPrizeIndex 获取中奖位置,计算出总的动画步数。
动画过程中,使用递归 setTimeout 实现循环播放,每一步都会移除前一个格子的高亮状态、给当前格子添加高亮效果,同时根据当前步数动态调整速度——前20步加速,最后20步减速,最终在指定步数停止,并调用 showDrawResult 展示结果。
function startLotteryAnimation() { const totalItems = 8; const baseRounds = 3; const finalIndex = getRandomPrizeIndex(); const totalSteps = baseRounds * totalItems + finalIndex; let currentStep = 0; let currentIndex = 0; let previousIndex = -1; let speed = 50; // 初始速度 const animate = () => { // 移除前一个元素的 active 类 if (previousIndex !== -1) { const previousItem = document.querySelector(`[data-index="${previousIndex}"]`); if (previousItem) { previousItem.classList.remove('active'); } } // 高亮当前格子 const currentItem = document.querySelector(`[data-index="${currentIndex}"]`); if (currentItem) { currentItem.classList.add('active'); } previousIndex = currentIndex; currentStep++; // 速度逐渐变慢 if (currentStep > totalSteps - 20) { speed += 10; } else if (currentStep < 20) { speed = Math.max(30, speed - 5); } // 更新索引 currentIndex = (currentIndex + 1) % totalItems; if (currentStep < totalSteps) { setTimeout(animate, speed); } else { // 动画结束,显示结果 setTimeout(() => { showDrawResult(finalIndex); }, 500); } }; animate();}
getRandomPrizeIndex 函数基于概率权重算法来确定中奖结果。它首先生成一个0到100之间的随机数,然后遍历 prizes 数组,累加每个奖项的概率值,当随机数小于等于累计概率时,就返回当前奖项的索引,从而实现按照预设概率分布进行抽奖。如果遍历完所有奖项都没有匹配,则默认返回索引0。
function getRandomPrizeIndex() { const random = Math.random() * 100; let cumulative = 0; for (let i = 0; i < prizes.length; i++) { cumulative += prizes[i].probability; if (random <= cumulative) { return i; } } return 0;}
积分抽奖 积分抽奖
当前积分:1000
10积分参与奖50积分幸运奖100积分三等奖500积分特等奖20积分鼓励奖200积分二等奖谢谢参与再接再厉30积分安慰奖
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8