【星辰电竞】免单抽奖开源代码
<!DOCTYPE html><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>幸运抽奖系统 · 完美转盘版</title><linkrel="stylesheet"href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"><style>* {margin: 0;padding: 0;box-sizing: border-box;font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;}body {background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);min-height: 100vh;display: flex;flex-direction: column;align-items: center;padding: 20px;color: white;overflow-x: hidden;}.header {text-align: center;margin-bottom: 30px;padding: 20px;width: 100%;}h1 {font-size: 3.2rem;margin-bottom: 15px;text-shadow: 0 0 15px rgba(255, 255, 255, 0.7);background: linear-gradient(to right, #ff9966, #ff5e62);-webkit-background-clip: text;-webkit-text-fill-color: transparent;letter-spacing: 2px;}.subtitle {font-size: 1.3rem;color: #ffcc00;margin-bottom: 10px;text-shadow: 0 0 5px rgba(0,0,0,0.5);}.tabs {display: flex;justify-content: center;margin-bottom: 30px;background: rgba(0, 0, 0, 0.3);border-radius: 50px;padding: 8px;max-width: 500px;width: 100%;box-shadow: 0 5px 15px rgba(0,0,0,0.3);}.tab-btn {background: none;border: none;color: white;padding: 14px 35px;font-size: 1.2rem;cursor: pointer;border-radius: 30px;transition: all 0.3s ease;margin: 0 5px;display: flex;align-items: center;gap: 8px;}.tab-btn.active {background: linear-gradient(to right, #ff9966, #ff5e62);box-shadow: 0 0 15px rgba(255, 94, 98, 0.5);}.tab-btn i {font-size: 1.3rem;}.container {display: flex;flex-direction: column;align-items: center;width: 100%;max-width: 1200px;}.tab-content {display: none;width: 100%;background: rgba(255, 255, 255, 0.1);backdrop-filter: blur(10px);border-radius: 20px;padding: 35px;box-shadow: 0 15px 35px rgba(0, 0, 0, 0.4);margin-bottom: 30px;border: 1px solid rgba(255,255,255,0.2);}.tab-content.active {display: block;animation: fadeIn 0.6s ease;}@keyframes fadeIn {from { opacity: 0; transform: translateY(20px); }to { opacity: 1; transform: translateY(0); }}/* 转盘抽奖样式 (Canvas版) */.wheel-container {display: flex;flex-direction: column;align-items: center;}.wheel-wrapper {position: relative;width: 420px;height: 420px;margin: 0 auto 40px;}#wheelCanvas {width: 100%;height: 100%;display: block;border-radius: 50%;box-shadow: 0 0 0 15px rgba(255, 215, 0, 0.5),0 0 40px rgba(255, 215, 0, 0.8);transition: transform 4s cubic-bezier(0.17, 0.67, 0.12, 0.99);background: #2c3e50; /* 底色, 实际被canvas覆盖 */}.wheel-center {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);width: 70px;height: 70px;background: #fff;border-radius: 50%;box-shadow: 0 0 15px rgba(0,0,0,0.5);z-index: 10;display: flex;align-items: center;justify-content: center;font-weight: bold;color: #ff5e62;font-size: 1.4rem;cursor: pointer;transition: transform 0.3s ease;}.wheel-center:hover {transform: translate(-50%, -50%) scale(1.1);}.pointer {position: absolute;top: -25px;left: 50%;transform: translateX(-50%);width: 50px;height: 70px;z-index: 9;}.pointer::before {content: "";position: absolute;top: 0;left: 0;width: 0;height: 0;border-left: 25px solid transparent;border-right: 25px solid transparent;border-top: 50px solid #ff5e62;filter: drop-shadow(0 0 5px rgba(0,0,0,0.5));}.controls {display: flex;flex-direction: column;align-items: center;width: 100%;max-width: 500px;}.prize-result {margin: 25px 0;font-size: 1.8rem;min-height: 50px;text-align: center;font-weight: bold;color: gold;text-shadow: 0 0 8px rgba(0,0,0,0.8);padding: 15px 30px;border-radius: 15px;background: rgba(0,0,0,0.3);width: 100%;transition: all 0.3s ease;}.prize-result.win {background: rgba(0, 100, 0, 0.4);animation: pulse 1s infinite;}@keyframes pulse {0% { box-shadow: 0 0 5px gold; }50% { box-shadow: 0 0 20px gold; }100% { box-shadow: 0 0 5px gold; }}.btn {background: linear-gradient(to right, #ff9966, #ff5e62);border: none;color: white;padding: 18px 45px;font-size: 1.3rem;border-radius: 50px;cursor: pointer;transition: all 0.3s ease;box-shadow: 0 5px 20px rgba(255, 94, 98, 0.4);margin: 15px 0;display: flex;align-items: center;gap: 10px;font-weight: bold;letter-spacing: 1px;}.btn:hover {transform: translateY(-5px);box-shadow: 0 10px 25px rgba(255, 94, 98, 0.6);}.btn:active {transform: translateY(2px);}.prize-info {display: grid;grid-template-columns: repeat(3, 1fr);gap: 20px;width: 100%;max-width: 700px;margin-top: 30px;}.prize-card {background: rgba(255, 255, 255, 0.15);border-radius: 15px;padding: 20px;text-align: center;border: 2px solid rgba(255,255,255,0.2);transition: all 0.3s ease;}.prize-card:hover {transform: translateY(-5px);box-shadow: 0 10px 20px rgba(0,0,0,0.2);}.prize-card h3 {font-size: 1.4rem;margin-bottom: 10px;color: #ffcc00;}.prize-card p {font-size: 1.2rem;font-weight: bold;}/* 名字抽取样式 */.draw-container {display: flex;flex-direction: column;align-items: center;width: 100%;}.input-area {width: 100%;max-width: 700px;margin-bottom: 30px;}textarea {width: 100%;height: 180px;padding: 20px;border-radius: 15px;border: 3px solid #ff5e62;background: rgba(255, 255, 255, 0.1);color: white;font-size: 18px;resize: vertical;margin-bottom: 20px;transition: all 0.3s ease;}textarea:focus {outline: none;border-color: #ffcc00;box-shadow: 0 0 15px rgba(255, 204, 0, 0.5);}textarea::placeholder {color: rgba(255, 255, 255, 0.6);}.draw-controls {display: flex;flex-wrap: wrap;gap: 20px;justify-content: center;margin-bottom: 30px;width: 100%;}.draw-controls input {padding: 15px 25px;border-radius: 30px;border: 3px solid #ff5e62;background: rgba(255, 255, 255, 0.1);color: white;font-size: 18px;width: 150px;text-align: center;font-weight: bold;}.result-area {display: flex;flex-wrap: wrap;justify-content: center;gap: 25px;width: 100%;max-width: 900px;min-height: 200px;margin-bottom: 30px;}.result-card {background: linear-gradient(135deg, #ff9966, #ff5e62);border-radius: 18px;padding: 30px 45px;font-size: 2.2rem;font-weight: bold;text-align: center;box-shadow: 0 8px 25px rgba(0, 0, 0, 0.4);animation: popIn 0.5s ease;min-width: 220px;display: flex;align-items: center;justify-content: center;position: relative;overflow: hidden;}.result-card::after {content: "";position: absolute;top: -50%;left: -50%;width: 200%;height: 200%;background: linear-gradient(rgba(255,255,255,0.1), rgba(255,255,255,0));transform: rotate(30deg);}@keyframes popIn {0% { transform: scale(0.5) rotate(-10deg); opacity: 0; }100% { transform: scale(1) rotate(0); opacity: 1; }}.history {width: 100%;max-width: 800px;margin-top: 20px;background: rgba(0, 0, 0, 0.2);border-radius: 20px;padding: 25px;border: 1px solid rgba(255,255,255,0.1);}.history h3 {text-align: center;margin-bottom: 20px;color: #ffcc00;font-size: 1.8rem;display: flex;align-items: center;justify-content: center;gap: 15px;}.history-list {max-height: 220px;overflow-y: auto;padding: 10px;background: rgba(0,0,0,0.2);border-radius: 10px;}.history-item {padding: 15px;border-bottom: 1px solid rgba(255, 255, 255, 0.1);font-size: 1.2rem;display: flex;align-items: center;gap: 15px;}.history-item::before {content: "•";color: #ff5e62;font-size: 1.8rem;}/* 响应式 */@media (max-width: 900px) {.prize-info {grid-template-columns: repeat(2, 1fr);}}@media (max-width: 768px) {.wheel-wrapper {width: 350px;height: 350px;}h1 {font-size: 2.5rem;}.result-card {font-size: 1.8rem;padding: 25px 35px;}.prize-info {grid-template-columns: 1fr;}}@media (max-width: 480px) {.wheel-wrapper {width: 280px;height: 280px;}.btn {padding: 15px 35px;font-size: 1.1rem;}.draw-controls {flex-direction: column;align-items: center;}.tab-btn {padding: 12px 25px;font-size: 1.1rem;}h1 {font-size: 2rem;}.result-card {font-size: 1.5rem;padding: 20px 30px;min-width: 180px;}}.firework {position: absolute;width: 10px;height: 10px;border-radius: 50%;pointer-events: none;animation: firework 1s ease-out;z-index: 100;}@keyframes firework {0% { transform: translate(0, 0); opacity: 1; }100% { transform: translate(var(--tx), var(--ty)); opacity: 0; }}.confetti {position: absolute;width: 15px;height: 15px;background-color: #f00;border-radius: 50%;animation: confetti-fall 3s linear forwards;z-index: 1000;}@keyframes confetti-fall {0% {transform: translateY(-20vh) rotate(0deg);opacity: 1;}100% {transform: translateY(100vh) rotate(720deg);opacity: 0;}}</style></head><body><divclass="header"><h1><iclass="fas fa-star"></i> 幸运抽奖系统 <iclass="fas fa-star"></i></h1><pclass="subtitle">优化版 · 完美转盘 + 名字抽取</p></div><divclass="tabs"><buttonclass="tab-btn active"data-tab="wheel"><iclass="fas fa-sync-alt"></i> 转盘抽奖</button><buttonclass="tab-btn"data-tab="draw"><iclass="fas fa-users"></i> 名字抽取</button></div><divclass="container"><!-- 转盘抽奖页面 (Canvas重制) --><divid="wheel-tab"class="tab-content active"><divclass="wheel-container"><divclass="wheel-wrapper"><canvasid="wheelCanvas"width="400"height="400"></canvas><divclass="wheel-center"id="spin-center">GO!</div><divclass="pointer"></div></div><divclass="prize-result"id="prize-result">点击GO!开始抽奖...</div><divclass="controls"><buttonclass="btn"id="spin-btn"><iclass="fas fa-play"></i> 开始抽奖</button></div><divclass="prize-info"><divclass="prize-card"><h3><iclass="fas fa-trophy"></i> 一等奖</h3><p>概率 2%</p></div><divclass="prize-card"><h3><iclass="fas fa-medal"></i> 二等奖</h3><p>概率 5%</p></div><divclass="prize-card"><h3><iclass="fas fa-award"></i> 三等奖</h3><p>概率 10%</p></div><divclass="prize-card"><h3><iclass="fas fa-gem"></i> 四等奖</h3><p>概率 20%</p></div><divclass="prize-card"><h3><iclass="fas fa-certificate"></i> 五等奖</h3><p>概率 30%</p></div><divclass="prize-card"><h3><iclass="fas fa-heart"></i> 参与奖</h3><p>概率 33%</p></div></div></div></div><!-- 名字抽取页面 (保持不变) --><divid="draw-tab"class="tab-content"><divclass="draw-container"><divclass="input-area"><textareaid="name-input"placeholder="请输入名字,每行一个名字 例如: 张三 李四 王五 赵六 钱七"></textarea></div><divclass="draw-controls"><inputtype="number"id="draw-count"min="1"max="20"value="3"placeholder="抽取数量"><buttonclass="btn"id="draw-btn"><iclass="fas fa-random"></i> 随机抽取</button><buttonclass="btn"id="reset-btn"><iclass="fas fa-redo"></i> 重置结果</button></div><divclass="result-area"id="result-area"></div><divclass="history"><h3><iclass="fas fa-history"></i> 抽取历史</h3><divclass="history-list"id="history-list"></div></div></div></div></div><script>// ================== 标签切换 ==================const tabBtns = document.querySelectorAll('.tab-btn');const tabContents = document.querySelectorAll('.tab-content');tabBtns.forEach(btn => {btn.addEventListener('click', () => {tabBtns.forEach(b => b.classList.remove('active'));tabContents.forEach(c => c.classList.remove('active'));btn.classList.add('active');const tabId = btn.getAttribute('data-tab');document.getElementById(`${tabId}-tab`).classList.add('active');});});// ================== 转盘抽奖 (Canvas绘制) ==================const canvas = document.getElementById('wheelCanvas');const ctx = canvas.getContext('2d');const spinBtn = document.getElementById('spin-btn');const spinCenter = document.getElementById('spin-center');const prizeResult = document.getElementById('prize-result');// 奖项配置 (名称, 概率, 颜色)const prizes = [{ name: "一等奖", probability: 2, color: "#FF6384" },{ name: "二等奖", probability: 5, color: "#36A2EB" },{ name: "三等奖", probability: 10, color: "#FFCE56" },{ name: "四等奖", probability: 20, color: "#4BC0C0" },{ name: "五等奖", probability: 30, color: "#9966FF" },{ name: "参与奖", probability: 33, color: "#C9CBCF" }];// 计算总概率 & 存储每个奖项的角度范围 (弧度, 绝对角度从0°开始)const totalProb = prizes.reduce((sum, p) => sum + p.probability, 0);let prizeRanges = []; // 每个奖项: { start, end, mid, name, color }function calcRanges() {let start = 0; // 弧度, 从0开始 (右侧水平)prizeRanges = prizes.map(p => {const angle = (p.probability / totalProb) * 2 * Math.PI;const end = start + angle;const mid = start + angle / 2;const range = {start, end, mid,name: p.name,color: p.color,probability: p.probability};start = end;return range;});}calcRanges();// 绘制转盘function drawWheel() {const w = canvas.width;const h = canvas.height;const radius = w * 0.4; // 留出边距const centerX = w / 2;const centerY = h / 2;ctx.clearRect(0, 0, w, h);// 绘制每个扇形prizeRanges.forEach(range => {ctx.beginPath();ctx.moveTo(centerX, centerY);ctx.arc(centerX, centerY, radius, range.start, range.end);ctx.closePath();ctx.fillStyle = range.color;ctx.fill();// 描边分割线ctx.strokeStyle = 'rgba(255,255,255,0.3)';ctx.lineWidth = 2;ctx.beginPath();ctx.moveTo(centerX, centerY);ctx.arc(centerX, centerY, radius, range.start, range.end);ctx.lineTo(centerX, centerY);ctx.stroke();});// 绘制文字ctx.fillStyle = '#1e2a3a';ctx.font = 'bold 18px "Segoe UI", "Microsoft YaHei", sans-serif';ctx.textAlign = 'center';ctx.textBaseline = 'middle';prizeRanges.forEach(range => {const textRadius = radius * 0.7;const x = centerX + Math.cos(range.mid) * textRadius;const y = centerY + Math.sin(range.mid) * textRadius;// 白色背景衬底ctx.fillStyle = '#ffffff';ctx.fillText(range.name, x, y);ctx.fillStyle = '#1e2a3a';ctx.fillText(range.name, x, y);});// 中心小圆装饰ctx.beginPath();ctx.arc(centerX, centerY, 12, 0, 2 * Math.PI);ctx.fillStyle = '#ffdd99';ctx.shadowColor = 'gold';ctx.shadowBlur = 10;ctx.fill();ctx.shadowBlur = 0;}// 旋转转盘let isSpinning = false;const wheelCanvasEl = document.getElementById('wheelCanvas');function spinWheel() {if (isSpinning) return;isSpinning = true;// 重置旋转 (瞬间回到0°, 取消过渡)wheelCanvasEl.style.transition = 'none';wheelCanvasEl.style.transform = 'rotate(0deg)';prizeResult.textContent = "抽奖中...";prizeResult.classList.remove('win');// 根据概率随机选择奖项let rand = Math.random() * totalProb;let accumulated = 0;let selectedRange = null;for (let i = 0; i < prizes.length; i++) {accumulated += prizes[i].probability;if (rand <= accumulated) {selectedRange = prizeRanges[i];break;}}// 计算目标角度: 使选中扇形的中间(mid)对准指针方向(指针在正上方 = -90° 或 270°)// 指针方向(绝对): -PI/2 (270°)// 旋转公式: 需要将mid转到 -PI/2 方向, 因此旋转角度 = mid - (-PI/2) = mid + PI/2 (弧度)// 转换为度: rotation = (mid + PI/2) * 180/PIconst mid = selectedRange.mid; // 弧度let targetDeg = (mid + Math.PI/2) * 180 / Math.PI; // 转换为度// 多转几圈增加真实感targetDeg += 360 * 5; // 5圈// 应用旋转setTimeout(() => {wheelCanvasEl.style.transition = 'transform 4s cubic-bezier(0.17, 0.67, 0.12, 0.99)';wheelCanvasEl.style.transform = `rotate(${targetDeg}deg)`;// 烟花 & 结果createFireworks(20);setTimeout(() => {prizeResult.textContent = `恭喜您获得:${selectedRange.name}!`;prizeResult.classList.add('win');createConfetti();isSpinning = false;}, 4000);}, 20);}spinBtn.addEventListener('click', spinWheel);spinCenter.addEventListener('click', spinWheel);// 烟花效果function createFireworks(count) {for (let i = 0; i < count; i++) {const f = document.createElement('div');f.className = 'firework';f.style.left = `${Math.random() * 100}%`;f.style.top = `${Math.random() * 100}%`;f.style.backgroundColor = `hsl(${Math.random() * 360}, 100%, 60%)`;f.style.setProperty('--tx', `${Math.random() * 200 - 100}px`);f.style.setProperty('--ty', `${Math.random() * 200 - 100}px`);document.body.appendChild(f);setTimeout(() => f.remove(), 1000);}}// 彩色纸屑function createConfetti() {const colors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff'];for (let i = 0; i < 150; i++) {const c = document.createElement('div');c.className = 'confetti';c.style.left = `${Math.random() * 100}%`;c.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];c.style.animationDuration = `${Math.random() * 3 + 2}s`;document.body.appendChild(c);setTimeout(() => c.remove(), 5000);}}// ================== 名字抽取逻辑 (不变) ==================const nameInput = document.getElementById('name-input');const drawCountInput = document.getElementById('draw-count');const drawBtn = document.getElementById('draw-btn');const resetBtn = document.getElementById('reset-btn');const resultArea = document.getElementById('result-area');const historyList = document.getElementById('history-list');drawBtn.addEventListener('click', () => {const names = nameInput.value.split('\n').filter(name => name.trim() !== '');if (names.length === 0) {alert('请输入至少一个名字');return;}let drawCount = parseInt(drawCountInput.value);if (isNaN(drawCount)) drawCount = 3;drawCount = Math.max(1, Math.min(drawCount, names.length));const selected = [];const temp = [...names];for (let i = 0; i < drawCount; i++) {if (temp.length === 0) break;const idx = Math.floor(Math.random() * temp.length);selected.push(temp[idx]);temp.splice(idx, 1);}// 显示结果resultArea.innerHTML = '';selected.forEach(name => {const card = document.createElement('div');card.className = 'result-card';card.textContent = name;resultArea.appendChild(card);});// 历史记录const item = document.createElement('div');item.className = 'history-item';const time = new Date().toLocaleTimeString();item.textContent = `${time} - 抽取: ${selected.join(', ')}`;historyList.appendChild(item);historyList.scrollTop = historyList.scrollHeight;if (historyList.children.length > 10) {historyList.removeChild(historyList.firstChild);}});resetBtn.addEventListener('click', () => {resultArea.innerHTML = '';});// 初始化window.onload = function() {drawWheel(); // 绘制转盘nameInput.value = "张三\n李四\n王五\n赵六\n钱七\n孙八\n周九\n吴十\n郑十一\n王十二";};</script></body></html>
夜雨聆风
