682 lines
30 KiB
HTML
682 lines
30 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>随机点餐转盘</title>
|
||
<script src="https://cdn.tailwindcss.com"></script>
|
||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
|
||
<script>
|
||
tailwind.config = {
|
||
theme: {
|
||
extend: {
|
||
colors: {
|
||
primary: '#FF6B6B',
|
||
secondary: '#4ECDC4',
|
||
accent: '#FFD166',
|
||
dark: '#2A2D34',
|
||
light: '#F7FFF7'
|
||
},
|
||
fontFamily: {
|
||
inter: ['Inter', 'system-ui', 'sans-serif'],
|
||
},
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
<style type="text/tailwindcss">
|
||
@layer utilities {
|
||
.content-auto {
|
||
content-visibility: auto;
|
||
}
|
||
.spinning {
|
||
animation: spin 3s cubic-bezier(0.17, 0.67, 0.83, 0.67);
|
||
}
|
||
.result-appear {
|
||
animation: fadeIn 0.5s ease-in-out;
|
||
}
|
||
.button-press {
|
||
animation: press 0.2s ease-in-out;
|
||
}
|
||
.heart-fall {
|
||
animation: heartFall 3s linear forwards;
|
||
}
|
||
.confetti {
|
||
animation: confettiFall 3s ease-in-out forwards;
|
||
}
|
||
}
|
||
|
||
@keyframes spin {
|
||
0% { transform: rotate(0deg); }
|
||
100% { transform: rotate(calc(360deg * 5 + var(--random-rotation, 0deg))); }
|
||
}
|
||
|
||
@keyframes fadeIn {
|
||
0% { opacity: 0; transform: translateY(10px); }
|
||
100% { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
@keyframes press {
|
||
0% { transform: scale(1); }
|
||
50% { transform: scale(0.95); }
|
||
100% { transform: scale(1); }
|
||
}
|
||
|
||
@keyframes heartFall {
|
||
0% { transform: translateY(-10vh) rotate(0deg); opacity: 1; }
|
||
100% { transform: translateY(110vh) rotate(720deg); opacity: 0; }
|
||
}
|
||
|
||
@keyframes confettiFall {
|
||
0% { transform: translateY(-10vh) rotate(0deg); opacity: 1; }
|
||
100% { transform: translateY(110vh) rotate(360deg); opacity: 0; }
|
||
}
|
||
</style>
|
||
</head>
|
||
<body class="bg-gradient-to-br from-light to-secondary/10 min-h-screen font-inter text-dark flex flex-col relative overflow-x-hidden">
|
||
<header class="bg-white/80 backdrop-blur-md shadow-sm sticky top-0 z-50">
|
||
<div class="container mx-auto px-4 py-4 flex justify-between items-center">
|
||
<h1 class="text-[clamp(1.5rem,3vw,2.5rem)] font-bold text-primary flex items-center">
|
||
<i class="fa-solid fa-cutlery mr-3"></i>
|
||
<span>我可爱的老婆今天吃什么呀?(还有隐藏彩蛋等你呦!)</span>
|
||
</h1>
|
||
<button id="helpBtn" class="p-2 rounded-full hover:bg-gray-100 transition-all duration-300">
|
||
<i class="fa-solid fa-question text-dark/70"></i>
|
||
</button>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="flex-grow container mx-auto px-4 py-8">
|
||
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
|
||
<!-- 左侧:食物列表 -->
|
||
<div class="bg-white rounded-xl shadow-md p-6 order-2 lg:order-1">
|
||
<h2 class="text-xl font-bold mb-4 flex items-center">
|
||
<i class="fa-solid fa-list-ul mr-2 text-secondary"></i>
|
||
食物列表
|
||
</h2>
|
||
<div id="foodList" class="space-y-2 max-h-[400px] overflow-y-auto pr-2">
|
||
<div class="food-item flex items-center justify-between p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-all">
|
||
<span>烤鸭</span>
|
||
<button class="delete-btn text-red-400 hover:text-red-600 transition-colors">
|
||
<i class="fa-solid fa-trash"></i>
|
||
</button>
|
||
</div>
|
||
<div class="food-item flex items-center justify-between p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-all">
|
||
<span>红烧肉</span>
|
||
<button class="delete-btn text-red-400 hover:text-red-600 transition-colors">
|
||
<i class="fa-solid fa-trash"></i>
|
||
</button>
|
||
</div>
|
||
<div class="food-item flex items-center justify-between p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-all">
|
||
<span>炒茄子</span>
|
||
<button class="delete-btn text-red-400 hover:text-red-600 transition-colors">
|
||
<i class="fa-solid fa-trash"></i>
|
||
</button>
|
||
</div>
|
||
<div class="food-item flex items-center justify-between p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-all">
|
||
<span>汉堡</span>
|
||
<button class="delete-btn text-red-400 hover:text-red-600 transition-colors">
|
||
<i class="fa-solid fa-trash"></i>
|
||
</button>
|
||
</div>
|
||
<div class="food-item flex items-center justify-between p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-all">
|
||
<span>奶茶</span>
|
||
<button class="delete-btn text-red-400 hover:text-red-600 transition-colors">
|
||
<i class="fa-solid fa-trash"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mt-6">
|
||
<h3 class="text-lg font-medium mb-2">添加食物</h3>
|
||
<div class="flex">
|
||
<input type="text" id="newFoodInput" placeholder="输入食物名称" class="flex-grow px-4 py-2 rounded-l-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-secondary/50 focus:border-secondary transition-all">
|
||
<button id="addFoodBtn" class="bg-secondary text-white px-4 py-2 rounded-r-lg hover:bg-secondary/90 transition-colors">
|
||
<i class="fa-solid fa-plus"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 中间:转盘 -->
|
||
<div class="flex flex-col items-center justify-center order-1 lg:order-2">
|
||
<div class="relative">
|
||
<!-- 转盘 -->
|
||
<div id="wheelContainer" class="relative w-[min(80vw,400px)] h-[min(80vw,400px)]">
|
||
<canvas id="wheelCanvas" class="w-full h-full rounded-full shadow-lg"></canvas>
|
||
|
||
<!-- 指针 -->
|
||
<div class="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-4 z-10">
|
||
<div class="w-8 h-12 bg-primary rounded-t-lg flex items-start justify-center shadow-md">
|
||
<div class="w-0 h-0 border-l-4 border-r-4 border-b-6 border-l-transparent border-r-transparent border-b-primary transform translate-y-[-10px]"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 中心按钮 -->
|
||
<button id="spinBtn" class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-16 h-16 bg-white rounded-full shadow-lg flex items-center justify-center z-10 hover:bg-gray-50 transition-all duration-300 active:button-press">
|
||
<span class="text-primary font-bold text-lg">转</span>
|
||
</button>
|
||
</div>
|
||
|
||
<!-- 结果显示 -->
|
||
<div id="resultDisplay" class="mt-8 text-center opacity-0">
|
||
<div class="bg-white p-4 rounded-xl shadow-md inline-block transform transition-all">
|
||
<h3 class="text-xl font-bold text-dark mb-1">今天就吃</h3>
|
||
<p id="resultText" class="text-3xl font-bold text-primary"></p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右侧:历史记录 -->
|
||
<div class="bg-white rounded-xl shadow-md p-6 order-3">
|
||
<h2 class="text-xl font-bold mb-4 flex items-center">
|
||
<i class="fa-solid fa-history mr-2 text-accent"></i>
|
||
历史记录
|
||
</h2>
|
||
<div id="historyList" class="space-y-3 max-h-[400px] overflow-y-auto pr-2">
|
||
<!-- 历史记录将通过JS动态添加 -->
|
||
<div class="text-center text-gray-500 italic">暂无记录</div>
|
||
</div>
|
||
|
||
<div class="mt-6">
|
||
<button id="clearHistoryBtn" class="w-full py-2 px-4 bg-gray-100 hover:bg-gray-200 rounded-lg text-gray-700 transition-colors flex items-center justify-center">
|
||
<i class="fa-solid fa-trash mr-2"></i>
|
||
清空历史
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<footer class="bg-dark text-white py-6 mt-8">
|
||
<div class="container mx-auto px-4 text-center">
|
||
<p>© 2025 我可爱的老婆今天吃点什么呢?长按转盘随机点餐哦❤</p>
|
||
<p class="text-sm mt-2 text-gray-400">做出选择,告别纠结</p>
|
||
</div>
|
||
</footer>
|
||
|
||
<!-- 帮助模态框 -->
|
||
<div id="helpModal" class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 hidden flex items-center justify-center">
|
||
<div class="bg-white rounded-xl shadow-xl max-w-md w-full mx-4 overflow-hidden transform transition-all">
|
||
<div class="bg-primary text-white p-4 flex justify-between items-center">
|
||
<h3 class="text-xl font-bold">使用帮助</h3>
|
||
<button id="closeHelpBtn" class="text-white hover:text-gray-200 transition-colors">
|
||
<i class="fa-solid fa-times"></i>
|
||
</button>
|
||
</div>
|
||
<div class="p-6">
|
||
<ul class="space-y-4">
|
||
<li class="flex">
|
||
<div class="bg-primary/10 rounded-full p-2 mr-3">
|
||
<i class="fa-solid fa-list-ul text-primary"></i>
|
||
</div>
|
||
<div>
|
||
<h4 class="font-bold">管理食物列表</h4>
|
||
<p class="text-gray-600">在左侧输入框添加食物,点击垃圾桶图标删除食物</p>
|
||
</div>
|
||
</li>
|
||
<li class="flex">
|
||
<div class="bg-primary/10 rounded-full p-2 mr-3">
|
||
<i class="fa-solid fa-play text-primary"></i>
|
||
</div>
|
||
<div>
|
||
<h4 class="font-bold">开始转盘</h4>
|
||
<p class="text-gray-600">点击转盘中心的"转"按钮开始随机选择</p>
|
||
</div>
|
||
</li>
|
||
<li class="flex">
|
||
<div class="bg-primary/10 rounded-full p-2 mr-3">
|
||
<i class="fa-solid fa-history text-primary"></i>
|
||
</div>
|
||
<div>
|
||
<h4 class="font-bold">查看历史</h4>
|
||
<p class="text-gray-600">右侧面板会记录最近的选择结果</p>
|
||
</div>
|
||
</li>
|
||
<li class="flex">
|
||
<div class="bg-primary/10 rounded-full p-2 mr-3">
|
||
<i class="fa-solid fa-star text-primary"></i>
|
||
</div>
|
||
<div>
|
||
<h4 class="font-bold">隐藏彩蛋</h4>
|
||
<p class="text-gray-600">连续两次选中同一食物会触发爱心特效,连续三次选中同一食物会触发超级彩蛋!</p>
|
||
</div>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
<div class="bg-gray-50 p-4 text-center">
|
||
<button id="gotItBtn" class="bg-primary text-white px-6 py-2 rounded-lg hover:bg-primary/90 transition-colors">
|
||
知道了
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 爱心容器 -->
|
||
<div id="heartsContainer" class="fixed inset-0 pointer-events-none z-40 hidden"></div>
|
||
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// 获取元素
|
||
const canvas = document.getElementById('wheelCanvas');
|
||
const ctx = canvas.getContext('2d');
|
||
const spinBtn = document.getElementById('spinBtn');
|
||
const foodList = document.getElementById('foodList');
|
||
const newFoodInput = document.getElementById('newFoodInput');
|
||
const addFoodBtn = document.getElementById('addFoodBtn');
|
||
const resultDisplay = document.getElementById('resultDisplay');
|
||
const resultText = document.getElementById('resultText');
|
||
const historyList = document.getElementById('historyList');
|
||
const clearHistoryBtn = document.getElementById('clearHistoryBtn');
|
||
const helpBtn = document.getElementById('helpBtn');
|
||
const helpModal = document.getElementById('helpModal');
|
||
const closeHelpBtn = document.getElementById('closeHelpBtn');
|
||
const gotItBtn = document.getElementById('gotItBtn');
|
||
const heartsContainer = document.getElementById('heartsContainer');
|
||
|
||
// 设置Canvas尺寸
|
||
const setCanvasSize = () => {
|
||
const container = canvas.parentElement;
|
||
const size = Math.min(container.clientWidth, container.clientHeight);
|
||
canvas.width = size;
|
||
canvas.height = size;
|
||
};
|
||
|
||
setCanvasSize();
|
||
window.addEventListener('resize', setCanvasSize);
|
||
|
||
// 食物数据
|
||
let foods = ['烤鸭', '红烧肉', '炒茄子', '汉堡', '奶茶']; // 修改了食物列表
|
||
let isSpinning = false;
|
||
let rotation = 0;
|
||
let resultIndex = 0;
|
||
let animationId = null;
|
||
|
||
// 历史记录
|
||
let history = [];
|
||
|
||
// 连续选择记录
|
||
let consecutiveResults = [];
|
||
|
||
// 绘制转盘
|
||
const drawWheel = () => {
|
||
const centerX = canvas.width / 2;
|
||
const centerY = canvas.height / 2;
|
||
const radius = Math.min(centerX, centerY) - 20;
|
||
|
||
// 清除画布
|
||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||
|
||
// 如果没有食物,显示提示
|
||
if (foods.length === 0) {
|
||
ctx.fillStyle = '#f0f0f0';
|
||
ctx.beginPath();
|
||
ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
|
||
ctx.fill();
|
||
|
||
ctx.fillStyle = '#999';
|
||
ctx.font = 'bold 16px Inter';
|
||
ctx.textAlign = 'center';
|
||
ctx.textBaseline = 'middle';
|
||
ctx.fillText('请添加食物', centerX, centerY);
|
||
return;
|
||
}
|
||
|
||
// 计算每个扇形的角度
|
||
const sliceAngle = (Math.PI * 2) / foods.length;
|
||
|
||
// 颜色数组
|
||
const colors = [
|
||
'#FF6B6B', '#4ECDC4', '#FFD166', '#6A0572', '#1A936F',
|
||
'#F7B801', '#E63946', '#457B9D', '#1D3557', '#A8DADC'
|
||
];
|
||
|
||
// 绘制每个扇形
|
||
foods.forEach((food, index) => {
|
||
const color = colors[index % colors.length];
|
||
const startAngle = sliceAngle * index + rotation;
|
||
const endAngle = startAngle + sliceAngle;
|
||
|
||
// 绘制扇形
|
||
ctx.fillStyle = color;
|
||
ctx.beginPath();
|
||
ctx.moveTo(centerX, centerY);
|
||
ctx.arc(centerX, centerY, radius, startAngle, endAngle);
|
||
ctx.closePath();
|
||
ctx.fill();
|
||
|
||
// 添加边框
|
||
ctx.strokeStyle = '#fff';
|
||
ctx.lineWidth = 2;
|
||
ctx.stroke();
|
||
|
||
// 绘制文字
|
||
ctx.save();
|
||
ctx.translate(centerX, centerY);
|
||
ctx.rotate(startAngle + sliceAngle / 2);
|
||
|
||
ctx.fillStyle = '#fff';
|
||
ctx.font = 'bold 14px Inter';
|
||
ctx.textAlign = 'center';
|
||
ctx.fillText(food, radius * 0.7, 0);
|
||
|
||
ctx.restore();
|
||
});
|
||
|
||
// 绘制中心圆
|
||
ctx.fillStyle = '#fff';
|
||
ctx.beginPath();
|
||
ctx.arc(centerX, centerY, 30, 0, Math.PI * 2);
|
||
ctx.fill();
|
||
};
|
||
|
||
// 旋转转盘
|
||
const spinWheel = () => {
|
||
// 修复:检查动画ID并取消现有动画
|
||
if (animationId) {
|
||
cancelAnimationFrame(animationId);
|
||
}
|
||
|
||
if (isSpinning || foods.length < 2) return;
|
||
|
||
isSpinning = true;
|
||
resultDisplay.style.opacity = '0';
|
||
|
||
// 优化:根据食物数量调整旋转速度和圈数
|
||
const baseSpins = 3;
|
||
const spinVariation = Math.floor(Math.random() * 4) + 2;
|
||
const totalSpins = baseSpins + spinVariation;
|
||
|
||
// 优化:根据食物数量调整动画持续时间
|
||
const baseDuration = 2000;
|
||
const durationVariation = 1000;
|
||
const spinDuration = baseDuration + (foods.length * 200) + Math.random() * durationVariation;
|
||
|
||
const randomRotation = Math.random() * Math.PI * 2;
|
||
const targetRotation = rotation + totalSpins * Math.PI * 2 + randomRotation;
|
||
|
||
// 计算结果索引
|
||
const normalizedRotation = targetRotation % (Math.PI * 2);
|
||
const sliceAngle = (Math.PI * 2) / foods.length;
|
||
resultIndex = Math.floor((Math.PI * 2 - normalizedRotation) / sliceAngle) % foods.length;
|
||
|
||
// 动画旋转
|
||
let startTime = null;
|
||
|
||
const animateSpin = (timestamp) => {
|
||
if (!startTime) startTime = timestamp;
|
||
const progress = (timestamp - startTime) / spinDuration;
|
||
|
||
if (progress < 1) {
|
||
// 使用缓动函数使旋转减速
|
||
const easeOut = 1 - Math.pow(1 - progress, 3);
|
||
rotation = rotation + (targetRotation - rotation) * easeOut * (timestamp - startTime) / 16;
|
||
drawWheel();
|
||
animationId = requestAnimationFrame(animateSpin);
|
||
} else {
|
||
rotation = targetRotation;
|
||
drawWheel();
|
||
isSpinning = false;
|
||
animationId = null;
|
||
|
||
// 显示结果
|
||
setTimeout(() => {
|
||
resultText.textContent = foods[resultIndex];
|
||
resultDisplay.classList.add('result-appear');
|
||
resultDisplay.style.opacity = '1';
|
||
|
||
// 添加到历史记录
|
||
addToHistory(foods[resultIndex]);
|
||
|
||
// 检查连续选择
|
||
checkConsecutiveResults(foods[resultIndex]);
|
||
}, 500);
|
||
}
|
||
};
|
||
|
||
animationId = requestAnimationFrame(animateSpin);
|
||
};
|
||
|
||
// 添加食物
|
||
const addFood = () => {
|
||
const foodName = newFoodInput.value.trim();
|
||
if (foodName && !foods.includes(foodName)) {
|
||
foods.push(foodName);
|
||
newFoodInput.value = '';
|
||
updateFoodList();
|
||
drawWheel();
|
||
} else if (foods.includes(foodName)) {
|
||
newFoodInput.classList.add('border-red-500');
|
||
setTimeout(() => {
|
||
newFoodInput.classList.remove('border-red-500');
|
||
}, 1000);
|
||
}
|
||
};
|
||
|
||
// 更新食物列表
|
||
const updateFoodList = () => {
|
||
foodList.innerHTML = '';
|
||
|
||
if (foods.length === 0) {
|
||
const emptyState = document.createElement('div');
|
||
emptyState.className = 'text-center text-gray-500 italic py-4';
|
||
emptyState.textContent = '食物列表为空';
|
||
foodList.appendChild(emptyState);
|
||
return;
|
||
}
|
||
|
||
foods.forEach((food, index) => {
|
||
const foodItem = document.createElement('div');
|
||
foodItem.className = 'food-item flex items-center justify-between p-3 bg-gray-50 rounded-lg hover:bg-gray-100 transition-all';
|
||
|
||
const foodName = document.createElement('span');
|
||
foodName.textContent = food;
|
||
|
||
const deleteBtn = document.createElement('button');
|
||
deleteBtn.className = 'delete-btn text-red-400 hover:text-red-600 transition-colors';
|
||
deleteBtn.innerHTML = '<i class="fa-solid fa-trash"></i>';
|
||
deleteBtn.addEventListener('click', () => {
|
||
// 如果删除的是当前结果,重置结果显示
|
||
if (index === resultIndex) {
|
||
resultDisplay.style.opacity = '0';
|
||
}
|
||
|
||
foods.splice(index, 1);
|
||
updateFoodList();
|
||
drawWheel();
|
||
});
|
||
|
||
foodItem.appendChild(foodName);
|
||
foodItem.appendChild(deleteBtn);
|
||
foodList.appendChild(foodItem);
|
||
});
|
||
};
|
||
|
||
// 添加到历史记录
|
||
const addToHistory = (food) => {
|
||
const now = new Date();
|
||
const timeString = now.toLocaleTimeString();
|
||
|
||
history.unshift({
|
||
food,
|
||
time: timeString
|
||
});
|
||
|
||
// 限制历史记录数量
|
||
if (history.length > 10) {
|
||
history.pop();
|
||
}
|
||
|
||
updateHistoryList();
|
||
};
|
||
|
||
// 更新历史记录列表
|
||
const updateHistoryList = () => {
|
||
historyList.innerHTML = '';
|
||
|
||
if (history.length === 0) {
|
||
const emptyState = document.createElement('div');
|
||
emptyState.className = 'text-center text-gray-500 italic';
|
||
emptyState.textContent = '暂无记录';
|
||
historyList.appendChild(emptyState);
|
||
return;
|
||
}
|
||
|
||
history.forEach((item) => {
|
||
const historyItem = document.createElement('div');
|
||
historyItem.className = 'flex items-center justify-between p-3 border-b border-gray-100 last:border-0';
|
||
|
||
const foodContainer = document.createElement('div');
|
||
|
||
const foodName = document.createElement('p');
|
||
foodName.className = 'font-medium';
|
||
foodName.textContent = item.food;
|
||
|
||
const time = document.createElement('p');
|
||
time.className = 'text-sm text-gray-500';
|
||
time.textContent = item.time;
|
||
|
||
foodContainer.appendChild(foodName);
|
||
foodContainer.appendChild(time);
|
||
|
||
historyItem.appendChild(foodContainer);
|
||
historyList.appendChild(historyItem);
|
||
});
|
||
};
|
||
|
||
// 清空历史记录
|
||
const clearHistory = () => {
|
||
history = [];
|
||
updateHistoryList();
|
||
};
|
||
|
||
// 打开帮助模态框
|
||
const openHelpModal = () => {
|
||
helpModal.classList.remove('hidden');
|
||
helpModal.classList.add('flex');
|
||
document.body.style.overflow = 'hidden';
|
||
};
|
||
|
||
// 关闭帮助模态框
|
||
const closeHelpModal = () => {
|
||
helpModal.classList.add('hidden');
|
||
helpModal.classList.remove('flex');
|
||
document.body.style.overflow = '';
|
||
};
|
||
|
||
// 检查连续选择
|
||
const checkConsecutiveResults = (food) => {
|
||
// 添加到连续选择数组
|
||
consecutiveResults.push(food);
|
||
|
||
// 限制数组长度为3
|
||
if (consecutiveResults.length > 3) {
|
||
consecutiveResults.shift();
|
||
}
|
||
|
||
// 检查是否连续两次相同
|
||
if (consecutiveResults.length >= 2 &&
|
||
consecutiveResults[consecutiveResults.length - 1] === consecutiveResults[consecutiveResults.length - 2]) {
|
||
|
||
// 触发爱心特效
|
||
createHearts(food);
|
||
|
||
// 如果连续三次相同,触发彩蛋
|
||
if (consecutiveResults.length === 3 &&
|
||
consecutiveResults[0] === consecutiveResults[1] &&
|
||
consecutiveResults[1] === consecutiveResults[2]) {
|
||
|
||
triggerEasterEgg(food);
|
||
}
|
||
}
|
||
};
|
||
|
||
// 创建爱心特效
|
||
const createHearts = (food) => {
|
||
heartsContainer.innerHTML = '';
|
||
heartsContainer.classList.remove('hidden');
|
||
|
||
// 创建100个爱心
|
||
for (let i = 0; i < 100; i++) {
|
||
setTimeout(() => {
|
||
const heart = document.createElement('div');
|
||
heart.className = 'heart-fall absolute text-primary';
|
||
heart.style.left = `${Math.random() * 100}vw`;
|
||
heart.style.fontSize = `${16 + Math.random() * 24}px`;
|
||
heart.style.animationDuration = `${2 + Math.random() * 3}s`;
|
||
heart.style.opacity = `${0.5 + Math.random() * 0.5}`;
|
||
|
||
// 50%概率是爱心,50%概率是食物名称
|
||
if (Math.random() > 0.5) {
|
||
heart.innerHTML = '❤️';
|
||
} else {
|
||
heart.innerHTML = food;
|
||
}
|
||
|
||
heartsContainer.appendChild(heart);
|
||
|
||
// 动画结束后移除
|
||
setTimeout(() => {
|
||
heart.remove();
|
||
}, 5000);
|
||
}, i * 30);
|
||
}
|
||
|
||
// 3秒后隐藏容器
|
||
setTimeout(() => {
|
||
heartsContainer.classList.add('hidden');
|
||
}, 5000);
|
||
};
|
||
|
||
// 触发彩蛋
|
||
const triggerEasterEgg = (food) => {
|
||
// 显示提示
|
||
alert(`恭喜触发彩蛋!看来你真的很想吃${food},那就别犹豫啦!`);
|
||
|
||
// 把转盘上所有选项都变成这个食物
|
||
const originalFoods = [...foods];
|
||
foods = Array(foods.length).fill(food);
|
||
|
||
// 重新绘制转盘
|
||
drawWheel();
|
||
|
||
// 3秒后恢复原来的食物列表
|
||
setTimeout(() => {
|
||
foods = originalFoods;
|
||
drawWheel();
|
||
}, 3000);
|
||
};
|
||
|
||
// 事件监听
|
||
spinBtn.addEventListener('click', spinWheel);
|
||
addFoodBtn.addEventListener('click', addFood);
|
||
newFoodInput.addEventListener('keypress', (e) => {
|
||
if (e.key === 'Enter') addFood();
|
||
});
|
||
clearHistoryBtn.addEventListener('click', clearHistory);
|
||
helpBtn.addEventListener('click', openHelpModal);
|
||
closeHelpBtn.addEventListener('click', closeHelpModal);
|
||
gotItBtn.addEventListener('click', closeHelpModal);
|
||
|
||
// 点击模态框外部关闭
|
||
helpModal.addEventListener('click', (e) => {
|
||
if (e.target === helpModal) {
|
||
closeHelpModal();
|
||
}
|
||
});
|
||
|
||
// 初始化
|
||
updateFoodList();
|
||
updateHistoryList();
|
||
drawWheel();
|
||
|
||
// 修复:添加resize事件处理
|
||
window.addEventListener('resize', () => {
|
||
setCanvasSize();
|
||
drawWheel();
|
||
});
|
||
});
|
||
</script>
|
||
</body>
|
||
</html> |