吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 828|回复: 22
上一主题 下一主题
收起左侧

[其他原创] 【HTML】【已更新】美食大转盘 - 点餐助手4.0

[复制链接]
跳转到指定楼层
楼主
小乖乖 发表于 2025-12-25 14:59 回帖奖励
本帖最后由 小乖乖 于 2026-1-1 20:44 编辑



更新了一下,让大转盘更加完善一些
这个版本的美食大转盘支持两种开始点餐方式
  • 点击"开始点餐"按钮
  • 按空格键(当不在输入框中且没有弹窗时)
  • 左上角增加菜单隐藏显示功能
  • 选定美食后有烟花效果
  • 打开默认隐藏设置美食窗口,左上角有设置按钮
  • 修复了一些bug

[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>
    <style>
        /* 全局样式变量 */
        :root {
            --primary-color: #ff6b6b;
            --primary-light: #ff8e8e;
            --secondary-color: #ffd93d;
            --accent-color: #6c5ce7;
            --danger-color: #ff3838;
            --warning-color: #ff9f1a;
            --text-primary: #2d3436;
            --text-secondary: #636e72;
            --bg-gradient: linear-gradient(135deg, #fdfcfb 0%, #e2d1c3 100%);
        }
        
        /* 左上角控制栏 - 悬停显示 */
        .top-controls-area {
            position: fixed;
            top: 0;
            left: 0;
            width: 40px;
            height: 40px;
            z-index: 1000;
            transition: all 0.3s ease;
            border-radius: 0 0 20px 0;
            overflow: hidden;
        }
        
        .top-controls-area:hover {
            width: 220px;
            height: 90px;
            background: rgba(255, 255, 255, 0.9);
            backdrop-filter: blur(10px);
            box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
            border: 1px solid rgba(255, 107, 107, 0.2);
        }
        
        .top-controls {
            display: flex;
            gap: 0.75rem;
            padding: 0.75rem;
            opacity: 0;
            transform: translateX(-100%);
            transition: all 0.3s ease 0.1s;
            width: 100%;
            height: 100%;
            align-items: center;
            justify-content: center;
            flex-wrap: wrap;
        }
        
        .top-controls-area:hover .top-controls {
            opacity: 1;
            transform: translateX(0);
        }
        
        /* 悬停提示区域 */
        .hover-trigger {
            position: absolute;
            top: 0;
            left: 0;
            width: 40px;
            height: 40px;
            display: flex;
            align-items: center;
            justify-content: center;
            background: rgba(255, 255, 255, 0.1);
            border-radius: 0 0 20px 0;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .hover-trigger:hover {
            background: rgba(255, 107, 107, 0.1);
        }
        
        .hover-trigger::before {
            content: "&#8942;&#8942;";
            font-size: 16px;
            font-weight: bold;
            color: var(--primary-color);
            transform: rotate(90deg);
        }
        
        /* 控制栏按钮样式调整 */
        .top-controls .btn {
            padding: 0.6rem 1rem;
            font-size: 0.9rem;
            min-width: 90px;
            flex: 1;
            max-width: 100px;
        }
        
        @media (max-width: 768px) {
            .top-controls-area {
                width: 35px;
                height: 35px;
            }
            
            .top-controls-area:hover {
                width: 180px;
                height: 80px;
            }
            
            .hover-trigger::before {
                font-size: 14px;
            }
            
            .top-controls .btn {
                padding: 0.5rem 0.8rem;
                font-size: 0.8rem;
                min-width: 80px;
                max-width: 85px;
            }
        }
        
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
  
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            min-height: 100vh;
            background: var(--bg-gradient);
            padding: 1rem;
            color: var(--text-primary);
            line-height: 1.6;
        }
  
        .container {
            max-width: 1200px;
            margin: 0 auto;
        }
  
        .header {
            text-align: center;
            margin-bottom: 2rem;
            padding-bottom: 1.5rem;
        }
  
        .header h1 {
            font-size: clamp(2rem, 5vw, 3rem);
            font-weight: 800;
            color: var(--text-primary);
            margin: 0.5rem 0;
        }
  
        .header p {
            color: var(--text-secondary);
            font-size: 1.2rem;
            margin-top: 1rem;
            max-width: 600px;
            margin-left: auto;
            margin-right: auto;
        }
        
        .shortcut-hint {
            display: inline-block;
            background: linear-gradient(135deg, #ff6b6b 0%, #ff8e8e 100%);
            color: white;
            padding: 0.5rem 1.5rem;
            border-radius: 50px;
            font-size: 0.9rem;
            margin-top: 0.5rem;
        }
  
        .main-grid {
            display: grid;
            grid-template-columns: 350px 1fr;
            gap: 2rem;
            align-items: start;
        }
        
        .main-grid.menu-empty {
            grid-template-columns: 1fr;
        }
        
        .main-grid.menu-empty .list-panel {
            display: none;
        }
        
        @media (max-width: 900px) {
            .main-grid {
                grid-template-columns: 1fr;
            }
            
            .main-grid.menu-empty .list-panel {
                display: none;
            }
            
            .main-grid .list-panel { 
                order: 2; 
            }
            .main-grid .wheel-panel { 
                order: 1; 
            }
        }
  
        .panel {
            background: rgba(255, 255, 255, 0.95);
            border-radius: 20px;
            padding: 1.5rem;
            border: none;
            box-shadow: 0 15px 35px rgba(0, 0, 0, 0.2);
            position: relative;
            overflow: hidden;
        }
        
        .panel::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 5px;
            background: linear-gradient(135deg, #ff6b6b 0%, #ff8e8e 100%);
        }
  
        .panel-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-bottom: 1.5rem;
            padding-bottom: 1rem;
        }
  
        .panel-header h2 {
            font-size: 1.5rem;
            font-weight: 700;
            color: var(--text-primary);
            display: flex;
            align-items: center;
            gap: 0.5rem;
        }
        
        .count-badge {
            font-size: 0.85rem;
            font-weight: 700;
            color: white;
            background: linear-gradient(135deg, #ff6b6b 0%, #ff8e8e 100%);
            padding: 0.3rem 0.8rem;
            border-radius: 20px;
            box-shadow: 0 4px 8px rgba(255, 107, 107, 0.3);
        }
  
        .input-group {
            margin-bottom: 1.5rem;
        }
  
        .input-label {
            color: var(--text-primary);
            margin-bottom: 0.5rem;
            display: block;
            font-weight: 600;
        }
  
        .input-row {
            display: flex;
            gap: 0.75rem;
        }
  
        input, textarea {
            background: white;
            border: 2px solid rgba(255, 107, 107, 0.2);
            border-radius: 12px;
            padding: 0.85rem 1.2rem;
            color: var(--text-primary);
            outline: none;
            transition: all 0.3s;
            width: 100%;
            font-size: 1rem;
        }
  
        input:focus, textarea:focus {
            border-color: var(--primary-color);
            box-shadow: 0 0 0 3px rgba(255, 107, 107, 0.2);
        }
  
        .input-row input {
            flex: 1;
        }
  
        .btn {
            padding: 0.85rem 1.5rem;
            border: none;
            border-radius: 12px;
            font-weight: 700;
            cursor: pointer;
            transition: all 0.3s;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: 0.5rem;
            font-size: 1rem;
            position: relative;
            overflow: hidden;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
        }
        
        .btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
        }
  
        .btn-primary {
            background: linear-gradient(135deg, #ff6b6b 0%, #ff8e8e 100%);
            color: white;
        }
  
        .btn-primary:hover:not(:disabled) {
            transform: translateY(-3px);
            box-shadow: 0 8px 20px rgba(255, 107, 107, 0.4);
        }
  
        .btn-success {
            background: linear-gradient(135deg, #ffd93d 0%, #ffed6b 100%);
            color: var(--text-primary);
        }
        
        .btn-secondary {
            background: white;
            color: var(--text-primary);
            border: 2px solid rgba(255, 107, 107, 0.2);
        }
        
        .btn-danger {
            background: linear-gradient(135deg, #ff3838 0%, #ff6b6b 100%);
            color: white;
        }
        
        .btn-danger:hover:not(:disabled) {
            transform: translateY(-3px);
            box-shadow: 0 8px 20px rgba(255, 56, 56, 0.4);
        }
        
        .btn-warning {
            background: linear-gradient(135deg, #ff9f1a 0%, #ffd93d 100%);
            color: var(--text-primary);
        }
        
        .btn-info {
            background: linear-gradient(135deg, #6c5ce7 0%, #a29bfe 100%);
            color: white;
        }
        
        .btn-info:hover:not(:disabled) {
            transform: translateY(-3px);
            box-shadow: 0 8px 20px rgba(108, 92, 231, 0.4);
        }
  
        .punishment-list {
            max-height: 400px;
            overflow-y: auto;
            margin-bottom: 1.5rem;
            padding-right: 0.5rem;
        }
  
        .punishment-item {
            background: white;
            padding: 1.2rem;
            border-radius: 12px;
            margin-bottom: 0.75rem;
            display: flex;
            justify-content: space-between;
            align-items: center;
            transition: all 0.3s;
            color: var(--text-primary);
            border: 2px solid transparent;
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
        }
  
        .punishment-item:hover {
            background: #f9f9f9;
            transform: translateX(8px);
            box-shadow: 0 6px 15px rgba(0, 0, 0, 0.2);
        }
  
        .punishment-item .remove-btn {
            background: transparent;
            border: 2px solid rgba(255, 107, 107, 0.2);
            color: #b2bec3;
            cursor: pointer;
            font-size: 1.2rem;
            width: 32px;
            height: 32px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.3s;
        }
  
        .punishment-item .remove-btn:hover {
            background: var(--danger-color);
            border-color: var(--danger-color);
            color: white;
            transform: rotate(90deg);
        }
        
        /* 菜品图标样式 - 保持原有样式 */
        .food-icon {
            font-size: 1.2rem;
            margin-right: 0.5rem;
            display: inline-block;
        }
        
        .food-name {
            font-size: 1rem;
            font-weight: 500;
        }

        /* 今日推荐图标样式 - 彩色图标 */
        .winner-icon {
            font-size: 2.2rem;
            margin-right: 0.75rem;
            display: inline-block;
            filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.2));
            animation: bounce 2s infinite;
            /* 确保图标有色彩,不使用背景裁剪 */
            color: inherit;
            background: none;
            -webkit-background-clip: initial;
            background-clip: initial;
        }
        
        @keyframes bounce {
            0%, 20%, 53%, 80%, 100% { transform: translateY(0); }
            40%, 43% { transform: translateY(-10px); }
            70% { transform: translateY(-5px); }
            90% { transform: translateY(-2px); }
        }

        /* 转盘上的菜品图标 - 保持原有样式 */
        .wheel-food-icon {
            font-size: 1.5rem;
            margin-bottom: 5px;
            display: block;
        }
  
        .wheel-container {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            width: 100%;
        }
  
        .wheel-wrapper {
            position: relative;
            margin-bottom: 2.5rem;
            width: 100%;
            max-width: 550px;
            aspect-ratio: 1/1;
        }
  
        .wheel-pointer {
            position: absolute;
            top: -20px;
            left: 50%;
            transform: translateX(-50%);
            z-index: 20;
            width: 50px;
            height: 50px;
            background: #ffd700;
            border: 4px solid white;
            border-radius: 50%;
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.5rem;
            color: var(--text-primary);
        }
        
        .wheel-pointer::after {
            content: '';
            position: absolute;
            top: 100%;
            left: 50%;
            transform: translateX(-50%);
            border-left: 12px solid transparent;
            border-right: 12px solid transparent;
            border-top: 18px solid #ffd700;
        }
  
        .wheel-svg {
            width: 100%;
            height: 100%;
            transition-property: transform;
            transition-timing-function: cubic-bezier(0.15, 0, 0.20, 1);
            filter: drop-shadow(0 10px 20px rgba(0, 0, 0, 0.2));
        }
        
        /* 中心固定区域 */
        .wheel-center {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            width: 120px;
            height: 120px;
            border-radius: 50%;
            background: radial-gradient(circle, #ffd700 0%, #ffa500 100%);
            border: 6px solid white;
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 24px;
            font-weight: bold;
            color: white;
            z-index: 10;
            pointer-events: none;
            text-shadow: 0 2px 3px rgba(0, 0, 0, 0.2);
        }
  
        .control-buttons {
            display: flex;
            gap: 1rem;
            margin-bottom: 2.5rem;
            flex-wrap: wrap;
            justify-content: center;
        }
  
        .result-display {
            background: linear-gradient(135deg, #ff9a9e 0%, #fad0c4 99%, #fad0c4 100%);
            color: var(--text-primary);
            padding: 2rem 3rem;
            border-radius: 20px;
            text-align: center;
            font-weight: 700;
            box-shadow: 0 15px 30px rgba(255, 154, 158, 0.4);
            min-width: 320px;
            transform: scale(0.9);
            opacity: 0;
            transition: all 0.5s;
        }
 
        .result-display.show {
            transform: scale(1);
            opacity: 1;
        }
  
        .result-display h3 {
            font-size: 1.5rem;
            margin-bottom: 0.75rem;
            color: var(--text-primary);
        }
         
        .result-display .punishment-text {
            font-size: 2rem;
            font-weight: 800;
            word-break: break-word;
            line-height: 1.4;
            /* 移除背景渐变,确保文字颜色正常 */
            color: var(--primary-color);
            display: flex;
            align-items: center;
            justify-content: center;
            flex-wrap: wrap;
        }
        
        .add-menu-prompt {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 3rem;
            background: rgba(255, 255, 255, 0.9);
            border-radius: 20px;
            margin-bottom: 2rem;
            text-align: center;
            border: 3px dashed var(--accent-color);
        }
        
        .add-menu-prompt h3 {
            background: linear-gradient(135deg, #ff6b6b 0%, #6c5ce7 100%);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
            margin-bottom: 1rem;
            font-size: 2rem;
        }
        
        .add-menu-prompt p {
            color: var(--text-secondary);
            margin-bottom: 2rem;
            max-width: 500px;
            font-size: 1.1rem;
        }
  
        .celebration-modal {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.8);
            z-index: 2000;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 1rem;
        }
  
        .celebration-content {
            background: white;
            border-radius: 30px;
            padding: 3rem;
            max-width: 35rem;
            width: 100%;
            text-align: center;
            position: relative;
            box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3);
            background: var(--bg-gradient);
            z-index: 100;
        }
  
        .celebration-close {
            position: absolute;
            top: 1.5rem;
            right: 1.5rem;
            width: 3rem;
            height: 3rem;
            background: white;
            border: 2px solid rgba(255, 107, 107, 0.2);
            border-radius: 50%;
            color: var(--text-secondary);
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.8rem;
            transition: all 0.3s;
            z-index: 101;
        }
  
        .celebration-close:hover {
            background: var(--primary-color);
            color: white;
            border-color: var(--primary-color);
        }
  
        .celebration-emoji {
            font-size: 5rem;
            margin-bottom: 1.5rem;
            display: block;
        }
  
        .celebration-title {
            font-size: 2.2rem;
            font-weight: 800;
            color: var(--text-primary);
            margin-bottom: 2rem;
            background: linear-gradient(135deg, #ff6b6b 0%, #6c5ce7 100%);
            -webkit-background-clip: text;
            background-clip: text;
            color: transparent;
        }
  
        .celebration-result-box {
            background: white;
            border-radius: 20px;
            padding: 2.5rem;
            margin-bottom: 2.5rem;
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
        }
  
        .celebration-result-label {
            font-size: 1.2rem;
            color: var(--text-secondary);
            margin-bottom: 0.75rem;
            font-weight: 600;
        }
 
        .celebration-result-text {
            font-size: 2.2rem;
            font-weight: 800;
            color: var(--primary-color);
            line-height: 1.3;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-wrap: wrap;
        }
  
        .celebration-btn {
            background: linear-gradient(135deg, #ff6b6b 0%, #ff8e8e 100%);
            color: white;
            border: none;
            padding: 1.2rem 4rem;
            border-radius: 15px;
            font-weight: 700;
            font-size: 1.2rem;
            cursor: pointer;
            transition: all 0.3s;
            box-shadow: 0 8px 20px rgba(255, 107, 107, 0.4);
            position: relative;
            z-index: 101;
        }
  
        .celebration-btn:hover {
            transform: translateY(-5px);
            box-shadow: 0 12px 25px rgba(255, 107, 107, 0.5);
        }
        
        /* 烟花画布 */
        .fireworks-canvas {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            pointer-events: none;
            z-index: 99;
        }
        
        .file-import-note {
            color: var(--text-secondary);
            font-size: 0.9rem;
            margin-top: 0.5rem;
            padding-left: 0.5rem;
        }
        
        .clear-all-section {
            display: flex;
            justify-content: flex-end;
            margin-top: 1.5rem;
            padding-top: 1.5rem;
        }
        
        .confirm-clear-modal {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.8);
            z-index: 2000;
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 1rem;
        }
        
        .confirm-clear-content {
            background: white;
            border-radius: 25px;
            padding: 3rem;
            max-width: 30rem;
            width: 100%;
            text-align: center;
            position: relative;
            box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3);
            background: var(--bg-gradient);
        }
        
        .confirm-clear-icon {
            font-size: 4rem;
            margin-bottom: 1.5rem;
            display: block;
            color: var(--warning-color);
        }
        
        .confirm-clear-title {
            font-size: 1.8rem;
            font-weight: 800;
            color: var(--text-primary);
            margin-bottom: 1.2rem;
        }
        
        .confirm-clear-message {
            font-size: 1.1rem;
            color: var(--text-secondary);
            margin-bottom: 2.5rem;
            line-height: 1.6;
        }
        
        .confirm-clear-count {
            font-weight: 800;
            color: var(--danger-color);
            font-size: 1.5rem;
        }
        
        .confirm-clear-buttons {
            display: flex;
            gap: 1.2rem;
            justify-content: center;
        }
        
        .confirm-clear-btn {
            padding: 1rem 2.5rem;
            border: none;
            border-radius: 12px;
            font-weight: 700;
            font-size: 1.1rem;
            cursor: pointer;
            transition: all 0.3s;
            min-width: 140px;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
        }
        
        .confirm-clear-btn.confirm {
            background: linear-gradient(135deg, #ffd93d 0%, #ffed6b 100%);
            color: var(--text-primary);
        }
        
        .confirm-clear-btn.confirm:hover {
            transform: translateY(-3px);
            box-shadow: 0 8px 20px rgba(255, 217, 61, 0.4);
        }
        
        .confirm-clear-btn.cancel {
            background: white;
            color: var(--text-primary);
            border: 2px solid rgba(255, 107, 107, 0.2);
        }
        
        .confirm-clear-btn.cancel:hover {
            background: #f8f9fa;
            transform: translateY(-3px);
            box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
        }
  
        .hidden {
            display: none;
        }
        
        @media (max-width: 768px) {
            .panel {
                padding: 1.5rem;
            }
            
            .header h1 {
                font-size: clamp(1.8rem, 5vw, 2.5rem);
            }
            
            .header p {
                font-size: 1.1rem;
            }
            
            .control-buttons {
                flex-direction: column;
                align-items: center;
            }
            
            .btn {
                width: 100%;
                max-width: 300px;
            }
            
            .celebration-content {
                padding: 2rem;
            }
            
            .celebration-title {
                font-size: 1.8rem;
            }
            
            .celebration-result-text {
                font-size: 1.8rem;
            }
            
            .confirm-clear-content {
                padding: 2rem;
            }
            
            .add-menu-prompt {
                padding: 2rem;
            }
            
            .result-display {
                min-width: auto;
                width: 100%;
                padding: 1.5rem;
            }
            
            .result-display .punishment-text {
                font-size: 1.8rem;
            }
            
            .winner-icon {
                font-size: 1.8rem;
                margin-right: 0.5rem;
            }
            
            .wheel-center {
                width: 100px;
                height: 100px;
                font-size: 20px;
            }
        }
    </style>
</head>
<body>
    <!-- 左上角控制栏 - 悬停显示 -->
    <div class="top-controls-area">
        <div class="hover-trigger"></div>
        <div class="top-controls">
            <button class="btn btn-primary" id="themeToggleBtn">
                <span>切换主题</span>
            </button>
            <button class="btn btn-info" id="menuToggleBtn">
                <span>显示菜单</span>
            </button>
        </div>
    </div>
    
    <div class="container">
        <!-- 头部标题 -->
        <div class="header">
            <h1>美食大转盘</h1>
            <p>还在为"吃什么"发愁吗?让转盘帮你决定今天的美食!</p>
            <div class="shortcut-hint">&#128161; 提示:按空格键可以快速开始点餐</div>
        </div>
  
        <div class="main-grid" id="mainGrid">
            <!-- 菜品管理面板 -->
            <div class="panel list-panel">
                <div class="panel-header">
                    <div style="display: flex; align-items: center; gap: 0.5rem;">
                        <h2>我的美食菜单</h2>
                        <div class="count-badge" id="punishmentCount">0项</div>
                    </div>
                    <button class="btn btn-danger" id="clearAllPunishmentsBtn">
                        一键清空
                    </button>
                </div>
                  
                <div class="input-group">
                    <label class="input-label">添加新菜品:</label>
                    <div class="input-row">
                        <input type="text" id="punishmentInput" placeholder="例如:麻辣香锅、披萨、寿司..." autocomplete="off">
                        <button class="btn btn-primary" id="addPunishmentBtn">
                            添加
                        </button>
                    </div>
                </div>
                
                <!-- 文件导入功能 -->
                <div class="input-group">
                    <label class="input-label">导入菜品列表(TXT文件):</label>
                    <div class="input-row">
                        <input type="file" id="importFile" accept=".txt" style="flex: 1; padding: 0.5rem;">
                        <button class="btn btn-secondary" id="importBtn">
                            导入
                        </button>
                    </div>
                    <div class="file-import-note">
                        每行一个菜品,支持批量导入
                    </div>
                </div>
  
                <div class="punishment-list" id="punishmentList">
                    <!-- 菜品项目动态加载 -->
                </div>
                
                <div class="clear-all-section">
                    <button class="btn btn-warning" id="resetToDefaultBtn">
                        恢复默认菜单
                    </button>
                </div>
            </div>
  
            <!-- 转盘控制面板 -->
            <div class="panel wheel-panel">
                <div class="wheel-container">
                    <!-- 当菜单为空时的提示 -->
                    <div id="addMenuPrompt" class="add-menu-prompt hidden">
                        <h3>菜单空空如也</h3>
                        <p>请先添加一些菜品到菜单中,然后就可以使用转盘点餐了!</p>
                        <div style="display: flex; gap: 1rem; flex-wrap: wrap; justify-content: center;">
                            <button class="btn btn-info" id="showMenuPanelBtn">
                                显示菜单面板
                            </button>
                            <button class="btn btn-primary" id="addFirstItemBtn">
                                添加第一个菜品
                            </button>
                            <button class="btn btn-secondary" id="importQuickBtn">
                                快速导入
                            </button>
                        </div>
                    </div>
                    
                    <div class="wheel-wrapper">
                        <!-- 转盘指针 -->
                        <div class="wheel-pointer">&#10148;</div>
                        <!-- SVG转盘 -->
                        <svg id="wheelSvg" class="wheel-svg" viewBox="-250 -250 500 500">
                            <defs>
                                <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
                                    <feDropShadow dx="0" dy="0" stdDeviation="8" flood-color="rgba(0,0,0,0.2)"/>
                                </filter>
                            </defs>
                            <!-- 转盘扇形区域(动态生成) -->
                            <g id="wheelSections"></g>
                        </svg>
                        <!-- 固定不动的中心区域 -->
                        <div class="wheel-center">点餐</div>
                    </div>
  
                    <!-- 控制按钮区域 -->
                    <div class="control-buttons">
                        <button class="btn btn-primary" id="startBtn" style="min-width: 180px; padding: 1.2rem;">
                            <span id="startBtnText">开始点餐</span>
                        </button>
                        <button class="btn btn-secondary" id="resetBtn" style="padding: 1.2rem;">
                            重置转盘
                        </button>
                    </div>
  
                    <!-- 结果展示区域 -->
                    <div id="resultDisplay" class="result-display">
                        <h3>今日推荐</h3>
                        <div class="punishment-text" id="winnerPunishment">
                            <span class="winner-icon">&#127869;&#65039;</span>
                            <span>等待选择...</span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
 
    <!-- 庆祝弹窗 -->
    <div id="celebrationModal" class="celebration-modal hidden">
        <!-- 烟花画布 -->
        <canvas id="fireworksCanvas" class="fireworks-canvas"></canvas>
        
        <div class="celebration-content">
            <button class="celebration-close" id="closeCelebrationBtn">×</button>
            <div class="celebration-inner">
                <span class="celebration-emoji">&#127869;&#65039;</span>
                <h2 class="celebration-title">今日美食已选定!</h2>
                  
                <div class="celebration-result-box">
                    <div class="celebration-result-label">转盘推荐:</div>
                    <div class="celebration-result-text" id="celebrationPunishment">
                        <span class="winner-icon">&#127869;&#65039;</span>
                        <span>等待选择...</span>
                    </div>
                </div>
  
                <button class="celebration-btn" id="confirmCelebrationBtn">
                    确定
                </button>
            </div>
        </div>
    </div>
    
    <!-- 一键清空确认弹窗 -->
    <div id="confirmClearModal" class="confirm-clear-modal hidden">
        <div class="confirm-clear-content">
            <span class="confirm-clear-icon">&#9888;&#65039;</span>
            <h2 class="confirm-clear-title">确认清空菜单</h2>
            <div class="confirm-clear-message">
                您确定要清空所有 <span class="confirm-clear-count" id="clearCount">0</span> 个菜品吗?<br>
                此操作无法撤销,所有自定义和导入的菜品将被永久删除。
            </div>
            <div class="confirm-clear-buttons">
                <button class="confirm-clear-btn cancel" id="cancelClearBtn">
                    取消
                </button>
                <button class="confirm-clear-btn confirm" id="confirmClearBtn">
                    确定清空
                </button>
            </div>
        </div>
    </div>
  
    <script>
        // 默认菜品列表(带图标)
        const defaultPunishmentsWithIcons = [
            {name: '披萨', icon: '&#127829;'},
            {name: '汉堡', icon: '&#127828;'},
            {name: '拉面', icon: '&#127836;'},
            {name: '寿司', icon: '&#127843;'},
            {name: '麻辣香锅', icon: '&#129368;'},
            {name: '火锅', icon: '&#127858;'},
            {name: '沙拉', icon: '&#129367;'},
            {name: '咖喱饭', icon: '&#127835;'},
            {name: '便当', icon: '&#127857;'},
            {name: '三明治', icon: '&#129386;'},
            {name: '意大利面', icon: '&#127837;'},
            {name: '墨西哥卷饼', icon: '&#127791;'},
            {name: '饺子', icon: '&#129375;'},
            {name: '炸虾', icon: '&#127844;'},
            {name: '冰淇淋', icon: '&#127846;'}
        ];
        
        // 常用菜品图标映射
        const foodIcons = {
            '披萨': '&#127829;', '汉堡': '&#127828;', '拉面': '&#127836;', '寿司': '&#127843;', 
            '麻辣香锅': '&#129368;', '火锅': '&#127858;', '沙拉': '&#129367;', '咖喱饭': '&#127835;',
            '便当': '&#127857;', '三明治': '&#129386;', '意大利面': '&#127837;', '墨西哥卷饼': '&#127791;',
            '饺子': '&#129375;', '炸虾': '&#127844;', '冰淇淋': '&#127846;', '烧烤': '&#127842;',
            '炸鸡': '&#127831;', '牛排': '&#129385;', '米饭': '&#127834;', '面条': '&#127836;',
            '面包': '&#127838;', '蛋糕': '&#127856;', '甜甜圈': '&#127849;', '咖啡': '&#9749;',
            '茶': '&#127861;', '果汁': '&#129475;', '啤酒': '&#127866;', '红酒': '&#127863;',
            '鸡尾酒': '&#127864;', '水果': '&#127822;', '蔬菜': '&#129382;', '海鲜': '&#129438;',
            '烤肉': '&#129363;', '汤': '&#127858;', '炒饭': '&#127835;', '煎饺': '&#129375;',
            '寿司卷': '&#127843;', '天妇罗': '&#127844;', '章鱼烧': '&#128025;', '关东煮': '&#127842;',
            '拉面': '&#127836;', '乌冬面': '&#127836;', '荞麦面': '&#127836;', '冷面': '&#127836;',
            '炒面': '&#127836;', '拌面': '&#127836;', '刀削面': '&#127836;', '米粉': '&#127836;',
            '河粉': '&#127836;', '粉丝': '&#127836;', '米线': '&#127836;', '土豆粉': '&#127836;',
            '麻辣烫': '&#127858;', '串串香': '&#127842;', '烤鱼': '&#128031;', '水煮鱼': '&#128031;',
            '酸菜鱼': '&#128031;', '清蒸鱼': '&#128031;', '红烧肉': '&#129385;', '糖醋排骨': '&#129385;',
            '宫保鸡丁': '&#127831;', '麻婆豆腐': '&#129368;', '回锅肉': '&#129385;', '鱼香肉丝': '&#129385;',
            '东坡肉': '&#129385;', '叫花鸡': '&#127831;', '北京烤鸭': '&#129414;', '盐水鸭': '&#129414;',
            '烧鹅': '&#129414;', '白切鸡': '&#127831;', '口水鸡': '&#127831;', '辣子鸡': '&#127831;',
            '大盘鸡': '&#127831;', '椒盐虾': '&#127844;', '蒜蓉虾': '&#127844;', '油焖大虾': '&#127844;',
            '清蒸蟹': '&#129408;', '香辣蟹': '&#129408;', '小龙虾': '&#129438;', '生蚝': '&#129450;',
            '扇贝': '&#128026;', '海参': '&#127754;', '鲍鱼': '&#128026;', '鱼翅': '&#129416;',
            '燕窝': '&#128038;', '佛跳墙': '&#127858;', '四喜丸子': '&#129385;', '狮子头': '&#129385;',
            '梅菜扣肉': '&#129385;', '粉蒸肉': '&#129385;', '蚂蚁上树': '&#127836;', '毛血旺': '&#129368;',
            '夫妻肺片': '&#129385;', '蒜泥白肉': '&#129385;', '水煮肉片': '&#129385;', '酸汤肥牛': '&#129385;',
            '干锅牛蛙': '&#128056;', '干锅菜花': '&#129382;', '干锅土豆片': '&#129364;', '干锅千页豆腐': '&#129368;',
            '烤羊排': '&#129385;', '烤羊肉串': '&#127842;', '烤牛肉串': '&#127842;', '烤鸡翅': '&#127831;',
            '烤鱿鱼': '&#129425;', '烤生蚝': '&#129450;', '烤扇贝': '&#128026;', '烤茄子': '&#127814;',
            '烤玉米': '&#127805;', '烤红薯': '&#127840;', '煎饼果子': '&#129374;', '肉夹馍': '&#129369;',
            '凉皮': '&#129379;', '热干面': '&#127836;', '炸酱面': '&#127836;', '担担面': '&#127836;',
            '烩面': '&#127836;', '臊子面': '&#127836;', '油泼面': '&#127836;', '阳春面': '&#127836;',
            '葱油拌面': '&#127836;', '重庆小面': '&#127836;', '宜宾燃面': '&#127836;', '兰州拉面': '&#127836;',
            '山西刀削面': '&#127836;', '武汉热干面': '&#127836;', '北京炸酱面': '&#127836;', '四川担担面': '&#127836;',
            '陕西臊子面': '&#127836;', '河南烩面': '&#127836;', '江苏阳春面': '&#127836;', '上海葱油拌面': '&#127836;',
            '广东云吞面': '&#127836;', '福建沙县拌面': '&#127836;', '台湾牛肉面': '&#127836;', '香港车仔面': '&#127836;'
        };
        
        // 从默认菜品列表中提取名称
        const defaultPunishmentNames = defaultPunishmentsWithIcons.map(item => item.name);
        
        // 从LocalStorage加载数据
        let punishments = JSON.parse(localStorage.getItem('wheelPunishments')) || [...defaultPunishmentNames];
         
        // 转盘状态控制变量
        let isSpinning = false;
        let currentRotation = 0;
        let currentPunishment = '';
        
        // 菜单面板状态 - 默认设置为false(隐藏菜单)
        let menuVisible = false;
        
        // 主题状态
        let isLuxuryTheme = true;

        // 转盘扇形颜色列表
        const luxuryColors = [
            '#ff6b6b', '#ffd93d', '#6c5ce7', '#00b894', '#fd79a8',
            '#e17055', '#00cec9', '#a29bfe', '#fab1a0', '#74b9ff',
            '#55efc4', '#ffeaa7', '#dfe6e9', '#fd9644', '#9b59b6'
        ];
        
        const simpleColors = [
            '#4a90e2', '#50c878', '#ff8c42', '#9c5bdf', '#ff6b6b',
            '#20b2aa', '#ffa726', '#7e8c8d', '#e91e63', '#009688',
            '#673ab7', '#ff5722', '#795548', '#607d8b', '#3f51b5'
        ];
        
        // 当前使用的颜色数组
        let currentColors = luxuryColors;
        
        // 烟花效果相关变量
        let fireworks = [];
        let particles = [];
        let animationId = null;
        let canvas, ctx;
        
        // 烟花颜色
        const fireworkColors = [
            '#FF0000', '#FF4500', '#FFD700', '#00FF00', '#1E90FF',
            '#8A2BE2', '#FF1493', '#FF6B6B', '#FFD93D', '#6C5CE7'
        ];
        
        // 获取菜品图标
        function getFoodIcon(foodName) {
            // 首先检查是否有精确匹配的图标
            if (foodIcons[foodName]) {
                return foodIcons[foodName];
            }
            
            // 如果没有精确匹配,检查是否包含关键字
            for (const [key, icon] of Object.entries(foodIcons)) {
                if (foodName.includes(key)) {
                    return icon;
                }
            }
            
            // 默认图标
            return '&#127869;&#65039;';
        }
        
        // 获取转盘显示的菜品图标(特殊处理,只显示图标)
        function getWheelFoodIcon(foodName) {
            const icon = getFoodIcon(foodName);
            // 为转盘上的图标创建SVG文本
            return icon;
        }
        
        // 初始化烟花画布
        function initFireworks() {
            canvas = document.getElementById('fireworksCanvas');
            ctx = canvas.getContext('2d');
            
            // 设置画布尺寸
            function resizeCanvas() {
                canvas.width = window.innerWidth;
                canvas.height = window.innerHeight;
            }
            
            resizeCanvas();
            window.addEventListener('resize', resizeCanvas);
        }
        
        // 烟花粒子类
        class Particle {
            constructor(x, y, color) {
                this.x = x;
                this.y = y;
                this.color = color;
                this.velocity = {
                    x: (Math.random() - 0.5) * 10,
                    y: (Math.random() - 0.5) * 10
                };
                this.alpha = 1;
                this.decay = Math.random() * 0.02 + 0.01;
                this.size = Math.random() * 3 + 1;
                this.gravity = 0.1;
            }
            
            update() {
                this.velocity.y += this.gravity;
                this.x += this.velocity.x;
                this.y += this.velocity.y;
                this.alpha -= this.decay;
            }
            
            draw() {
                ctx.save();
                ctx.globalAlpha = this.alpha;
                ctx.fillStyle = this.color;
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
                ctx.fill();
                ctx.restore();
            }
        }
        
        // 烟花类
        class Firework {
            constructor(x, y) {
                this.x = x;
                this.y = y;
                this.color = fireworkColors[Math.floor(Math.random() * fireworkColors.length)];
                this.particles = [];
                this.exploded = false;
                
                // 创建爆炸粒子
                for (let i = 0; i < 100; i++) {
                    this.particles.push(new Particle(this.x, this.y, this.color));
                }
            }
            
            update() {
                if (!this.exploded) {
                    this.exploded = true;
                }
                
                for (let i = this.particles.length - 1; i >= 0; i--) {
                    this.particles[i].update();
                    
                    if (this.particles[i].alpha <= 0) {
                        this.particles.splice(i, 1);
                    }
                }
            }
            
            draw() {
                this.particles.forEach(particle => particle.draw());
            }
            
            isFinished() {
                return this.particles.length === 0;
            }
        }
        
        // 创建烟花
        function createFirework(x, y) {
            fireworks.push(new Firework(x, y));
        }
        
        // 随机创建烟花
        function createRandomFirework() {
            const x = Math.random() * canvas.width;
            const y = Math.random() * canvas.height * 0.5;
            createFirework(x, y);
        }
        
        // 在弹窗周围创建一圈烟花
        function createCelebrationFireworks() {
            const modal = document.getElementById('celebrationModal');
            const content = document.querySelector('.celebration-content');
            
            if (!modal || !content) return;
            
            const modalRect = modal.getBoundingClientRect();
            const contentRect = content.getBoundingClientRect();
            
            // 在弹窗周围创建烟花
            const positions = [
                // 左上角
                {x: contentRect.left - 50, y: contentRect.top - 50},
                // 右上角
                {x: contentRect.right + 50, y: contentRect.top - 50},
                // 左下角
                {x: contentRect.left - 50, y: contentRect.bottom + 50},
                // 右下角
                {x: contentRect.right + 50, y: contentRect.bottom + 50},
                // 上方中间
                {x: contentRect.left + contentRect.width / 2, y: contentRect.top - 100},
                // 下方中间
                {x: contentRect.left + contentRect.width / 2, y: contentRect.bottom + 100},
                // 左侧中间
                {x: contentRect.left - 100, y: contentRect.top + contentRect.height / 2},
                // 右侧中间
                {x: contentRect.right + 100, y: contentRect.top + contentRect.height / 2}
            ];
            
            positions.forEach(pos => {
                createFirework(pos.x, pos.y);
            });
            
            // 随机创建一些烟花
            setTimeout(() => {
                for (let i = 0; i < 5; i++) {
                    setTimeout(() => createRandomFirework(), i * 300);
                }
            }, 500);
        }
        
        // 动画循环
        function animateFireworks() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            
            // 更新和绘制所有烟花
            for (let i = fireworks.length - 1; i >= 0; i--) {
                fireworks[i].update();
                fireworks[i].draw();
                
                if (fireworks[i].isFinished()) {
                    fireworks.splice(i, 1);
                }
            }
            
            // 随机创建新烟花
            if (fireworks.length < 10 && Math.random() < 0.05) {
                createRandomFirework();
            }
            
            animationId = requestAnimationFrame(animateFireworks);
        }
        
        // 开始烟花效果
        function startFireworks() {
            if (animationId) {
                cancelAnimationFrame(animationId);
            }
            fireworks = [];
            createCelebrationFireworks();
            animateFireworks();
        }
        
        // 停止烟花效果
        function stopFireworks() {
            if (animationId) {
                cancelAnimationFrame(animationId);
                animationId = null;
            }
            fireworks = [];
            ctx.clearRect(0, 0, canvas.width, canvas.height);
        }
        
        // 切换主题
        function toggleTheme() {
            const body = document.body;
            const themeToggleBtn = document.getElementById('themeToggleBtn');
            
            isLuxuryTheme = !isLuxuryTheme;
            
            if (isLuxuryTheme) {
                body.classList.remove('simple-theme');
                body.classList.add('luxury-theme');
                currentColors = luxuryColors;
            } else {
                body.classList.remove('luxury-theme');
                body.classList.add('simple-theme');
                currentColors = simpleColors;
            }
            
            updateWheel();
            localStorage.setItem('foodWheelTheme', isLuxuryTheme ? 'luxury' : 'simple');
        }
        
        // 加载主题偏好
        function loadThemePreference() {
            const savedTheme = localStorage.getItem('foodWheelTheme');
            if (savedTheme === 'simple') {
                toggleTheme();
            }
        }
        
        // 更新菜品项目计数显示
        function updatePunishmentCount() {
            const countElement = document.getElementById('punishmentCount');
            const count = punishments.length;
            countElement.textContent = `${count}项`;
        }
        
        // 保存菜品列表到LocalStorage
        function savePunishments() {
            localStorage.setItem('wheelPunishments', JSON.stringify(punishments));
        }
        
        // 更新界面布局状态 - 修改:默认隐藏菜单
        function updateLayoutState() {
            const mainGrid = document.getElementById('mainGrid');
            const addMenuPrompt = document.getElementById('addMenuPrompt');
            const menuToggleBtn = document.getElementById('menuToggleBtn');
            const wheelPanel = document.querySelector('.wheel-panel');
            
            // 检查菜单是否为空
            if (punishments.length === 0) {
                mainGrid.classList.add('menu-empty');
                wheelPanel.classList.add('full-view');
                addMenuPrompt.classList.remove('hidden');
                menuToggleBtn.textContent = '显示菜单';
            } else {
                // 菜品不为空时,根据menuVisible决定是否显示菜单
                if (menuVisible) {
                    mainGrid.classList.remove('menu-empty');
                    menuToggleBtn.textContent = '隐藏菜单';
                } else {
                    mainGrid.classList.add('menu-empty');
                    menuToggleBtn.textContent = '显示菜单';
                }
                wheelPanel.classList.remove('full-view');
                addMenuPrompt.classList.add('hidden');
            }
            
            updatePunishmentCount();
        }
        
        // 切换菜单面板显示/隐藏
        function toggleMenuPanel() {
            const mainGrid = document.getElementById('mainGrid');
            const menuToggleBtn = document.getElementById('menuToggleBtn');
            
            if (punishments.length > 0) {
                menuVisible = !menuVisible;
                updateLayoutState();
            }
        }
        
        // 显示一键清空确认弹窗
        function showClearConfirmation() {
            if (isSpinning) {
                alert('转盘旋转时不能清空菜品!');
                return;
            }
            
            if (punishments.length === 0) {
                alert('当前没有菜品可清空!');
                return;
            }
            
            document.getElementById('clearCount').textContent = punishments.length;
            document.getElementById('confirmClearModal').classList.remove('hidden');
        }
        
        // 隐藏一键清空确认弹窗
        function hideClearConfirmation() {
            document.getElementById('confirmClearModal').classList.add('hidden');
        }
        
        // 执行一键清空操作
        function clearAllPunishments() {
            if (isSpinning) {
                alert('转盘旋转时不能清空菜品!');
                return;
            }
            
            const previousCount = punishments.length;
            punishments = [];
            
            updatePunishmentList();
            updateLayoutState();
            updateWheel();
            savePunishments();
            
            currentRotation = 0;
            currentPunishment = '';
            const wheelSvg = document.getElementById('wheelSvg');
            wheelSvg.style.transitionDuration = '0ms';
            wheelSvg.style.transform = 'rotate(0deg)';
            
            const resultDisplay = document.getElementById('resultDisplay');
            resultDisplay.classList.remove('show');
            
            closeCelebration();
            
            alert(`已清空 ${previousCount} 个菜品!`);
            hideClearConfirmation();
        }
        
        // 恢复默认菜单
        function resetToDefaultMenu() {
            if (isSpinning) {
                alert('转盘旋转时不能恢复默认菜单!');
                return;
            }
            
            if (!confirm('确定要恢复默认菜单吗?当前所有菜品将被替换为默认菜品。')) {
                return;
            }
            
            punishments = [...defaultPunishmentNames];
            updatePunishmentList();
            updateLayoutState();
            updateWheel();
            savePunishments();
            alert('已恢复默认菜单!');
        }
        
        // 导入TXT文件并解析菜品列表
        function importPunishmentsFromTxt(file) {
            const reader = new FileReader();
            
            reader.onload = function(e) {
                try {
                    const content = e.target.result;
                    const newPunishments = content.split(/\r?\n/)
                        .map(item => item.trim())
                        .filter(item => item.length > 0);
                    
                    if (newPunishments.length === 0) {
                        alert('文件为空或格式不正确!');
                        return;
                    }
                    
                    const uniqueNewPunishments = newPunishments.filter(
                        item => !punishments.includes(item)
                    );
                    
                    if (uniqueNewPunishments.length === 0) {
                        alert('所有菜品已存在!');
                        return;
                    }
                    
                    punishments.push(...uniqueNewPunishments);
                    updatePunishmentList();
                    updateLayoutState();
                    updateWheel();
                    savePunishments();
                    
                    alert(`成功导入 ${uniqueNewPunishments.length} 个新菜品!${newPunishments.length - uniqueNewPunishments.length > 0 ? `有 ${newPunishments.length - uniqueNewPunishments.length} 个重复菜品已跳过。` : ''}`);
                    
                } catch (error) {
                    console.error('导入文件时出错:', error);
                    alert('文件解析失败,请检查文件格式!');
                }
            };
            
            reader.onerror = function() {
                alert('读取文件失败!');
            };
            
            reader.readAsText(file);
        }
        
        // 快速添加第一个菜品
        function addFirstItem() {
            const item = prompt('请输入第一个菜品名称:', '披萨');
            if (item && item.trim()) {
                addPunishmentItem(item.trim());
            }
        }
        
        // 快速导入示例菜品
        function quickImportExample() {
            if (confirm('要导入示例菜品列表吗?')) {
                punishments = [...defaultPunishmentNames];
                updatePunishmentList();
                updateLayoutState();
                updateWheel();
                savePunishments();
                alert('已导入示例菜品列表!');
            }
        }
        
        // 显示菜单面板
        function showMenuPanel() {
            const mainGrid = document.getElementById('mainGrid');
            menuVisible = true;
            updateLayoutState();
            document.getElementById('menuToggleBtn').textContent = '隐藏菜单';
            document.getElementById('punishmentInput').focus();
        }

        // DOM加载完成事件
        document.addEventListener('DOMContentLoaded', function() {
            loadThemePreference();
            updatePunishmentList();
            updateLayoutState(); // 默认会隐藏菜单
            updateWheel();
            initFireworks();
              
            // 输入框回车事件
            const input = document.getElementById('punishmentInput');
            input.addEventListener('keypress', function(e) {
                if (e.key === 'Enter') {
                    addPunishment();
                }
            });
            
            // 绑定按钮事件
            document.getElementById('themeToggleBtn').addEventListener('click', toggleTheme);
            document.getElementById('menuToggleBtn').addEventListener('click', toggleMenuPanel);
            document.getElementById('addPunishmentBtn').addEventListener('click', addPunishment);
            document.getElementById('importBtn').addEventListener('click', function() {
                const fileInput = document.getElementById('importFile');
                if (fileInput.files.length > 0) {
                    importPunishmentsFromTxt(fileInput.files[0]);
                    fileInput.value = '';
                } else {
                    alert('请先选择文件!');
                }
            });
            
            document.getElementById('startBtn').addEventListener('click', startGame);
            document.getElementById('resetBtn').addEventListener('click', resetWheel);
            document.getElementById('resetToDefaultBtn').addEventListener('click', resetToDefaultMenu);
            document.getElementById('closeCelebrationBtn').addEventListener('click', closeCelebration);
            document.getElementById('confirmCelebrationBtn').addEventListener('click', closeCelebration);
            
            // 新增按钮事件
            document.getElementById('showMenuPanelBtn').addEventListener('click', showMenuPanel);
            document.getElementById('addFirstItemBtn').addEventListener('click', addFirstItem);
            document.getElementById('importQuickBtn').addEventListener('click', quickImportExample);
            
            // 一键清空相关事件
            document.getElementById('clearAllPunishmentsBtn').addEventListener('click', showClearConfirmation);
            document.getElementById('cancelClearBtn').addEventListener('click', hideClearConfirmation);
            document.getElementById('confirmClearBtn').addEventListener('click', clearAllPunishments);
            
            // 点击确认弹窗外部关闭弹窗
            document.getElementById('confirmClearModal').addEventListener('click', function(e) {
                if (e.target === this) {
                    hideClearConfirmation();
                }
            });
            
            // 处理动态生成的删除按钮
            document.getElementById('punishmentList').addEventListener('click', function(e) {
                if (e.target.classList.contains('remove-btn')) {
                    const item = e.target.closest('.punishment-item');
                    const index = Array.from(this.children).indexOf(item);
                    if (index !== -1) {
                        removePunishment(index);
                    }
                }
            });
            
            // 键盘事件监听 - 空格键开始点餐
            document.addEventListener('keydown', function(e) {
                if (e.code === 'Space' || e.key === ' ') {
                    e.preventDefault();
                    
                    const activeElement = document.activeElement;
                    const isInputFocused = activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA';
                    
                    const isModalOpen = !document.getElementById('celebrationModal').classList.contains('hidden') || 
                                       !document.getElementById('confirmClearModal').classList.contains('hidden');
                    
                    if (!isInputFocused && !isModalOpen && !isSpinning) {
                        startGame();
                    }
                }
            });
        });
        
        // 添加新菜品项目
        function addPunishment() {
            const input = document.getElementById('punishmentInput');
            const name = input.value.trim();
            
            if (!name) {
                alert('请输入菜品名称!');
                return;
            }
            
            if (name.length > 30) {
                alert('菜品名称过长,请控制在30字以内!');
                return;
            }
              
            addPunishmentItem(name);
        }
        
        // 添加菜品项目
        function addPunishmentItem(name) {
            if (!punishments.includes(name)) {
                punishments.push(name);
                document.getElementById('punishmentInput').value = '';
                document.getElementById('punishmentInput').focus();
                updatePunishmentList();
                updateLayoutState();
                updateWheel();
                savePunishments();
            } else {
                alert('该菜品已存在!');
            }
        }
  
        // 删除菜品项目
        function removePunishment(index) {
            if (isSpinning) {
                alert('转盘旋转时不能删除菜品!');
                return;
            }
            
            if (confirm('确定要删除这个菜品吗?')) {
                punishments.splice(index, 1);
                updatePunishmentList();
                updateLayoutState();
                updateWheel();
                savePunishments();
            }
        }
  
        // 更新菜品列表UI
        function updatePunishmentList() {
            const list = document.getElementById('punishmentList');
              
            if (punishments.length === 0) {
                list.innerHTML = '<div class="empty-state">菜品菜单是空的,请先添加菜品!</div>';
                return;
            }
              
            list.innerHTML = punishments.map((punishment, index) => {
                const icon = getFoodIcon(punishment);
                const isActive = currentPunishment === punishment;
                
                return `
                <div class="punishment-item ${isActive ? 'active' : ''}">
                    <div style="display: flex; align-items: center;">
                        <span class="food-icon">${icon}</span>
                        <span class="food-name">${punishment}</span>
                    </div>
                    <button class="remove-btn" title="删除此项">×</button>
                </div>
                `;
            }).join('');
        }
  
        // 更新转盘SVG图形
        function updateWheel() {
            const sectionsGroup = document.getElementById('wheelSections');
            sectionsGroup.innerHTML = '';
              
            // 空转盘状态
            if (punishments.length === 0) {
                const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
                path.setAttribute('d', 'M 0 0 L 240 0 A 240 240 0 1 1 -240 0 Z');
                path.setAttribute('fill', '#f5f5f5');
                path.setAttribute('stroke', '#e0e0e0');
                path.setAttribute('stroke-width', '3');
                  
                const text = document.createElementNS('http://www.w3.org/2000/svg', 'text');
                text.setAttribute('x', '0');
                text.setAttribute('y', '0');
                text.setAttribute('fill', '#999');
                text.setAttribute('font-size', '28');
                text.setAttribute('font-weight', '600');
                text.setAttribute('text-anchor', 'middle');
                text.setAttribute('dominant-baseline', 'middle');
                text.textContent = '请添加菜品';
                  
                sectionsGroup.appendChild(path);
                sectionsGroup.appendChild(text);
                return;
            }
              
            // 计算每个扇形的角度
            const sectionAngle = 360 / punishments.length;
            const radius = 240;
  
            // 生成每个扇形
            punishments.forEach((punishment, index) => {
                const startAngle = index * sectionAngle;
                const endAngle = (index + 1) * sectionAngle;
                  
                const startAngleRad = (startAngle * Math.PI) / 180;
                const endAngleRad = (endAngle * Math.PI) / 180;
                  
                const largeArcFlag = sectionAngle > 180 ? 1 : 0;
                  
                const x1 = Math.cos(startAngleRad) * radius;
                const y1 = Math.sin(startAngleRad) * radius;
                const x2 = Math.cos(endAngleRad) * radius;
                const y2 = Math.sin(endAngleRad) * radius;
                  
                const pathData = `M 0 0 L ${x1} ${y1} A ${radius} ${radius} 0 ${largeArcFlag} 1 ${x2} ${y2} Z`;
                  
                const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
                path.setAttribute('d', pathData);
                path.setAttribute('fill', currentColors[index % currentColors.length]);
                path.setAttribute('stroke', '#fff');
                path.setAttribute('stroke-width', '3');
                path.setAttribute('filter', 'url(#shadow)');
                  
                // 计算文本位置
                const midAngle = (startAngle + endAngle) / 2;
                const textRadius = radius * 0.65;
                const textX = Math.cos((midAngle * Math.PI) / 180) * textRadius;
                const textY = Math.sin((midAngle * Math.PI) / 180) * textRadius;
                  
                let fontSize = 22;
                if (punishments.length > 15) fontSize = 16;
                else if (punishments.length > 10) fontSize = 18;
                else if (punishments.length > 8) fontSize = 20;
                  
                // 创建包含图标和文字的文本元素 - 放在同一行
                const textElement = document.createElementNS('http://www.w3.org/2000/svg', 'text');
                textElement.setAttribute('x', textX);
                textElement.setAttribute('y', textY);
                textElement.setAttribute('fill', '#fff');
                textElement.setAttribute('font-size', fontSize);
                textElement.setAttribute('font-weight', '700');
                textElement.setAttribute('text-anchor', 'middle');
                textElement.setAttribute('dominant-baseline', 'middle');
                textElement.setAttribute('transform', `rotate(${midAngle}, ${textX}, ${textY})`);
                textElement.setAttribute('filter', 'url(#shadow)');
                
                // 创建图标tspan(图标字体大一些)
                const iconSpan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
                iconSpan.setAttribute('font-size', fontSize + 8);
                iconSpan.textContent = getWheelFoodIcon(punishment);
                
                // 创建文字tspan
                const nameSpan = document.createElementNS('http://www.w3.org/2000/svg', 'tspan');
                nameSpan.setAttribute('dx', '0.2em'); // 图标和文字之间的间距
                
                const maxChars = 6;
                let displayText = punishment;
                if (punishment.length > maxChars) {
                    displayText = punishment.substring(0, maxChars) + '..';
                }
                nameSpan.textContent = displayText;
                
                // 将图标和文字添加到文本元素中
                textElement.appendChild(iconSpan);
                textElement.appendChild(nameSpan);
                
                sectionsGroup.appendChild(path);
                sectionsGroup.appendChild(textElement);
            });
        }
  
        // 开始转盘游戏
        function startGame() {
            if (punishments.length === 0) {
                alert('请先添加菜品!');
                return;
            }
  
            if (isSpinning) return;
  
            isSpinning = true;
            currentPunishment = '';
              
            const startBtn = document.getElementById('startBtn');
            const startBtnText = document.getElementById('startBtnText');
            startBtn.disabled = true;
            startBtnText.textContent = '点餐中...';
              
            const resultDisplay = document.getElementById('resultDisplay');
            resultDisplay.classList.remove('show');
            
            const randomDuration = 4000 + Math.random() * 4000;
            
            const randomDegreeOffset = Math.floor(Math.random() * 360);
            const randomSpins = 5 + Math.floor(Math.random() * 5);
            const finalRotation = currentRotation + (randomSpins * 360) + randomDegreeOffset;
            
            currentRotation = finalRotation;
            
            const wheelSvg = document.getElementById('wheelSvg');
            wheelSvg.style.transitionDuration = `${randomDuration}ms`;
            wheelSvg.style.transform = `rotate(${currentRotation}deg)`;
            
            setTimeout(() => {
                isSpinning = false;
                
                const POINTER_ANGLE = 270;
                
                const actualRotation = currentRotation % 360;
                
                let winningAngle = (POINTER_ANGLE - actualRotation);
                
                winningAngle = winningAngle % 360;
                if (winningAngle < 0) {
                    winningAngle += 360;
                }
                
                const sectionAngle = 360 / punishments.length;
                const winningIndex = Math.floor(winningAngle / sectionAngle);
                
                currentPunishment = punishments[winningIndex] || punishments[0];
                
                startBtn.disabled = false;
                startBtnText.textContent = '再次点餐';
                
                // 更新结果显示 - 确保图标是彩色表情符号
                const winnerIcon = getFoodIcon(currentPunishment);
                document.getElementById('winnerPunishment').innerHTML = `
                    <span class="winner-icon">${winnerIcon}</span>
                    <span>${currentPunishment}</span>
                `;
                resultDisplay.classList.add('show');
                
                // 更新庆祝弹窗结果
                document.getElementById('celebrationPunishment').innerHTML = `
                    <span class="winner-icon">${winnerIcon}</span>
                    <span>${currentPunishment}</span>
                `;
                
                // 更新列表高亮
                updatePunishmentList();
                
                // 显示庆祝弹窗
                showCelebration();
            }, randomDuration);
        }
  
        // 重置转盘
        function resetWheel() {
            if (isSpinning) {
                alert('转盘旋转时不能重置!');
                return;
            }
            
            if (!confirm('确定要重置转盘吗?')) return;
              
            currentRotation = 0;
            currentPunishment = '';
              
            const wheelSvg = document.getElementById('wheelSvg');
            wheelSvg.style.transitionDuration = '0ms';
            wheelSvg.style.transform = 'rotate(0deg)';
              
            const resultDisplay = document.getElementById('resultDisplay');
            resultDisplay.classList.remove('show');
            
            // 重置结果显示
            document.getElementById('winnerPunishment').innerHTML = `
                <span class="winner-icon">&#127869;&#65039;</span>
                <span>等待选择...</span>
            `;
            
            // 重置庆祝弹窗结果
            document.getElementById('celebrationPunishment').innerHTML = `
                <span class="winner-icon">&#127869;&#65039;</span>
                <span>等待选择...</span>
            `;
            
            updatePunishmentList();
            closeCelebration();
        }
  
        // 显示庆祝弹窗
        function showCelebration() {
            const modal = document.getElementById('celebrationModal');
            modal.classList.remove('hidden');
            // 启动烟花效果
            startFireworks();
        }
  
        // 关闭庆祝弹窗
        function closeCelebration() {
            document.getElementById('celebrationModal').classList.add('hidden');
            // 停止烟花效果
            stopFireworks();
        }
    </script>
</body></html>

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
top777 + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

来自 #
 楼主| 小乖乖 发表于 2025-12-26 10:00 |楼主
本帖最后由 小乖乖 于 2026-1-1 20:39 编辑

这个是直接保存为html网页的代码,方便你们下载

美食大转盘.rar

13.55 KB, 下载次数: 18, 下载积分: 吾爱币 -1 CB

推荐
ericwise 发表于 2025-12-25 21:33
本帖最后由 ericwise 于 2025-12-25 21:34 编辑
小乖乖 发表于 2025-12-25 20:07
再发一个素雅版本,这个素雅版的美食大转盘保持了完整的功能,同时在视觉上更加简洁、专业,适合各种使用场 ...
1351行注释掉
1353行                  text.innerHTML = displayText;
1434行                document.getElementById('winnerPunishment').innerHTML = currentPunishment;
1478行             document.getElementById('celebrationPunishment').innerHTML = currentPunishment;
推荐
 楼主| 小乖乖 发表于 2025-12-25 19:33 |楼主
迈克老狼 发表于 2025-12-25 18:11
挺好的能否做成离线的

本来就是离线的啊,将代码保存为html格式就可以一直用,代码是utf8格式,记住保存文本也要是这种格式,不然会乱码
3#
youziyouwei 发表于 2025-12-25 17:46
能自定义转盘内容吗?
4#
ysjd22 发表于 2025-12-25 17:48
非常有创意,每天可以不重样了
5#
chishingchan 发表于 2025-12-25 18:02
Windows 7 + 傲游浏览器,转盘全是 &#xxxxx (x=数字)
6#
迈克老狼 发表于 2025-12-25 18:11
挺好的能否做成离线的
7#
当兵的男人 发表于 2025-12-25 18:36
本帖最后由 当兵的男人 于 2025-12-25 18:38 编辑
chishingchan 发表于 2025-12-25 18:02
Windows 7 + 傲游浏览器,转盘全是 &#xxxxx (x=数字)

看错了  以为是我那个大转盘咧   哈哈哈
8#
当兵的男人 发表于 2025-12-25 18:37
迈克老狼 发表于 2025-12-25 18:11
挺好的能否做成离线的

难道这不是离线的吗?双击  就能666
9#
ldwz 发表于 2025-12-25 18:46
彻底解决了。不知道吃什么的世界性难题~
10#
zt185 发表于 2025-12-25 18:57
真是啥软件都有,楼主厉害!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - 52pojie.cn ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2026-1-2 19:01

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表