分享图
A
动画渲染工坊
就绪

这是一个非常有趣的设计挑战——将"傲娇害羞退缩导致信息链断裂"的社交问题,通过"魔法共鸣"的场效应灯光同步来解决,并且要用 IFR(最终理想解)的视角来呈现。让我深入设计这个动画。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>魔法共鸣通信 · IFR理想解原理动画</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@400;700;900&family=Noto+Sans+SC:wght@300;400;700&display=swap" rel="stylesheet">
<style>
:root {
    --bg: #06060c;
    --fg: #e8dfd4;
    --muted: #6a6575;
    --accent: #c9a84c;
    --card: #0e0e18;
    --border: #22222e;
    --red: #ff2d55;
    --blue: #00b4ff;
    --green: #00ff88;
    --room-evil: #0c0a14;
    --room-neuro: #0a0c16;
}
*{margin:0;padding:0;box-sizing:border-box}
body{
    background:var(--bg);
    color:var(--fg);
    font-family:'Noto Sans SC',sans-serif;
    min-height:100vh;
    display:flex;flex-direction:column;align-items:center;
    overflow-x:hidden;
}
body::before{
    content:'';position:fixed;inset:0;
    background:
        radial-gradient(ellipse at 20% 25%,rgba(50,20,70,0.25) 0%,transparent 55%),
        radial-gradient(ellipse at 80% 75%,rgba(15,30,70,0.25) 0%,transparent 55%),
        radial-gradient(ellipse at 50% 50%,rgba(201,168,76,0.03) 0%,transparent 40%);
    pointer-events:none;z-index:0;
}
.container{position:relative;z-index:1;width:100%;max-width:1260px;padding:20px 16px}
header{text-align:center;margin-bottom:18px}
header h1{
    font-family:'Cinzel',serif;font-weight:900;
    font-size:clamp(22px,3.8vw,40px);letter-spacing:.08em;
    color:var(--accent);
    text-shadow:0 0 40px rgba(201,168,76,0.25),0 2px 8px rgba(0,0,0,0.6);
}
header p{font-size:13px;color:var(--muted);margin-top:5px;font-weight:300;letter-spacing:.12em}
.animation-wrapper{
    width:100%;
    background:linear-gradient(145deg,#0c0a16 0%,#08080e 45%,#0a0c18 100%);
    border:1px solid var(--border);border-radius:14px;
    overflow:hidden;
    box-shadow:0 0 80px rgba(0,0,0,0.6),inset 0 0 80px rgba(0,0,0,0.4);
}
.animation-wrapper svg{width:100%;height:auto;display:block}

/* 控制面板 */
.control-panel{
    display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
    gap:14px;margin-top:20px;padding:18px 20px;
    background:var(--card);border:1px solid var(--border);border-radius:12px;
}
.symbol-btn{
    display:flex;flex-direction:column;align-items:center;gap:3px;
    padding:12px 22px;border:2px solid var(--border);border-radius:10px;
    background:transparent;color:var(--fg);
    font-family:'Noto Sans SC',sans-serif;font-size:13px;
    cursor:pointer;transition:all .3s ease;min-width:108px;
    position:relative;overflow:hidden;
}
.symbol-btn::before{
    content:'';position:absolute;inset:0;opacity:0;transition:opacity .3s;
    border-radius:8px;
}
.symbol-btn.moon::before{background:radial-gradient(circle,rgba(255,45,85,0.15),transparent 70%)}
.symbol-btn.sun::before{background:radial-gradient(circle,rgba(0,180,255,0.15),transparent 70%)}
.symbol-btn.star::before{background:radial-gradient(circle,rgba(0,255,136,0.15),transparent 70%)}
.symbol-btn:hover::before{opacity:1}
.symbol-btn:hover{transform:translateY(-2px);box-shadow:0 6px 24px rgba(0,0,0,0.4)}
.symbol-btn.moon{border-color:rgba(255,45,85,0.25)}
.symbol-btn.moon:hover,.symbol-btn.moon.active{border-color:var(--red);box-shadow:0 0 24px rgba(255,45,85,0.25)}
.symbol-btn.sun{border-color:rgba(0,180,255,0.25)}
.symbol-btn.sun:hover,.symbol-btn.sun.active{border-color:var(--blue);box-shadow:0 0 24px rgba(0,180,255,0.25)}
.symbol-btn.star{border-color:rgba(0,255,136,0.25)}
.symbol-btn.star:hover,.symbol-btn.star.active{border-color:var(--green);box-shadow:0 0 24px rgba(0,255,136,0.25)}
.symbol-btn.active::before{opacity:1}
.symbol-btn.active{transform:translateY(-1px)}
.symbol-icon{font-size:26px;line-height:1}
.symbol-name{font-weight:700;font-size:13px}
.symbol-color-tag{font-size:10px;opacity:.5;letter-spacing:.06em}
.moon .symbol-icon{color:var(--red)}.sun .symbol-icon{color:var(--blue)}.star .symbol-icon{color:var(--green)}
.reset-btn{
    padding:10px 22px;background:transparent;border:1px solid var(--border);
    border-radius:8px;color:var(--muted);font-family:'Noto Sans SC',sans-serif;
    font-size:12px;cursor:pointer;transition:all .3s;letter-spacing:.05em;
}
.reset-btn:hover{border-color:var(--accent);color:var(--accent)}

.status-bar{
    flex-basis:100%;text-align:center;padding-top:10px;
    border-top:1px solid var(--border);margin-top:6px;
}
.status-text{
    font-size:12px;color:var(--muted);transition:color .4s;
    font-weight:300;letter-spacing:.08em;
}
.status-text.active{color:var(--fg)}

/* IFR说明 */
.info-panel{
    margin-top:20px;padding:18px 22px;
    background:var(--card);border:1px solid var(--border);border-radius:12px;
    font-size:12.5px;line-height:1.9;color:var(--muted);
}
.info-panel h3{
    font-family:'Cinzel',serif;color:var(--accent);font-size:14px;
    margin-bottom:8px;letter-spacing:.06em;
}
.info-panel .hl{color:var(--fg);font-weight:700}
.ifr-core{
    margin-top:12px;padding:12px 16px;
    background:rgba(201,168,76,0.05);border-left:3px solid var(--accent);
    border-radius:0 6px 6px 0;
}
.ifr-core .hl{color:var(--accent)}

/* SVG内动画 */
@keyframes rotate-cw{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
@keyframes rotate-ccw{from{transform:rotate(0deg)}to{transform:rotate(-360deg)}}
@keyframes flicker{0%,100%{opacity:.82}25%{opacity:1}50%{opacity:.72}75%{opacity:.93}}
@keyframes pulse-soft{0%,100%{opacity:.08}50%{opacity:.18}}
@keyframes dash-flow{from{stroke-dashoffset:0}to{stroke-dashoffset:-30}}
@keyframes float-y{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}
.rune-ring{animation:rotate-cw 45s linear infinite;transform-origin:0 0}
.geo-ring{animation:rotate-ccw 28s linear infinite;transform-origin:0 0}
.inner-deco{animation:rotate-cw 18s linear infinite;transform-origin:0 0}
.candle-glow{animation:flicker 2.2s ease-in-out infinite}
.ambient-pulse{animation:pulse-soft 5s ease-in-out infinite}
.dash-anim{animation:dash-flow 1.5s linear infinite}
.float-anim{animation:float-y 4s ease-in-out infinite}
@media(prefers-reduced-motion:reduce){
    *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.15s!important}
}
@media(max-width:640px){
    .container{padding:10px 8px}
    .symbol-btn{padding:8px 14px;min-width:85px}
    .symbol-icon{font-size:20px}
    .info-panel{font-size:11.5px;padding:14px 16px}
}
</style>
</head>
<body>
<div class="container">
<header>
    <h1>ARCANE RESONANCE</h1>
    <p>IFR 理想解原理动画 — 灯光同步确认机制</p>
</header>

<div class="animation-wrapper">
<svg id="main-svg" viewBox="0 0 1400 720" xmlns="http://www.w3.org/2000/svg">
<defs>
    <!-- 发光滤镜 -->
    <filter id="glow-sm" x="-50%" y="-50%" width="200%" height="200%">
        <feGaussianBlur in="SourceGraphic" stdDeviation="4" result="b"/>
        <feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
    </filter>
    <filter id="glow-md" x="-50%" y="-50%" width="200%" height="200%">
        <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="b"/>
        <feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
    </filter>
    <filter id="glow-lg" x="-80%" y="-80%" width="260%" height="260%">
        <feGaussianBlur in="SourceGraphic" stdDeviation="22" result="b"/>
        <feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
    </filter>
    <filter id="glow-xl" x="-100%" y="-100%" width="300%" height="300%">
        <feGaussianBlur in="SourceGraphic" stdDeviation="40" result="b"/>
        <feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
    </filter>

    <!-- 房间渐变 -->
    <radialGradient id="evil-ambient" cx="50%" cy="25%" r="65%">
        <stop offset="0%" stop-color="#1a1028" stop-opacity="0.6"/>
        <stop offset="100%" stop-color="#0c0a14" stop-opacity="0"/>
    </radialGradient>
    <radialGradient id="neuro-ambient" cx="50%" cy="65%" r="60%">
        <stop offset="0%" stop-color="#101828" stop-opacity="0.6"/>
        <stop offset="100%" stop-color="#0a0c16" stop-opacity="0"/>
    </radialGradient>

    <!-- 法阵核心渐变(动态替换) -->
    <radialGradient id="core-grad" cx="50%" cy="50%" r="50%">
        <stop offset="0%" stop-color="#2a3a6a" stop-opacity="0.6"/>
        <stop offset="60%" stop-color="#1a2a4a" stop-opacity="0.2"/>
        <stop offset="100%" stop-color="#0a1020" stop-opacity="0"/>
    </radialGradient>

    <!-- 吊灯光渐变 -->
    <radialGradient id="candle-grad" cx="50%" cy="50%" r="50%">
        <stop offset="0%" stop-color="#c9a84c" stop-opacity="0.9"/>
        <stop offset="100%" stop-color="#c9a84c" stop-opacity="0"/>
    </radialGradient>

    <!-- 连接路径 -->
    <path id="wifi-path" d="M480,210 C600,80 800,80 920,380" fill="none"/>

    <!-- 符文路径 -->
    <path id="rune-circle" d="M-125,0 a125,125 0 1,1 250,0 a125,125 0 1,1 -250,0" fill="none"/>
</defs>

<!-- ===== 全局背景 ===== -->
<rect width="1400" height="720" fill="#08080e"/>

<!-- ===== 左侧:Evil密室 ===== -->
<g id="evil-chamber">
    <!-- 房间框架 -->
    <rect x="30" y="20" width="600" height="680" rx="6" fill="#0c0a14" stroke="#1e1a2a" stroke-width="1.5"/>
    <rect x="30" y="20" width="600" height="680" rx="6" fill="url(#evil-ambient)"/>
    <!-- 哥特拱顶 -->
    <path d="M30,20 Q330,-30 630,20" fill="none" stroke="#2a2440" stroke-width="1"/>
    <!-- 石墙纹理线 -->
    <line x1="30" y1="180" x2="630" y2="180" stroke="#151220" stroke-width="0.5"/>
    <line x1="30" y1="400" x2="630" y2="400" stroke="#151220" stroke-width="0.5"/>
    <line x1="30" y1="560" x2="630" y2="560" stroke="#151220" stroke-width="0.5"/>
    <line x1="200" y1="20" x2="200" y2="400" stroke="#151220" stroke-width="0.3"/>
    <line x1="460" y1="20" x2="460" y2="400" stroke="#151220" stroke-width="0.3"/>

    <!-- 房间标签 -->
    <text x="330" y="60" text-anchor="middle" font-family="Cinzel,serif" font-size="13" fill="#4a4060" letter-spacing="0.15em">EVIL CHAMBER</text>

    <!-- ===== 哥特吊灯 ===== -->
    <g id="chandelier" transform="translate(330,0)">
        <!-- 天花板底座 -->
        <ellipse cx="0" cy="82" rx="18" ry="6" fill="#3a3040" stroke="#5a4a5a" stroke-width="1"/>
        <!-- 链条 -->
        <g stroke="#5a4a5a" stroke-width="1.5" fill="none">
            <line x1="0" y1="20" x2="0" y2="68"/>
            <ellipse cx="0" cy="72" rx="4" ry="5"/>
            <ellipse cx="0" cy="82" rx="3" ry="4"/>
        </g>
        <!-- 顶部冠饰 -->
        <path d="M-14,88 Q-7,84 0,88 Q7,84 14,88" fill="#3a3040" stroke="#6a5a6a" stroke-width="0.8"/>
        <!-- 中心柱 -->
        <rect x="-6" y="88" width="12" height="18" rx="3" fill="#3a3040" stroke="#5a4a5a" stroke-width="0.8"/>
        <!-- 装饰环 -->
        <ellipse cx="0" cy="94" rx="10" ry="3" fill="none" stroke="#6a5a6a" stroke-width="0.6"/>

        <!-- 5条臂 -->
        <g stroke="#5a4a5a" fill="none" stroke-width="2.5" stroke-linecap="round">
            <path d="M0,98 C-50,100 -75,108 -95,122"/>
            <path d="M0,98 C-30,102 -48,112 -58,128"/>
            <path d="M0,98 L0,135"/>
            <path d="M0,98 C30,102 48,112 58,128"/>
            <path d="M0,98 C50,100 75,108 95,122"/>
        </g>
        <!-- 臂末端卷曲装饰 -->
        <g fill="#5a4a5a">
            <circle cx="-95" cy="122" r="3"/><circle cx="-58" cy="128" r="3"/>
            <circle cx="0" cy="135" r="3"/>
            <circle cx="58" cy="128" r="3"/><circle cx="95" cy="122" r="3"/>
        </g>

        <!-- 蜡烛座 + 灯光 -->
        <g id="candle-lights">
            <!-- 每根蜡烛:底座矩形 + 火焰圆 + 光晕圆 -->
            <g class="candle-unit" data-idx="0" transform="translate(-95,122)">
                <rect x="-3" y="-6" width="6" height="8" rx="1" fill="#4a3a3a"/>
                <circle class="flame-core" cx="0" cy="-10" r="5" fill="#c9a84c" filter="url(#glow-sm)"/>
                <circle class="flame-glow candle-glow" cx="0" cy="-10" r="22" fill="#c9a84c" opacity="0.12" filter="url(#glow-md)"/>
            </g>
            <g class="candle-unit" data-idx="1" transform="translate(-58,128)">
                <rect x="-3" y="-6" width="6" height="8" rx="1" fill="#4a3a3a"/>
                <circle class="flame-core" cx="0" cy="-10" r="5" fill="#c9a84c" filter="url(#glow-sm)"/>
                <circle class="flame-glow candle-glow" cx="0" cy="-10" r="22" fill="#c9a84c" opacity="0.12" filter="url(#glow-md)"/>
            </g>
            <g class="candle-unit" data-idx="2" transform="translate(0,135)">
                <rect x="-3" y="-6" width="6" height="8" rx="1" fill="#4a3a3a"/>
                <circle class="flame-core" cx="0" cy="-10" r="5" fill="#c9a84c" filter="url(#glow-sm)"/>
                <circle class="flame-glow candle-glow" cx="0" cy="-10" r="22" fill="#c9a84c" opacity="0.12" filter="url(#glow-md)"/>
            </g>
            <g class="candle-unit" data-idx="3" transform="translate(58,128)">
                <rect x="-3" y="-6" width="6" height="8" rx="1" fill="#4a3a3a"/>
                <circle class="flame-core" cx="0" cy="-10" r="5" fill="#c9a84c" filter="url(#glow-sm)"/>
                <circle class="flame-glow candle-glow" cx="0" cy="-10" r="22" fill="#c9a84c" opacity="0.12" filter="url(#glow-md)"/>
            </g>
            <g class="candle-unit" data-idx="4" transform="translate(95,122)">
                <rect x="-3" y="-6" width="6" height="8" rx="1" fill="#4a3a3a"/>
                <circle class="flame-core" cx="0" cy="-10" r="5" fill="#c9a84c" filter="url(#glow-sm)"/>
                <circle class="flame-glow candle-glow" cx="0" cy="-10" r="22" fill="#c9a84c" opacity="0.12" filter="url(#glow-md)"/>
            </g>
        </g>

        <!-- 水晶垂饰 -->
        <g fill="#7a7aaa" opacity="0.4">
            <path d="M-95,130 l-2,10 2,3 2,-3z"/>
            <path d="M-58,136 l-1.5,8 1.5,2.5 1.5,-2.5z"/>
            <path d="M0,143 l-2,12 2,3 2,-3z"/>
            <path d="M58,136 l-1.5,8 1.5,2.5 1.5,-2.5z"/>
            <path d="M95,130 l-2,10 2,3 2,-3z"/>
        </g>
        <!-- 底部装饰坠 -->
        <path d="M0,155 l-3,14 3,4 3,-4z" fill="#8a7aaa" opacity="0.35"/>
    </g>

    <!-- 环境光晕(吊灯周围) -->
    <circle cx="330" cy="130" r="80" fill="#c9a84c" opacity="0.04" filter="url(#glow-lg)" class="ambient-pulse" id="evil-ambient-glow"/>

    <!-- Evil人影(剪影) -->
    <g id="evil-figure" transform="translate(310,530)">
        <!-- 身体 -->
        <ellipse cx="0" cy="0" rx="18" ry="8" fill="#120e1a"/>
        <rect x="-14" y="-40" width="28" height="42" rx="8" fill="#120e1a"/>
        <!-- 头 -->
        <circle cx="0" cy="-52" r="11" fill="#120e1a"/>
        <!-- 双马尾 -->
        <path d="M-8,-56 C-20,-50 -28,-35 -26,-15" stroke="#120e1a" fill="none" stroke-width="5" stroke-linecap="round"/>
        <path d="M8,-56 C20,-50 28,-35 26,-15" stroke="#120e1a" fill="none" stroke-width="5" stroke-linecap="round"/>
        <!-- 交叉手臂(傲娇姿势) -->
        <path d="M-14,-25 L-6,-18 L6,-25" stroke="#120e1a" fill="none" stroke-width="4" stroke-linecap="round"/>
        <path d="M14,-25 L6,-18 L-6,-25" stroke="#120e1a" fill="none" stroke-width="4" stroke-linecap="round"/>
    </g>

    <!-- 语音波纹起点 -->
    <circle id="voice-origin" cx="310" cy="490" r="3" fill="none" opacity="0"/>

    <!-- 语音气泡容器 -->
    <g id="speech-bubble" opacity="0">
        <rect x="200" y="430" width="220" height="38" rx="8" fill="#1a1528" stroke="#3a3050" stroke-width="1"/>
        <polygon points="295,468 310,485 325,468" fill="#1a1528" stroke="#3a3050" stroke-width="1"/>
        <polygon points="297,468 310,482 323,468" fill="#1a1528"/>
        <text id="speech-text" x="310" y="454" text-anchor="middle" font-family="'Noto Sans SC',sans-serif" font-size="12" fill="#c9a84c"></text>
    </g>
</g>

<!-- ===== 中间连接区域 ===== -->
<g id="connection-zone">
    <!-- 分隔墙 -->
    <rect x="640" y="20" width="120" height="680" rx="0" fill="#0a0a12" stroke="#1a1a28" stroke-width="0.5"/>
    <text x="700" y="48" text-anchor="middle" font-family="Cinzel,serif" font-size="10" fill="#2a2840" letter-spacing="0.2em">WIFI BIND</text>

    <!-- 连接路径(底层虚线) -->
    <use href="#wifi-path" stroke="#1a2040" stroke-width="1.5" stroke-dasharray="6 8" class="dash-anim" fill="none"/>

    <!-- WiFi信号图标 -->
    <g transform="translate(700,180)" id="wifi-icon">
        <circle cx="0" cy="10" r="4" fill="#2a3a5a"/>
        <path d="M-10,4 A14,14 0 0,1 10,4" fill="none" stroke="#2a3a5a" stroke-width="2" stroke-linecap="round"/>
        <path d="M-20,-2 A24,24 0 0,1 20,-2" fill="none" stroke="#2a3a5a" stroke-width="2" stroke-linecap="round"/>
        <path d="M-30,-8 A34,34 0 0,1 30,-8" fill="none" stroke="#1a2a4a" stroke-width="1.5" stroke-linecap="round"/>
    </g>

    <!-- 传输脉冲容器 -->
    <g id="pulse-layer"></g>

    <!-- 箭头指示 -->
    <polygon points="890,375 900,385 890,395" fill="#1a2a4a" opacity="0.5"/>
</g>

<!-- ===== 右侧:Neuro密室 ===== -->
<g id="neuro-chamber">
    <!-- 房间框架 -->
    <rect x="770" y="20" width="600" height="680" rx="6" fill="#0a0c16" stroke="#1a1e30" stroke-width="1.5"/>
    <rect x="770" y="20" width="600" height="680" rx="6" fill="url(#neuro-ambient)"/>
    <!-- 拱顶 -->
    <path d="M770,20 Q1070,-20 1370,20" fill="none" stroke="#1a2040" stroke-width="1"/>
    <!-- 墙纹 -->
    <line x1="770" y1="200" x2="1370" y2="200" stroke="#0e1020" stroke-width="0.5"/>
    <line x1="770" y1="420" x2="1370" y2="420" stroke="#0e1020" stroke-width="0.5"/>

    <!-- 房间标签 -->
    <text x="1070" y="55" text-anchor="middle" font-family="Cinzel,serif" font-size="13" fill="#3a4060" letter-spacing="0.15em">NEURO CHAMBER</text>

    <!-- ===== 法阵 ===== -->
    <g id="magic-circle" transform="translate(1070,430)">
        <!-- 地面光晕 -->
        <circle r="180" fill="#0a1020" opacity="0.3" id="ground-glow"/>

        <!-- 外环 -->
        <circle r="155" fill="none" stroke="#1a2a4a" stroke-width="2.5"/>
        <circle r="152" fill="none" stroke="#1a2a4a" stroke-width="0.5" stroke-dasharray="2 6"/>
        <!-- 外环刻度 -->
        <g stroke="#2a3a5a" stroke-width="1" opacity="0.5">
            <line x1="0" y1="-155" x2="0" y2="-148"/>
            <line x1="77.5" y1="-134" x2="74" y2="-128"/>
            <line x1="134" y1="-77.5" x2="128" y2="-74"/>
            <line x1="155" y1="0" x2="148" y2="0"/>
            <line x1="134" y1="77.5" x2="128" y2="74"/>
            <line x1="77.5" y1="134" x2="74" y2="128"/>
            <line x1="0" y1="155" x2="0" y2="148"/>
            <line x1="-77.5" y1="134" x2="-74" y2="128"/>
            <line x1="-134" y1="77.5" x2="-128" y2="74"/>
            <line x1="-155" y1="0" x2="-148" y2="0"/>
            <line x1="-134" y1="-77.5" x2="-128" y2="-74"/>
            <line x1="-77.5" y1="-134" x2="-74" y2="-128"/>
        </g>

        <!-- 符文环(旋转) -->
        <g class="rune-ring" transform="translate(0,0)">
            <circle r="125" fill="none" stroke="#1e2e50" stroke-width="1.2"/>
            <text font-size="11" fill="#3a5a8a" opacity="0.55" letter-spacing="6">
                <textPath href="#rune-circle" startOffset="0%">ᚠ ᚢ ᚦ ᚨ ᚱ ᚲ ᚷ ᚹ ᚺ ᚾ ᛁ ᛃ ᛈ ᛇ ᛉ ᛊ ᛏ ᛒ ᛖ ᛗ ᛚ ᛞ ᛟ</textPath>
            </text>
        </g>

        <!-- 几何环(旋转) -->
        <g class="geo-ring" transform="translate(0,0)">
            <circle r="95" fill="none" stroke="#1e2e50" stroke-width="1"/>
            <!-- 六芒星 -->
            <polygon points="0,-88 76.2,44 -76.2,44" fill="none" stroke="#2a4a6a" stroke-width="1" opacity="0.5"/>
            <polygon points="0,88 76.2,-44 -76.2,-44" fill="none" stroke="#2a4a6a" stroke-width="1" opacity="0.5"/>
        </g>

        <!-- 内装饰环(旋转) -->
        <g class="inner-deco" transform="translate(0,0)">
            <circle r="58" fill="none" stroke="#1e2e50" stroke-width="1"/>
            <!-- 小菱形装饰 -->
            <g fill="#2a4a6a" opacity="0.4">
                <rect x="-4" y="-62" width="8" height="8" rx="1" transform="rotate(45,0,-58)"/>
                <rect x="-4" y="-62" width="8" height="8" rx="1" transform="rotate(45,0,-58) rotate(60,0,0)"/>
                <rect x="-4" y="-62" width="8" height="8" rx="1" transform="rotate(45,0,-58) rotate(120,0,0)"/>
                <rect x="-4" y="-62" width="8" height="8" rx="1" transform="rotate(45,0,-58) rotate(180,0,0)"/>
                <rect x="-4" y="-62" width="8" height="8" rx="1" transform="rotate(45,0,-58) rotate(240,0,0)"/>
                <rect x="-4" y="-62" width="8" height="8" rx="1" transform="rotate(45,0,-58) rotate(300,0,0)"/>
            </g>
        </g>

        <!-- 内环 -->
        <circle r="35" fill="none" stroke="#2a3a5a" stroke-width="1.5"/>

        <!-- 核心 -->
        <circle id="circle-core" r="18" fill="url(#core-grad)"/>
        <circle id="core-inner" r="8" fill="#1a2a4a" opacity="0.5"/>
        <!-- 核心光晕 -->
        <circle id="core-glow" r="50" fill="#1a2a4a" opacity="0.06" filter="url(#glow-lg)" class="ambient-pulse"/>
    </g>

    <!-- 环境光晕(法阵周围) -->
    <circle cx="1070" cy="430" r="120" fill="#1a2a4a" opacity="0.03" filter="url(#glow-xl)" class="ambient-pulse" id="neuro-ambient-glow"/>

    <!-- Neuro人影 -->
    <g id="neuro-figure" transform="translate(1070,570)">
        <ellipse cx="0" cy="0" rx="16" ry="7" fill="#0e1020"/>
        <rect x="-12" y="-38" width="24" height="40" rx="7" fill="#0e1020"/>
        <circle cx="0" cy="-50" r="10" fill="#0e1020"/>
        <!-- 头发装饰 -->
        <path d="M-10,-55 C-6,-62 6,-62 10,-55" stroke="#0e1020" fill="none" stroke-width="3" stroke-linecap="round"/>
        <!-- 一只手托下巴 -->
        <path d="M12,-35 L18,-42 L16,-50" stroke="#0e1020" fill="none" stroke-width="3.5" stroke-linecap="round"/>
    </g>

    <!-- 注意力指示器(激活时出现) -->
    <g id="attention-indicator" opacity="0" transform="translate(1070,360)">
        <line x1="0" y1="0" x2="0" y2="-30" stroke="#c9a84c" stroke-width="1.5" stroke-dasharray="3 3" opacity="0.6"/>
        <polygon points="-5,-30 0,-38 5,-30" fill="#c9a84c" opacity="0.6"/>
        <text x="12" y="-25" font-family="'Noto Sans SC',sans-serif" font-size="10" fill="#c9a84c" opacity="0.7">!</text>
    </g>
</g>

<!-- ===== 闪光覆盖层 ===== -->
<rect id="evil-flash" x="30" y="20" width="600" height="680" rx="6" fill="#c9a84c" opacity="0" pointer-events="none"/>
<rect id="neuro-flash" x="770" y="20" width="600" height="680" rx="6" fill="#1a2a4a" opacity="0" pointer-events="none"/>

<!-- ===== 共鸣标注 ===== -->
<g id="resonance-label" opacity="0" transform="translate(700,660)">
    <rect x="-120" y="-18" width="240" height="36" rx="6" fill="#12121a" stroke="#c9a84c" stroke-width="1" opacity="0.9"/>
    <text x="0" y="4" text-anchor="middle" font-family="'Noto Sans SC',sans-serif" font-size="13" fill="#c9a84c" font-weight="700" letter-spacing="0.08em">信号即确认 — 无需言语回应</text>
</g>

<!-- ===== IFR关键标注(激活时显示) ===== -->
<g id="ifr-annotation" opacity="0" transform="translate(700,120)">
    <rect x="-140" y="-14" width="280" height="28" rx="5" fill="#0e0e18" stroke="rgba(201,168,76,0.4)" stroke-width="1"/>
    <text x="0" y="4" text-anchor="middle" font-family="'Noto Sans SC',sans-serif" font-size="11" fill="rgba(201,168,76,0.8)" letter-spacing="0.06em">灯光 = 信号发送 + 通信确认(双重功能合一)</text>
</g>

<!-- ===== 动态元素层 ===== -->
<g id="dynamic-layer"></g>

</svg>
</div>

<!-- 控制面板 -->
<div class="control-panel">
    <button class="symbol-btn moon" data-symbol="moon" data-color="#ff2d55" aria-label="月亮符号-红色">
        <span class="symbol-icon">☽</span>
        <span class="symbol-name">月亮</span>
        <span class="symbol-color-tag">RED</span>
    </button>
    <button class="symbol-btn sun" data-symbol="sun" data-color="#00b4ff" aria-label="太阳符号-蓝色">
        <span class="symbol-icon">☀</span>
        <span class="symbol-name">太阳</span>
        <span class="symbol-color-tag">BLUE</span>
    </button>
    <button class="symbol-btn star" data-symbol="star" data-color="#00ff88" aria-label="星星符号-绿色">
        <span class="symbol-icon">✦</span>
        <span class="symbol-name">星星</span>
        <span class="symbol-color-tag">GREEN</span>
    </button>
    <button class="reset-btn" id="reset-btn" aria-label="重置动画">重置</button>
    <div class="status-bar">
        <p class="status-text" id="status-text">等待信号输入 ...</p>
    </div>
</div>

<!-- IFR说明 -->
<div class="info-panel">
    <h3>IDEAL FINAL RESULT</h3>
    <p><span class="hl">核心矛盾:</span>Evil需要确认信息已被接收,但羞于等待言语回应;Neuro需要强刺激才能注意力集中。</p>
    <p><span class="hl">理想解:</span>利用密室中<span class="hl">已有的灯光资源</span>,将"通信确认"工程动作替换为"魔法共鸣"场效应。灯光变色同时承担<span class="hl">信号发送</span>与<span class="hl">确认收到</span>双重功能——Evil看到灯亮即知对方收到(保护自尊),Neuro被强视觉刺激吸引(不走神)。</p>
    <div class="ifr-core">
        <span class="hl">IFR终极理想:</span>系统自行确认通信,无需额外的人为回应环节。灯光变化本身就是确认——矛盾在资源复用中消融,系统复杂度极低(仅WiFi绑定+语音关键词提取)。
    </div>
</div>
</div>

<script>
(function(){
    /* ===== 常量与配置 ===== */
    const SVG_NS = 'http://www.w3.org/2000/svg';
    const svg = document.getElementById('main-svg');
    const dynamicLayer = document.getElementById('dynamic-layer');
    const statusText = document.getElementById('status-text');

    /* 符号配置 */
    const SYMBOLS = {
        moon: { color: '#ff2d55', name: '月亮', keyword: '我看到月亮符号了' },
        sun:  { color: '#00b4ff', name: '太阳', keyword: '我看到太阳符号了' },
        star: { color: '#00ff88', name: '星星', keyword: '我看到星星符号了' }
    };

    let isAnimating = false;
    let currentState = 'idle';
    let activeSymbol = null;

    /* ===== DOM引用 ===== */
    const candleUnits = document.querySelectorAll('.candle-unit');
    const flameCores = document.querySelectorAll('.flame-core');
    const flameGlows = document.querySelectorAll('.flame-glow');
    const circleCore = document.getElementById('circle-core');
    const coreInner = document.getElementById('core-inner');
    const coreGlow = document.getElementById('core-glow');
    const evilFlash = document.getElementById('evil-flash');
    const neuroFlash = document.getElementById('neuro-flash');
    const evilAmbientGlow = document.getElementById('evil-ambient-glow');
    const neuroAmbientGlow = document.getElementById('neuro-ambient-glow');
    const speechBubble = document.getElementById('speech-bubble');
    const speechTextEl = document.getElementById('speech-text');
    const attentionIndicator = document.getElementById('attention-indicator');
    const resonanceLabel = document.getElementById('resonance-label');
    const ifrAnnotation = document.getElementById('ifr-annotation');
    const wifiIcon = document.getElementById('wifi-icon');
    const wifiPath = document.getElementById('wifi-path');

    /* ===== 工具函数 ===== */
    function delay(ms) { return new Promise(r => setTimeout(r, ms)); }

    function setStatus(text, active = false) {
        statusText.textContent = text;
        statusText.classList.toggle('active', active);
    }

    function createSVGElement(tag, attrs) {
        const el = document.createElementNS(SVG_NS, tag);
        for (const [k, v] of Object.entries(attrs)) {
            el.setAttribute(k, v);
        }
        return el;
    }

    function lerp(a, b, t) { return a + (b - a) * t; }

    /* ===== 动画:语音波纹 ===== */
    async function animateVoiceWaves(cx, cy, color) {
        const waveCount = 4;
        const promises = [];
        for (let i = 0; i < waveCount; i++) {
            promises.push(new Promise(resolve => {
                setTimeout(() => {
                    const wave = createSVGElement('circle', {
                        cx, cy, r: 12,
                        fill: 'none', stroke: color || '#c9a84c',
                        'stroke-width': 2, opacity: 0.8,
                        filter: 'url(#glow-sm)'
                    });
                    dynamicLayer.appendChild(wave);

                    const start = performance.now();
                    const duration = 900;
                    function step(now) {
                        const p = Math.min((now - start) / duration, 1);
                        const r = 12 + p * 55;
                        const opacity = 0.8 * (1 - p);
                        const sw = 2 * (1 - p * 0.6);
                        wave.setAttribute('r', r);
                        wave.setAttribute('opacity', opacity);
                        wave.setAttribute('stroke-width', sw);
                        if (p < 1) requestAnimationFrame(step);
                        else { wave.remove(); resolve(); }
                    }
                    requestAnimationFrame(step);
                }, i * 180);
            }));
        }
        await Promise.all(promises);
    }

    /* ===== 动画:传输脉冲 ===== */
    async function animateTransmissionPulse(color) {
        const pathLength = wifiPath.getTotalLength();
        const pulseCount = 3;
        const promises = [];

        for (let i = 0; i < pulseCount; i++) {
            promises.push(new Promise(resolve => {
                setTimeout(() => {
                    /* 主脉冲 */
                    const pulse = createSVGElement('circle', {
                        r: 6, fill: color, opacity: 0.95,
                        filter: 'url(#glow-md)'
                    });
                    /* 拖尾 */
                    const trail = createSVGElement('circle', {
                        r: 10, fill: color, opacity: 0.3,
                        filter: 'url(#glow-lg)'
                    });
                    dynamicLayer.appendChild(trail);
                    dynamicLayer.appendChild(pulse);

                    const start = performance.now();
                    const duration = 700;

                    function step(now) {
                        const p = Math.min((now - start) / duration, 1);
                        const point = wifiPath.getPointAtLength(p * pathLength);
                        const trailPoint = wifiPath.getPointAtLength(Math.max(0, p - 0.06) * pathLength);

                        pulse.setAttribute('cx', point.x);
                        pulse.setAttribute('cy', point.y);
                        trail.setAttribute('cx', trailPoint.x);
                        trail.setAttribute('cy', trailPoint.y);

                        /* 淡出 */
                        if (p > 0.7) {
                            const fadeP = (p - 0.7) / 0.3;
                            pulse.setAttribute('opacity', 0.95 * (1 - fadeP));
                            trail.setAttribute('opacity', 0.3 * (1 - fadeP));
                        }

                        if (p < 1) requestAnimationFrame(step);
                        else { pulse.remove(); trail.remove(); resolve(); }
                    }
                    requestAnimationFrame(step);
                }, i * 200);
            }));
        }
        await Promise.all(promises);
    }

    /* ===== 动画:粒子爆发 ===== */
    async function animateParticleBurst(cx, cy, color, count = 16) {
        const promises = [];
        for (let i = 0; i < count; i++) {
            promises.push(new Promise(resolve => {
                const angle = (Math.PI * 2 / count) * i + Math.random() * 0.3;
                const speed = 40 + Math.random() * 50;
                const dx = Math.cos(angle) * speed;
                const dy = Math.sin(angle) * speed;
                const size = 2 + Math.random() * 3;

                const p = createSVGElement('circle', {
                    cx, cy, r: size,
                    fill: color, opacity: 0.9,
                    filter: 'url(#glow-sm)'
                });
                dynamicLayer.appendChild(p);

                const start = performance.now();
                const duration = 600 + Math.random() * 400;

                function step(now) {
                    const t = Math.min((now - start) / duration, 1);
                    const ease = 1 - Math.pow(1 - t, 3); // easeOutCubic
                    p.setAttribute('cx', cx + dx * ease);
                    p.setAttribute('cy', cy + dy * ease);
                    p.setAttribute('opacity', 0.9 * (1 - t));
                    p.setAttribute('r', size * (1 - t * 0.5));
                    if (t < 1) requestAnimationFrame(step);
                    else { p.remove(); resolve(); }
                }
                requestAnimationFrame(step);
            }));
        }
        await Promise.all(promises);
    }

    /* ===== 动画:灯光颜色过渡 ===== */
    function setChandelierColor(color, duration = 500) {
        candleUnits.forEach((unit, i) => {
            const core = unit.querySelector('.flame-core');
            const glow = unit.querySelector('.flame-glow');
            setTimeout(() => {
                core.style.transition = `fill ${duration}ms ease`;
                glow.style.transition = `fill ${duration}ms ease, opacity ${duration}ms ease`;
                core.setAttribute('fill', color);
                glow.setAttribute('fill', color);
                glow.setAttribute('opacity', '0.25');
            }, i * 60);
        });
    }

    function setMagicCircleColor(color, duration = 500) {
        circleCore.style.transition = `fill ${duration}ms ease`;
        coreInner.style.transition = `fill ${duration}ms ease`;
        coreGlow.style.transition = `fill ${duration}ms ease, opacity ${duration}ms ease`;

        /* 更新渐变 */
        const grad = document.getElementById('core-grad');
        const stops = grad.querySelectorAll('stop');
        stops[0].style.transition = `stop-color ${duration}ms ease`;
        stops[1].style.transition = `stop-color ${duration}ms ease`;
        stops[0].setAttribute('stop-color', color);
        stops[0].setAttribute('stop-opacity', '0.8');
        stops[1].setAttribute('stop-color', color);
        stops[1].setAttribute('stop-opacity', '0.3');

        coreInner.setAttribute('fill', color);
        coreInner.setAttribute('opacity', '0.7');
        coreGlow.setAttribute('fill', color);
        coreGlow.setAttribute('opacity', '0.15');
    }

    /* ===== 动画:闪光效果 ===== */
    async function flashEffect(element, color, maxOpacity = 0.25) {
        element.setAttribute('fill', color);
        element.setAttribute('opacity', maxOpacity);

        const start = performance.now();
        const duration = 600;
        function step(now) {
            const p = Math.min((now - start) / duration, 1);
            const opacity = maxOpacity * (1 - p);
            element.setAttribute('opacity', opacity);
            if (p < 1) requestAnimationFrame(step);
        }
        requestAnimationFrame(step);
        await delay(duration);
    }

    /* ===== 动画:环境光变色 ===== */
    function setAmbientGlow(element, color, opacity = 0.08) {
        element.style.transition = 'fill 600ms ease, opacity 600ms ease';
        element.setAttribute('fill', color);
        element.setAttribute('opacity', opacity);
    }

    /* ===== 动画:WiFi图标激活 ===== */
    async function animateWiFiIcon(color) {
        const paths = wifiIcon.querySelectorAll('path');
        const circle = wifiIcon.querySelector('circle');
        paths.forEach((p, i) => {
            p.style.transition = `stroke ${300}ms ease`;
            p.setAttribute('stroke', color);
        });
        circle.style.transition = `fill ${300}ms ease`;
        circle.setAttribute('fill', color);
    }

    /* ===== 重置所有视觉状态 ===== */
    function resetVisuals() {
        /* 吊灯颜色 */
        const defaultFlame = '#c9a84c';
        flameCores.forEach(c => {
            c.style.transition = 'fill 400ms ease';
            c.setAttribute('fill', defaultFlame);
        });
        flameGlows.forEach(g => {
            g.style.transition = 'fill 400ms ease, opacity 400ms ease';
            g.setAttribute('fill', defaultFlame);
            g.setAttribute('opacity', '0.12');
        });

        /* 法阵颜色 */
        const grad = document.getElementById('core-grad');
        const stops = grad.querySelectorAll('stop');
        stops[0].setAttribute('stop-color', '#2a3a6a');
        stops[0].setAttribute('stop-opacity', '0.6');
        stops[1].setAttribute('stop-color', '#1a2a4a');
        stops[1].setAttribute('stop-opacity', '0.2');
        coreInner.setAttribute('fill', '#1a2a4a');
        coreInner.setAttribute('opacity', '0.5');
        coreGlow.setAttribute('fill', '#1a2a4a');
        coreGlow.setAttribute('opacity', '0.06');

        /* 闪光 */
        evilFlash.setAttribute('opacity', '0');
        neuroFlash.setAttribute('opacity', '0');

        /* 环境光 */
        evilAmbientGlow.setAttribute('fill', '#c9a84c');
        evilAmbientGlow.setAttribute('opacity', '0.04');
        neuroAmbientGlow.setAttribute('fill', '#1a2a4a');
        neuroAmbientGlow.setAttribute('opacity', '0.03');

        /* 语音气泡 */
        speechBubble.setAttribute('opacity', '0');

        /* 注意力指示 */
        attentionIndicator.setAttribute('opacity', '0');

        /* 共鸣标注 */
        resonanceLabel.setAttribute('opacity', '0');

        /* IFR标注 */
        ifrAnnotation.setAttribute('opacity', '0');

        /* WiFi图标 */
        const wifiPaths = wifiIcon.querySelectorAll('path');
        const wifiCircle = wifiIcon.querySelector('circle');
        wifiPaths[0].setAttribute('stroke', '#2a3a5a');
        wifiPaths[1].setAttribute('stroke', '#2a3a5a');
        wifiPaths[2].setAttribute('stroke', '#1a2a4a');
        wifiCircle.setAttribute('fill', '#2a3a5a');

        /* 清理动态层 */
        while (dynamicLayer.firstChild) dynamicLayer.firstChild.remove();

        /* 按钮状态 */
        document.querySelectorAll('.symbol-btn').forEach(b => b.classList.remove('active'));

        activeSymbol = null;
        currentState = 'idle';
    }

    /* ===== 主动画序列 ===== */
    async function runSequence(symbolKey) {
        if (isAnimating) return;
        isAnimating = true;

        const config = SYMBOLS[symbolKey];
        const color = config.color;

        /* 重置到干净状态 */
        resetVisuals();
        await delay(150);

        activeSymbol = symbolKey;
        document.querySelector(`.symbol-btn.${symbolKey}`).classList.add('active');

        /* === 阶段1:Evil发声 === */
        currentState = 'speaking';
        setStatus(`Evil: "${config.keyword}"`, true);

        /* 显示语音气泡 */
        speechTextEl.textContent = config.keyword;
        speechBubble.setAttribute('opacity', '1');

        /* 语音波纹 */
        await animateVoiceWaves(310, 490, '#c9a84c');
        await delay(200);

        /* === 阶段2:语音识别处理 === */
        currentState = 'processing';
        setStatus('语音识别: 提取关键词 → ' + config.name, true);

        /* 识别闪烁 - 吊灯微闪 */
        evilFlash.setAttribute('fill', color);
        evilFlash.setAttribute('opacity', '0.08');
        await delay(200);
        evilFlash.setAttribute('opacity', '0');

        await delay(300);

        /* === 阶段3:吊灯变色 === */
        currentState = 'chandelier';
        setStatus('Evil密室吊灯 → ' + config.name + '色', true);

        setChandelierColor(color, 600);
        setAmbientGlow(evilAmbientGlow, color, 0.1);

        /* 吊灯闪光 */
        await flashEffect(evilFlash, color, 0.15);
        await delay(300);

        /* === 阶段4:WiFi传输 === */
        currentState = 'transmitting';
        setStatus('WiFi信号同步传输中 ...', true);

        animateWiFiIcon(color);
        await animateTransmissionPulse(color);
        await delay(200);

        /* === 阶段5:法阵激活 === */
        currentState = 'circle';
        setStatus('Neuro密室法阵共鸣激活!', true);

        setMagicCircleColor(color, 500);
        setAmbientGlow(neuroAmbientGlow, color, 0.08);

        /* 法阵闪光 + 粒子 */
        flashEffect(neuroFlash, color, 0.2);
        animateParticleBurst(1070, 430, color, 20);
        await delay(400);

        /* Neuro注意力指示 */
        attentionIndicator.setAttribute('opacity', '1');
        await delay(500);

        /* === 阶段6:共鸣确认 === */
        currentState = 'resonance';
        setStatus('魔法共鸣 — 信号即确认,通信链路完整', true);

        /* 共鸣标注浮现 */
        resonanceLabel.setAttribute('opacity', '1');
        await delay(300);

        /* IFR核心标注 */
        ifrAnnotation.setAttribute('opacity', '1');

        /* 最终同步闪光 */
        await flashEffect(evilFlash, color, 0.12);
        await flashEffect(neuroFlash, color, 0.12);

        /* 隐藏语音气泡 */
        speechBubble.setAttribute('opacity', '0');

        currentState = 'confirmed';
        isAnimating = false;
    }

    /* ===== 事件绑定 ===== */
    document.querySelectorAll('.symbol-btn').forEach(btn => {
        btn.addEventListener('click', () => {
            const symbol = btn.dataset.symbol;
            if (symbol) runSequence(symbol);
        });
    });

    document.getElementById('reset-btn').addEventListener('click', () => {
        if (isAnimating) return;
        resetVisuals();
        setStatus('等待信号输入 ...');
    });

    /* ===== 键盘快捷键 ===== */
    document.addEventListener('keydown', (e) => {
        if (e.key === '1') runSequence('moon');
        else if (e.key === '2') runSequence('sun');
        else if (e.key === '3') runSequence('star');
        else if (e.key === 'r' || e.key === 'R') {
            if (!isAnimating) { resetVisuals(); setStatus('等待信号输入 ...'); }
        }
    });

    /* ===== 空闲粒子效果 ===== */
    function spawnAmbientParticle() {
        if (currentState !== 'idle') return;

        const isLeft = Math.random() > 0.5;
        const x = isLeft ? 80 + Math.random() * 500 : 820 + Math.random() * 500;
        const y = 100 + Math.random() * 500;
        const color = isLeft ? '#c9a84c' : '#3a5a8a';

        const p = createSVGElement('circle', {
            cx: x, cy: y, r: 1 + Math.random() * 1.5,
            fill: color, opacity: 0
        });
        dynamicLayer.appendChild(p);

        const start = performance.now();
        const duration = 2000 + Math.random() * 3000;
        const dy = -(20 + Math.random() * 30);
        const dx = (Math.random() - 0.5) * 20;

        function step(now) {
            const t = Math.min((now - start) / duration, 1);
            const ease = t;
            p.setAttribute('cx', x + dx * ease);
            p.setAttribute('cy', y + dy * ease);
            /* 淡入淡出 */
            const opacity = t < 0.3 ? t / 0.3 : t > 0.7 ? (1 - t) / 0.3 : 1;
            p.setAttribute('opacity', opacity * 0.35);
            if (t < 1) requestAnimationFrame(step);
            else p.remove();
        }
        requestAnimationFrame(step);
    }

    /* 定期生成环境粒子 */
    setInterval(spawnAmbientParticle, 400);

    /* 初始状态 */
    setStatus('等待信号输入 ... 点击符号按钮或按 1/2/3 触发');

})();
</script>
</body>
</html>

实现说明

视觉设计方向:深邃的暗黑哥特+神秘学美学,两个密室拥有截然不同的氛围——Evil侧是冷紫调的哥特石室配金色烛光吊灯,Neuro侧是深蓝调的星辰法阵室。中间以WiFi绑定区域连接,形成完整的信息通道。

核心动画序列(点击月亮/太阳/星星触发):

  1. Evil发声 — 语音气泡出现 + 扩散波纹从人影发出
  2. 语音识别 — 吊灯微闪,关键词被提取
  3. 吊灯变色 — 5支蜡烛依次过渡为目标色(红/蓝/绿),配合闪光效果
  4. WiFi传输 — 3个光脉冲沿弧线路径从左室飞向右室,带拖尾
  5. 法阵激活 — 核心渐变变色 + 粒子爆发 + 房间闪光 + Neuro注意力指示器
  6. 共鸣确认 — 双室同步微闪,浮现"信号即确认—无需言语回应"标注和IFR双重功能标注

IFR原理体现

  • 灯光变色同时承担信号发送与通信确认双重功能,无需额外言语回应环节
  • 利用了两个密室中已有的灯光资源(吊灯+法阵),仅增加WiFi绑定和语音提取,系统复杂度极低
  • 动画最终状态明确标注"灯光 = 信号发送 + 通信确认(双重功能合一)"

交互方式:点击三个符号按钮或按键盘 1/2/3 触发不同颜色的共鸣序列,按 R 或点击重置回归待机状态。空闲时有漂浮的环境粒子营造氛围。

积分规则:第一轮对话扣减6分,后续每轮扣4分