分享图
动画工坊
引擎就绪
<!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>
        @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Noto+Sans+SC:wght@400;700&display=swap');

        :root {
            --bg-color: #0b0f19;
            --panel-bg: rgba(15, 23, 42, 0.7);
            --border-color: #1e293b;
            --text-main: #e2e8f0;
            --text-muted: #94a3b8;
            --accent-radar: #0ea5e9;
            --accent-radar-glow: rgba(14, 165, 233, 0.5);
            --accent-purge: #10b981;
            --accent-purge-glow: rgba(16, 185, 129, 0.5);
            --liquid-main: #3b82f6;
            --liquid-dark: #1d4ed8;
            --metal-light: #94a3b8;
            --metal-dark: #334155;
            --metal-highlight: #cbd5e1;
            
            --hud-font: 'JetBrains Mono', monospace;
            --ui-font: 'Noto Sans SC', sans-serif;
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            background-color: var(--bg-color);
            color: var(--text-main);
            font-family: var(--ui-font);
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
            overflow: hidden;
            background-image: 
                radial-gradient(circle at 50% 50%, rgba(14, 165, 233, 0.05) 0%, transparent 60%),
                linear-gradient(rgba(255,255,255,0.02) 1px, transparent 1px),
                linear-gradient(90deg, rgba(255,255,255,0.02) 1px, transparent 1px);
            background-size: 100% 100%, 40px 40px, 40px 40px;
            background-position: center center;
        }

        /* Scanline effect */
        body::after {
            content: " ";
            display: block;
            position: absolute;
            top: 0;
            left: 0;
            bottom: 0;
            right: 0;
            background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.1) 50%), linear-gradient(90deg, rgba(255, 0, 0, 0.03), rgba(0, 255, 0, 0.01), rgba(0, 0, 255, 0.03));
            z-index: 2;
            background-size: 100% 3px, 6px 100%;
            pointer-events: none;
        }

        .container {
            position: relative;
            width: 100%;
            max-width: 1200px;
            height: 90vh;
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 10;
        }

        .svg-container {
            width: 100%;
            height: 100%;
            max-height: 800px;
            position: relative;
        }

        /* HUD Panels */
        .hud-panel {
            position: absolute;
            background: var(--panel-bg);
            border: 1px solid var(--border-color);
            border-radius: 8px;
            padding: 16px;
            backdrop-filter: blur(10px);
            -webkit-backdrop-filter: blur(10px);
            box-shadow: 0 4px 20px rgba(0,0,0,0.5), inset 0 0 0 1px rgba(255,255,255,0.05);
            z-index: 20;
        }

        .hud-panel h3 {
            font-size: 14px;
            color: var(--accent-radar);
            margin-bottom: 12px;
            text-transform: uppercase;
            letter-spacing: 1px;
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .hud-panel h3::before {
            content: '';
            display: block;
            width: 6px;
            height: 6px;
            background: var(--accent-radar);
            border-radius: 50%;
            box-shadow: 0 0 8px var(--accent-radar);
        }

        .hud-data {
            font-family: var(--hud-font);
            font-size: 12px;
            color: var(--text-muted);
            line-height: 1.6;
        }

        .hud-data span {
            color: var(--text-main);
            font-weight: bold;
        }

        .hud-data .value {
            color: var(--accent-radar);
            font-size: 14px;
        }
        
        .hud-data .purge-status {
            color: var(--metal-light);
            transition: color 0.3s;
        }
        .hud-data .purge-status.active {
            color: var(--accent-purge);
            text-shadow: 0 0 8px var(--accent-purge-glow);
        }

        /* Positioning panels to avoid central animation */
        #panel-left { top: 10%; left: 5%; width: 260px; }
        #panel-right { top: 10%; right: 5%; width: 280px; }
        #panel-bottom { bottom: 8%; left: 50%; transform: translateX(-50%); width: auto; display: flex; gap: 24px; padding: 12px 24px; }

        .stat-box { display: flex; flex-direction: column; align-items: center; }
        .stat-box .label { font-size: 10px; color: var(--text-muted); text-transform: uppercase; }
        .stat-box .num { font-family: var(--hud-font); font-size: 18px; color: var(--text-main); }
        .stat-box .num.acc { color: var(--accent-purge); }

        /* SVG Animations */
        @keyframes radar-pulse {
            0% { stroke-width: 0.5; opacity: 1; stroke: #fff; }
            100% { stroke-width: 3; opacity: 0; stroke: var(--accent-radar); }
        }

        @keyframes flow-dash {
            to { stroke-dashoffset: -20; }
        }

        @keyframes wave-move {
            0% { transform: translateX(0) scaleY(1); }
            50% { transform: translateX(-20px) scaleY(1.2); }
            100% { transform: translateX(-40px) scaleY(1); }
        }

        @keyframes bubble-rise {
            0% { transform: translateY(0) scale(0.5); opacity: 0; }
            20% { opacity: 0.8; }
            100% { transform: translateY(-100px) scale(1.5); opacity: 0; }
        }

        @keyframes purge-blast {
            0% { opacity: 0; transform: scaleX(0.8) translateX(10px); }
            10% { opacity: 1; transform: scaleX(1) translateX(0); }
            90% { opacity: 1; transform: scaleX(1) translateX(0); }
            100% { opacity: 0; transform: scaleX(0.9) translateX(-5px); }
        }

        @keyframes lens-clean {
            0% { stop-color: #334155; }
            20% { stop-color: #0ea5e9; }
            80% { stop-color: #0ea5e9; }
            100% { stop-color: #334155; }
        }

        /* Class toggles controlled by JS */
        .radar-wave {
            animation: radar-pulse 1.5s infinite linear;
        }
        .radar-wave:nth-child(2) { animation-delay: 0.5s; }
        .radar-wave:nth-child(3) { animation-delay: 1.0s; }

        .turbulent-wave {
            animation: wave-move 3s infinite ease-in-out alternate;
        }
        
        .bubble {
            animation: bubble-rise 4s infinite ease-in;
            transform-origin: center;
        }

        .is-purging .purge-gas {
            animation: purge-blast 2s forwards cubic-bezier(0.1, 0.8, 0.3, 1);
        }
        .is-purging .radar-lens-glow {
            animation: lens-clean 2s forwards;
        }
        .is-purging .splash-particle {
            opacity: 0 !important;
            transition: opacity 0.2s;
        }

        .splash-particle {
            transition: opacity 2s;
        }

        /* Interactive toggle (Optional, adding as per requirement 4 for IFR) */
        .ifr-toggle {
            position: absolute;
            top: 20px;
            right: 20px;
            background: rgba(14, 165, 233, 0.1);
            border: 1px solid var(--accent-radar);
            color: var(--accent-radar);
            padding: 8px 16px;
            border-radius: 4px;
            font-family: var(--ui-font);
            font-size: 12px;
            cursor: pointer;
            z-index: 30;
            transition: all 0.3s;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        .ifr-toggle:hover {
            background: rgba(14, 165, 233, 0.3);
            box-shadow: 0 0 10px var(--accent-radar-glow);
        }
        .ifr-toggle .indicator {
            width: 8px; height: 8px; border-radius: 50%; background: var(--accent-radar);
            box-shadow: 0 0 5px var(--accent-radar);
        }

    </style>
</head>
<body>

    <button class="ifr-toggle" onclick="manualPurge()">
        <div class="indicator" id="purge-indicator"></div>
        手动触发吹扫 (IFR 核心机制)
    </button>

    <div class="container">
        
        <!-- 左侧面板:方案原理 -->
        <div class="hud-panel" id="panel-left">
            <h3>系统架构 & IFR</h3>
            <div class="hud-data">
                <p><strong>最终理想解 (IFR):</strong></p>
                <p style="margin-bottom: 8px; color: var(--text-main); font-size: 11px;">测量系统在恶劣工况下自我维持清洁与平静,仿佛干扰不存在。</p>
                <p>▶ <strong>导波管 (Stilling Well)</strong><br>利用物理隔离,将外部剧烈波动的液面转化为管内平静液柱。</p>
                <p>▶ <strong>80GHz FMCW 雷达</strong><br>高频调频连续波,利用底部参考反射进行自校准抑制气泡。</p>
                <p>▶ <strong>气动吹扫系统</strong><br>巧妙利用现场气源资源,周期性喷吹隔离液滴飞溅。</p>
            </div>
        </div>

        <!-- 右侧面板:实时监控 -->
        <div class="hud-panel" id="panel-right">
            <h3 style="color: var(--accent-purge);">运行状态</h3>
            <div class="hud-data">
                <div style="display: flex; justify-content: space-between; border-bottom: 1px solid var(--border-color); padding-bottom: 4px; margin-bottom: 8px;">
                    <span>测量精度:</span>
                    <span class="value" style="color: var(--accent-purge);">≤±2.00 mm</span>
                </div>
                <div style="display: flex; justify-content: space-between; margin-bottom: 4px;">
                    <span>外部液面波动:</span>
                    <span class="value" style="color: #ef4444;">±150 mm (剧烈)</span>
                </div>
                <div style="display: flex; justify-content: space-between; margin-bottom: 8px;">
                    <span>管内液面波动:</span>
                    <span class="value">±0.5 mm (平静)</span>
                </div>
                <div style="display: flex; justify-content: space-between; margin-bottom: 4px;">
                    <span>环境干扰:</span>
                    <span class="value" style="color: #ef4444;">气相含液滴, 飞溅</span>
                </div>
                <div style="margin-top: 16px; padding: 8px; background: rgba(0,0,0,0.3); border-radius: 4px;">
                    <p style="margin-bottom: 4px; font-size: 10px; text-transform: uppercase;">吹扫电磁阀状态</p>
                    <div id="purge-status-text" class="purge-status">STANDBY [倒计时: <span id="countdown">30</span>s]</div>
                    <!-- 进度条 -->
                    <div style="width: 100%; height: 2px; background: #1e293b; margin-top: 6px; position: relative; overflow: hidden;">
                        <div id="purge-progress" style="position: absolute; left: 0; top: 0; height: 100%; width: 0%; background: var(--accent-purge); transition: width 1s linear;"></div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 底部面板:实时读数 -->
        <div class="hud-panel" id="panel-bottom">
            <div class="stat-box">
                <div class="label">雷达频率</div>
                <div class="num">80.0<span style="font-size:10px;color:var(--text-muted)"> GHz</span></div>
            </div>
            <div style="width: 1px; background: var(--border-color);"></div>
            <div class="stat-box">
                <div class="label">当前液位 (自校准后)</div>
                <div class="num" id="live-level">4,521.03<span style="font-size:10px;color:var(--text-muted)"> mm</span></div>
            </div>
            <div style="width: 1px; background: var(--border-color);"></div>
            <div class="stat-box">
                <div class="label">底部参考反射率</div>
                <div class="num acc">99.8<span style="font-size:10px;color:var(--text-muted)"> %</span></div>
            </div>
        </div>

        <!-- 核心 SVG 动画区 -->
        <div class="svg-container" id="animation-stage">
            <svg viewBox="0 0 800 600" width="100%" height="100%" preserveAspectRatio="xMidYMid meet">
                <defs>
                    <!-- 渐变定义 -->
                    <linearGradient id="metal-grad" x1="0%" y1="0%" x2="100%" y2="0%">
                        <stop offset="0%" stop-color="var(--metal-dark)" />
                        <stop offset="50%" stop-color="var(--metal-highlight)" />
                        <stop offset="100%" stop-color="var(--metal-dark)" />
                    </linearGradient>
                    <linearGradient id="metal-grad-vert" x1="0%" y1="0%" x2="0%" y2="100%">
                        <stop offset="0%" stop-color="var(--metal-highlight)" />
                        <stop offset="100%" stop-color="var(--metal-dark)" />
                    </linearGradient>
                    <linearGradient id="liquid-grad" x1="0%" y1="0%" x2="0%" y2="100%">
                        <stop offset="0%" stop-color="var(--liquid-main)" />
                        <stop offset="100%" stop-color="var(--liquid-dark)" />
                    </linearGradient>
                    <linearGradient id="liquid-turbulent-grad" x1="0%" y1="0%" x2="0%" y2="100%">
                        <stop offset="0%" stop-color="#2563eb" stop-opacity="0.8"/>
                        <stop offset="100%" stop-color="#1e3a8a" stop-opacity="0.9"/>
                    </linearGradient>
                    
                    <radialGradient id="radar-lens" cx="50%" cy="50%" r="50%">
                        <stop offset="0%" class="radar-lens-glow" stop-color="var(--metal-dark)" />
                        <stop offset="100%" stop-color="#0f172a" />
                    </radialGradient>

                    <linearGradient id="purge-gas-grad" x1="0%" y1="0%" x2="100%" y2="0%">
                        <stop offset="0%" stop-color="var(--accent-purge)" stop-opacity="0.9"/>
                        <stop offset="50%" stop-color="var(--accent-purge)" stop-opacity="0.5"/>
                        <stop offset="100%" stop-color="var(--bg-color)" stop-opacity="0"/>
                    </linearGradient>

                    <!-- 剪切路径,用于分离管内/管外的液体动画 -->
                    <clipPath id="clip-outside">
                        <!-- 扣除中心导波管的区域 -->
                        <path d="M 100,200 L 370,200 L 370,550 L 430,550 L 430,200 L 700,200 L 700,600 L 100,600 Z" />
                    </clipPath>
                    
                    <clipPath id="clip-inside">
                        <!-- 仅导波管内部区域 -->
                        <rect x="375" y="200" width="50" height="350" />
                    </clipPath>

                    <!-- 雷达波纹路模板 -->
                    <g id="radar-fmcw-wave">
                        <ellipse cx="400" cy="180" rx="20" ry="6" fill="none" class="radar-wave" />
                        <ellipse cx="400" cy="180" rx="40" ry="12" fill="none" class="radar-wave" />
                        <ellipse cx="400" cy="180" rx="60" ry="18" fill="none" class="radar-wave" />
                        <!-- 向下发射的波束指示线 -->
                        <line x1="385" y1="180" x2="385" y2="400" stroke="var(--accent-radar)" stroke-width="1" stroke-dasharray="4 4" opacity="0.5">
                            <animate attributeName="stroke-dashoffset" from="20" to="0" dur="0.5s" repeatCount="indefinite" />
                        </line>
                        <line x1="415" y1="180" x2="415" y2="400" stroke="var(--accent-radar)" stroke-width="1" stroke-dasharray="4 4" opacity="0.5">
                            <animate attributeName="stroke-dashoffset" from="20" to="0" dur="0.5s" repeatCount="indefinite" />
                        </line>
                    </g>
                </defs>

                <!-- 背景网格结构 -->
                <path d="M 100,150 L 100,550 M 700,150 L 700,550 M 100,550 L 700,550" stroke="#1e293b" stroke-width="4" fill="none" />
                <text x="110" y="540" fill="var(--text-muted)" font-size="12" font-family="var(--hud-font)">TANK_BOTTOM</text>

                <!-- ================= 1. 恶劣环境:管外剧烈波动的液体与气泡 ================= -->
                <g clip-path="url(#clip-outside)">
                    <!-- 动态波浪叠加层 -->
                    <g class="turbulent-wave" opacity="0.7">
                        <path d="M 50,420 Q 150,380 250,430 T 450,410 T 650,440 T 750,400 L 750,600 L 50,600 Z" fill="url(#liquid-turbulent-grad)" />
                    </g>
                    <g class="turbulent-wave" style="animation-delay: -1.5s; animation-duration: 4s;" opacity="0.5">
                        <path d="M 50,400 Q 200,450 350,390 T 550,440 T 750,410 L 750,600 L 50,600 Z" fill="url(#liquid-turbulent-grad)" />
                    </g>
                    
                    <!-- 飞溅液滴和环境雾气 (展示干扰) -->
                    <g fill="var(--liquid-main)" opacity="0.6" class="splash-particle">
                        <circle cx="350" cy="380" r="3"><animate attributeName="cy" values="380; 340; 400" dur="2s" repeatCount="indefinite"/></circle>
                        <circle cx="365" cy="350" r="2"><animate attributeName="cy" values="350; 320; 420" dur="1.8s" repeatCount="indefinite"/></circle>
                        <circle cx="435" cy="370" r="4"><animate attributeName="cy" values="370; 330; 410" dur="2.2s" repeatCount="indefinite"/></circle>
                        <circle cx="450" cy="390" r="2"><animate attributeName="cy" values="390; 350; 400" dur="1.5s" repeatCount="indefinite"/></circle>
                    </g>
                </g>

                <!-- ================= 2. 最终理想解体现一:物理隔离 (导波管) ================= -->
                <!-- 导波管背景壁 (暗部) -->
                <rect x="370" y="160" width="60" height="380" fill="#1e293b" opacity="0.8" />
                
                <!-- 管内平静液体 -->
                <g clip-path="url(#clip-inside)">
                    <rect id="calm-liquid" x="375" y="400" width="50" height="200" fill="url(#liquid-grad)">
                        <!-- 缓慢而平滑的液位变化 -->
                        <animate attributeName="y" values="400; 395; 405; 400" dur="10s" repeatCount="indefinite" ease="ease-in-out" />
                        <animate attributeName="height" values="150; 155; 145; 150" dur="10s" repeatCount="indefinite" ease="ease-in-out" />
                    </rect>
                    
                    <!-- 底部参考反射点 (IFR关键机制) -->
                    <path d="M 380,530 L 420,530" stroke="#f59e0b" stroke-width="4" stroke-dasharray="4 2" />
                    <text x="382" y="525" fill="#f59e0b" font-size="8" font-family="var(--hud-font)">REF_POINT</text>
                    
                    <!-- FMCW 雷达波束向下传播并反射 -->
                    <use href="#radar-fmcw-wave" />
                    <!-- 触及液面的反射波 -->
                    <ellipse cx="400" cy="400" rx="20" ry="4" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.8">
                        <animate attributeName="cy" values="400; 395; 405; 400" dur="10s" repeatCount="indefinite" />
                        <animate attributeName="opacity" values="0.8; 0; 0.8" dur="1.5s" repeatCount="indefinite" />
                    </ellipse>
                </g>

                <!-- 导波管外壳 (带开孔结构,允许液体连通但阻断波浪) -->
                <path d="M 370,160 L 370,550 M 430,160 L 430,550" stroke="url(#metal-grad-vert)" stroke-width="4" fill="none" />
                <!-- 管壁开槽/连通孔 -->
                <g stroke="#0f172a" stroke-width="4">
                    <line x1="370" y1="450" x2="370" y2="470" />
                    <line x1="370" y1="500" x2="370" y2="520" />
                    <line x1="430" y1="460" x2="430" y2="480" />
                    <line x1="430" y1="510" x2="430" y2="530" />
                </g>

                <!-- ================= 3. 雷达主机与隔离罩 ================= -->
                <!-- 隔离罩/法兰 -->
                <path d="M 340,160 L 460,160 L 450,140 L 350,140 Z" fill="url(#metal-grad)" />
                <path d="M 350,140 L 450,140 L 450,130 L 350,130 Z" fill="#475569" />
                
                <!-- 雷达表头主机 -->
                <rect x="365" y="60" width="70" height="70" rx="8" fill="url(#metal-grad)" stroke="#1e293b" stroke-width="2" />
                <!-- 仪表屏幕 -->
                <rect x="375" y="70" width="50" height="30" rx="2" fill="#020617" />
                <text x="380" y="85" fill="var(--accent-radar)" font-size="10" font-family="var(--hud-font)">80GHz</text>
                <text x="380" y="95" fill="var(--accent-purge)" font-size="8" font-family="var(--hud-font)">OK</text>
                
                <!-- 透镜/天线 -->
                <ellipse cx="400" cy="160" rx="18" ry="6" fill="url(#radar-lens)" />
                <path d="M 382,160 Q 400,175 418,160" fill="none" stroke="var(--metal-highlight)" stroke-width="1" />

                <!-- ================= 4. 最终理想解体现二:气动吹扫系统 ================= -->
                <!-- 吹扫气管线 -->
                <path d="M 200,120 L 320,120 L 320,150 L 340,155" fill="none" stroke="url(#metal-grad)" stroke-width="8" stroke-linejoin="round" />
                
                <!-- 气动吹扫电磁阀 & 气压调节器 -->
                <rect x="230" y="105" width="40" height="30" rx="4" fill="#334155" stroke="#1e293b" stroke-width="2" />
                <circle cx="250" cy="120" r="8" fill="#475569" stroke="#94a3b8" stroke-width="2" />
                <path d="M 250,116 L 253,122 L 247,122 Z" fill="#ef4444" /> <!-- 调节旋钮 -->
                <text x="230" y="100" fill="var(--text-muted)" font-size="10">PURGE VALVE</text>
                
                <!-- 气源输入指示 -->
                <path d="M 170,120 L 190,120" stroke="var(--accent-purge)" stroke-width="2" stroke-dasharray="4 2">
                    <animate attributeName="stroke-dashoffset" from="12" to="0" dur="0.5s" repeatCount="indefinite" />
                </path>
                <text x="150" y="123" fill="var(--accent-purge)" font-size="10">AIR</text>

                <!-- 吹扫喷嘴与气体喷射动画层 (核心视觉引导点) -->
                <g id="purge-effect-layer" opacity="0" class="purge-gas">
                    <!-- 喷嘴射出的高压气流,吹走下方飞溅 -->
                    <path d="M 340,155 L 430,160 L 440,180 L 320,170 Z" fill="url(#purge-gas-grad)" />
                    <!-- 气流线条增强动感 -->
                    <line x1="340" y1="158" x2="420" y2="165" stroke="#a7f3d0" stroke-width="2" opacity="0.8" />
                    <line x1="335" y1="162" x2="410" y2="172" stroke="#34d399" stroke-width="1.5" opacity="0.6" />
                    <!-- 文字视觉引导 -->
                    <text x="450" y="170" fill="var(--accent-purge)" font-size="12" font-weight="bold" font-style="italic">CLEANING ACT!</text>
                </g>
                
                <!-- 辅助说明引线 -->
                <g opacity="0.6" font-family="var(--ui-font)" font-size="10" fill="var(--text-muted)">
                    <path d="M 435,250 L 480,220 L 520,220" stroke="var(--text-muted)" stroke-width="1" fill="none" />
                    <circle cx="435" cy="250" r="2" fill="var(--text-muted)" />
                    <text x="525" y="223">隔离管消除液面震荡</text>

                    <path d="M 425,530 L 480,530 L 520,530" stroke="#f59e0b" stroke-width="1" fill="none" />
                    <circle cx="425" cy="530" r="2" fill="#f59e0b" />
                    <text x="525" y="533" fill="#f59e0b">参考点提供自校准基准</text>
                </g>
            </svg>
        </div>
    </div>

    <script>
        // 动画与业务逻辑控制
        document.addEventListener('DOMContentLoaded', () => {
            const animationStage = document.getElementById('animation-stage');
            const statusText = document.getElementById('purge-status-text');
            const progress = document.getElementById('purge-progress');
            const liveLevel = document.getElementById('live-level');
            const indicator = document.getElementById('purge-indicator');
            const countdownEl = document.getElementById('countdown');
            
            // 业务参数: 吹扫周期30s, 喷吹2s。为演示体验压缩时间为 10s 周期,喷吹 2s。
            const cycleTime = 10; 
            const purgeDuration = 2;
            let currentTimer = cycleTime;
            let timerInterval;

            // 模拟高精度液位读数 (±2mm)
            const baseLevel = 4521.00;
            setInterval(() => {
                const noise = (Math.random() * 4 - 2).toFixed(2); // ±2.00
                const val = (baseLevel + parseFloat(noise)).toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 2});
                liveLevel.innerHTML = `${val}<span style="font-size:10px;color:var(--text-muted)"> mm</span>`;
            }, 500);

            function startPurgeCycle() {
                clearInterval(timerInterval);
                
                timerInterval = setInterval(() => {
                    currentTimer--;
                    
                    if (currentTimer <= 0) {
                        // 触发吹扫
                        triggerPurgeAction();
                        currentTimer = cycleTime; // 重置周期
                    } else {
                        // 更新待机状态
                        const pct = ((cycleTime - currentTimer) / cycleTime) * 100;
                        progress.style.width = `${pct}%`;
                        countdownEl.textContent = currentTimer;
                    }
                }, 1000);
            }

            function triggerPurgeAction() {
                // UI 状态切换
                animationStage.classList.add('is-purging');
                statusText.innerHTML = 'ACTIVE [喷吹中]';
                statusText.classList.add('active');
                indicator.style.background = 'var(--accent-purge)';
                indicator.style.boxShadow = '0 0 10px var(--accent-purge)';
                
                // IFR 视觉强调机制:短暂显示气流,吹掉透镜下的虚拟“水珠/雾气”
                
                setTimeout(() => {
                    animationStage.classList.remove('is-purging');
                    statusText.innerHTML = `STANDBY [倒计时: <span id="countdown">${cycleTime}</span>s]`;
                    statusText.classList.remove('active');
                    indicator.style.background = 'var(--accent-radar)';
                    indicator.style.boxShadow = '0 0 5px var(--accent-radar)';
                    progress.style.width = '0%';
                    // 重新绑定倒计时元素
                    document.getElementById('countdown').textContent = cycleTime;
                }, purgeDuration * 1000);
            }

            // 暴露给全局以便按钮调用
            window.manualPurge = () => {
                currentTimer = cycleTime; // 重置计时器防止冲突
                progress.style.width = '0%';
                triggerPurgeAction();
            };

            // 启动自动循环 (满足要求6与7)
            startPurgeCycle();
        });
    </script>
</body>
</html>
积分规则:每轮对话扣10分