'commit'
This commit is contained in:
459
static/Test/地狱大转盘V4.html
Normal file
459
static/Test/地狱大转盘V4.html
Normal file
@@ -0,0 +1,459 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>🎰 地狱扭蛋机 V4 - 非酋还是欧皇? 🎰</title>
|
||||
<style>
|
||||
@import url('https://fonts.googleapis.com/css2?family=ZCOOL+KuaiLe&display=swap');
|
||||
|
||||
:root {
|
||||
--machine-red: #ff4757;
|
||||
--machine-dark: #c0392b;
|
||||
--gold: #f1c40f;
|
||||
--glass: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background-color: #2f3542;
|
||||
color: #fff;
|
||||
font-family: 'ZCOOL KuaiLe', cursive, sans-serif;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
color: var(--gold);
|
||||
text-shadow: 2px 2px 0px #000;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* 扭蛋机外壳 */
|
||||
.gacha-machine {
|
||||
position: relative;
|
||||
width: 400px;
|
||||
height: 600px;
|
||||
background: var(--machine-red);
|
||||
border: 10px solid #2f3542;
|
||||
border-radius: 50px 50px 20px 20px;
|
||||
box-shadow: 0 20px 0 var(--machine-dark), 0 30px 50px rgba(0,0,0,0.5);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 透明视窗 */
|
||||
.glass-dome {
|
||||
position: relative;
|
||||
width: 340px;
|
||||
height: 300px;
|
||||
background: radial-gradient(circle at 30% 30%, rgba(255,255,255,0.4) 0%, transparent 60%),
|
||||
rgba(255,255,255,0.1);
|
||||
border: 8px solid #333;
|
||||
border-radius: 40px;
|
||||
margin-top: 30px;
|
||||
overflow: hidden;
|
||||
box-shadow: inset 0 0 30px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
/* 扭蛋球 */
|
||||
.ball {
|
||||
position: absolute;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid rgba(255,255,255,0.3);
|
||||
box-shadow: inset -5px -5px 10px rgba(0,0,0,0.3), 0 5px 10px rgba(0,0,0,0.2);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
.ball img {
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
border: 1px solid rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
/* 扭蛋机下半部 */
|
||||
.controls {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
/* 旋转摇杆 */
|
||||
.handle-container {
|
||||
position: relative;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
background: #dfe6e9;
|
||||
border-radius: 50%;
|
||||
border: 8px solid #636e72;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: transform 0.5s;
|
||||
}
|
||||
|
||||
.handle-bar {
|
||||
width: 80%;
|
||||
height: 20px;
|
||||
background: #636e72;
|
||||
border-radius: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.handle-bar::before, .handle-bar::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: #2d3436;
|
||||
border-radius: 50%;
|
||||
top: -5px;
|
||||
}
|
||||
.handle-bar::before { left: -10px; }
|
||||
.handle-bar::after { right: -10px; }
|
||||
|
||||
.handle-container.spinning {
|
||||
animation: spin-handle 0.5s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin-handle {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* 出蛋口 */
|
||||
.exit-chute {
|
||||
width: 100px;
|
||||
height: 60px;
|
||||
background: #2d3436;
|
||||
border-radius: 10px 10px 0 0;
|
||||
position: relative;
|
||||
box-shadow: inset 0 10px 10px rgba(0,0,0,0.8);
|
||||
}
|
||||
|
||||
.exit-chute::after {
|
||||
content: 'PUSH';
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
font-size: 0.8rem;
|
||||
color: #636e72;
|
||||
}
|
||||
|
||||
/* 结果弹窗 */
|
||||
#resultOverlay {
|
||||
position: fixed;
|
||||
top: 0; left: 0; width: 100%; height: 100%;
|
||||
background: rgba(0,0,0,0.95);
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.card-container {
|
||||
perspective: 1000px;
|
||||
width: 300px;
|
||||
height: 450px;
|
||||
}
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transform-style: preserve-3d;
|
||||
transition: transform 0.8s;
|
||||
animation: card-reveal 1s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
|
||||
}
|
||||
|
||||
@keyframes card-reveal {
|
||||
0% { transform: scale(0) rotateY(0deg); }
|
||||
100% { transform: scale(1) rotateY(720deg); }
|
||||
}
|
||||
|
||||
.card-front {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #f1c40f 0%, #f39c12 100%);
|
||||
border: 10px solid #fff;
|
||||
border-radius: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
box-shadow: 0 0 50px rgba(241, 196, 15, 0.5);
|
||||
}
|
||||
|
||||
.rarity-badge {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
background: #ff4757;
|
||||
color: white;
|
||||
padding: 5px 15px;
|
||||
border-radius: 20px;
|
||||
font-size: 1.5rem;
|
||||
font-weight: bold;
|
||||
transform: rotate(15deg);
|
||||
box-shadow: 2px 2px 5px rgba(0,0,0,0.3);
|
||||
animation: flash 0.5s infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes flash {
|
||||
from { opacity: 0.8; transform: rotate(15deg) scale(1); }
|
||||
to { opacity: 1; transform: rotate(15deg) scale(1.1); }
|
||||
}
|
||||
|
||||
.student-photo {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 15px;
|
||||
border: 5px solid #fff;
|
||||
object-fit: cover;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.student-name {
|
||||
font-size: 2.5rem;
|
||||
color: #2d3436;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.student-desc {
|
||||
font-size: 1rem;
|
||||
color: #636e72;
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#closeBtn {
|
||||
margin-top: 30px;
|
||||
padding: 10px 40px;
|
||||
background: var(--gold);
|
||||
color: #2d3436;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
font-size: 1.5rem;
|
||||
cursor: pointer;
|
||||
font-family: 'ZCOOL KuaiLe', cursive;
|
||||
}
|
||||
|
||||
/* 提示文字 */
|
||||
.hint {
|
||||
margin-top: 20px;
|
||||
color: #fab1a0;
|
||||
font-size: 1.2rem;
|
||||
animation: bounce 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes bounce {
|
||||
0%, 100% { transform: translateY(0); }
|
||||
50% { transform: translateY(-5px); }
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>🎰 地狱扭蛋机 V4 🎰</h1>
|
||||
|
||||
<div class="gacha-machine">
|
||||
<div class="glass-dome" id="glassDome">
|
||||
<!-- 扭蛋球将由JS生成 -->
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<div class="handle-container" id="handle" onclick="drawGacha()">
|
||||
<div class="handle-bar"></div>
|
||||
</div>
|
||||
|
||||
<div class="exit-chute"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hint">点击摇杆,抽取今日“欧皇”!</div>
|
||||
|
||||
<div id="resultOverlay">
|
||||
<div class="card-container">
|
||||
<div class="card">
|
||||
<div class="card-front">
|
||||
<div class="rarity-badge" id="rarity">SSR</div>
|
||||
<img src="" class="student-photo" id="resultImg">
|
||||
<div class="student-name" id="resultName">???</div>
|
||||
<div class="student-desc" id="resultDesc">这是一个极其稀有的灵魂</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button id="closeBtn" onclick="hideResult()">收下并返回</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const totalStudents = 14;
|
||||
const imagePath = './Result/';
|
||||
const ballColors = ['#ff7675', '#74b9ff', '#55efc4', '#ffeaa7', '#a29bfe', '#fd79a8'];
|
||||
const balls = [];
|
||||
const glassDome = document.getElementById('glassDome');
|
||||
|
||||
const rarities = [
|
||||
{ name: 'N', color: '#bdc3c7', desc: '平平无奇的小可爱' },
|
||||
{ name: 'R', color: '#3498db', desc: '有点意思的灵魂' },
|
||||
{ name: 'SR', color: '#9b59b6', desc: '闪闪发光的候选人' },
|
||||
{ name: 'SSR', color: '#f1c40f', desc: '传说中的天选之子' },
|
||||
{ name: 'UR', color: '#e74c3c', desc: '绝无仅有的地狱之皇' }
|
||||
];
|
||||
|
||||
// 音效系统
|
||||
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
||||
function playSound(freq, type, duration, vol = 0.1) {
|
||||
const osc = audioCtx.createOscillator();
|
||||
const gain = audioCtx.createGain();
|
||||
osc.type = type;
|
||||
osc.frequency.setValueAtTime(freq, audioCtx.currentTime);
|
||||
gain.gain.setValueAtTime(vol, audioCtx.currentTime);
|
||||
gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + duration);
|
||||
osc.connect(gain);
|
||||
gain.connect(audioCtx.destination);
|
||||
osc.start();
|
||||
osc.stop(audioCtx.currentTime + duration);
|
||||
}
|
||||
|
||||
function init() {
|
||||
for (let i = 0; i < 20; i++) {
|
||||
const ball = document.createElement('div');
|
||||
ball.className = 'ball';
|
||||
|
||||
// 添加学生头像
|
||||
const img = document.createElement('img');
|
||||
const studentId = (i % totalStudents) + 1;
|
||||
img.src = `${imagePath}${studentId}.png`;
|
||||
img.onerror = () => img.src = 'https://via.placeholder.com/60?text=?';
|
||||
ball.appendChild(img);
|
||||
|
||||
const x = Math.random() * 280;
|
||||
const y = Math.random() * 240;
|
||||
ball.style.left = x + 'px';
|
||||
ball.style.top = y + 'px';
|
||||
|
||||
// 为扭蛋壳添加随机透明色
|
||||
const color = ballColors[Math.floor(Math.random() * ballColors.length)];
|
||||
ball.style.backgroundColor = color + '66'; // 增加透明度
|
||||
ball.style.borderColor = color;
|
||||
|
||||
glassDome.appendChild(ball);
|
||||
|
||||
balls.push({
|
||||
el: ball,
|
||||
x: x,
|
||||
y: y,
|
||||
vx: (Math.random() - 0.5) * 6,
|
||||
vy: (Math.random() - 0.5) * 6
|
||||
});
|
||||
}
|
||||
animate();
|
||||
}
|
||||
|
||||
let isSpinning = false;
|
||||
let shakeIntensity = 0;
|
||||
|
||||
function animate() {
|
||||
balls.forEach(ball => {
|
||||
ball.x += ball.vx * (1 + shakeIntensity);
|
||||
ball.y += ball.vy * (1 + shakeIntensity);
|
||||
|
||||
if (ball.x < 0 || ball.x > 280) ball.vx *= -1;
|
||||
if (ball.y < 0 || ball.y > 240) ball.vy *= -1;
|
||||
|
||||
ball.el.style.left = ball.x + 'px';
|
||||
ball.el.style.top = ball.y + 'px';
|
||||
});
|
||||
requestAnimationFrame(animate);
|
||||
}
|
||||
|
||||
async function drawGacha() {
|
||||
if (isSpinning) return;
|
||||
isSpinning = true;
|
||||
if (audioCtx.state === 'suspended') audioCtx.resume();
|
||||
|
||||
const handle = document.getElementById('handle');
|
||||
handle.classList.add('spinning');
|
||||
|
||||
// 震动效果
|
||||
shakeIntensity = 5;
|
||||
for (let i = 0; i < 10; i++) {
|
||||
playSound(100 + i * 50, 'square', 0.1, 0.05);
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
}
|
||||
|
||||
shakeIntensity = 0;
|
||||
handle.classList.remove('spinning');
|
||||
|
||||
// 抽取结果
|
||||
const studentIdx = Math.floor(Math.random() * totalStudents) + 1;
|
||||
const rarityIdx = Math.random() < 0.1 ? 4 : (Math.random() < 0.2 ? 3 : (Math.random() < 0.3 ? 2 : (Math.random() < 0.4 ? 1 : 0)));
|
||||
|
||||
showResult(studentIdx, rarityIdx);
|
||||
}
|
||||
|
||||
function showResult(idx, rarityIdx) {
|
||||
const overlay = document.getElementById('resultOverlay');
|
||||
const img = document.getElementById('resultImg');
|
||||
const name = document.getElementById('resultName');
|
||||
const rarity = document.getElementById('rarity');
|
||||
const desc = document.getElementById('resultDesc');
|
||||
const rarityData = rarities[rarityIdx];
|
||||
|
||||
img.src = `${imagePath}${idx}.png`;
|
||||
img.onerror = () => img.src = 'https://via.placeholder.com/200?text=Student';
|
||||
name.innerText = `同学 ${idx}`; // 这里可以根据需要替换成真实姓名列表
|
||||
rarity.innerText = rarityData.name;
|
||||
rarity.style.backgroundColor = rarityData.color;
|
||||
desc.innerText = rarityData.desc;
|
||||
|
||||
overlay.style.display = 'flex';
|
||||
|
||||
// 胜利音效
|
||||
if (rarityIdx >= 3) {
|
||||
// SSR/UR 华丽音效
|
||||
playSound(523, 'sawtooth', 0.5, 0.1);
|
||||
setTimeout(() => playSound(659, 'sawtooth', 0.5, 0.1), 100);
|
||||
setTimeout(() => playSound(783, 'sawtooth', 0.8, 0.1), 200);
|
||||
} else {
|
||||
playSound(440, 'sine', 0.5, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
function hideResult() {
|
||||
document.getElementById('resultOverlay').style.display = 'none';
|
||||
isSpinning = false;
|
||||
}
|
||||
|
||||
window.onload = init;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user