分享图
动画工坊
引擎就绪
<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>串列双翼太阳能 VTOL 原理可视化</title>
  <style>
    :root {
      --bg-color: #070c14;
      --panel-bg: rgba(13, 23, 38, 0.72);
      --panel-border: rgba(56, 189, 248, 0.18);
      --accent-solar: #f59e0b;
      --accent-solar-glow: rgba(245, 158, 11, 0.4);
      --accent-cyan: #38bdf8;
      --accent-thrust: #60a5fa;
      --accent-battery: #10b981;
      --accent-warn: #f43f5e;
      --text-main: #e2e8f0;
      --text-muted: #94a3b8;
      --font-mono: ui-monospace, SFMono-Regular, "JetBrains Mono", Menlo, Consolas, monospace;
      --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
    }

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

    body {
      background-color: var(--bg-color);
      color: var(--text-main);
      font-family: var(--font-sans);
      width: 100vw;
      height: 100vh;
      overflow: hidden;
      display: flex;
      flex-direction: column;
      position: relative;
    }

    /* 科技感背景网格 */
    .bg-grid {
      position: absolute;
      inset: 0;
      background-image: 
        radial-gradient(ellipse at 50% 35%, rgba(14, 165, 233, 0.12) 0%, transparent 60%),
        linear-gradient(to right, rgba(255, 255, 255, 0.03) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
      background-size: 100% 100%, 48px 48px, 48px 48px;
      pointer-events: none;
      z-index: 1;
    }

    /* 主画布区域:SVG居中满幅,占据绝对视觉主角 */
    .stage-container {
      position: relative;
      flex: 1;
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      z-index: 2;
    }

    svg#main-svg {
      width: 100%;
      height: 100%;
      max-width: 1400px;
      max-height: 860px;
      filter: drop-shadow(0 0 24px rgba(0, 0, 0, 0.6));
    }

    /* 轻量边角 HUD 说明(字号小、避开中央,绝不遮挡核心动画) */
    .hud-header {
      position: absolute;
      top: 16px;
      left: 20px;
      z-index: 10;
      display: flex;
      flex-direction: column;
      gap: 4px;
      pointer-events: none;
    }
    .hud-title {
      font-size: 15px;
      font-weight: 700;
      letter-spacing: 0.06em;
      color: #f8fafc;
      display: flex;
      align-items: center;
      gap: 8px;
    }
    .hud-badge {
      font-size: 10px;
      padding: 2px 6px;
      border-radius: 4px;
      background: rgba(16, 185, 129, 0.18);
      color: #34d399;
      border: 1px solid rgba(52, 211, 153, 0.35);
      font-family: var(--font-mono);
    }
    .hud-sub {
      font-size: 11px;
      color: var(--text-muted);
      letter-spacing: 0.02em;
    }

    /* 右上角实时能量收支仪表盘 */
    .hud-metrics {
      position: absolute;
      top: 16px;
      right: 20px;
      z-index: 10;
      background: var(--panel-bg);
      border: 1px solid var(--panel-border);
      backdrop-filter: blur(10px);
      padding: 10px 14px;
      border-radius: 8px;
      font-family: var(--font-mono);
      font-size: 11px;
      display: flex;
      flex-direction: column;
      gap: 6px;
      min-width: 210px;
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
    }
    .metric-row {
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
    .metric-name {
      color: var(--text-muted);
      display: flex;
      align-items: center;
      gap: 6px;
    }
    .metric-val {
      font-weight: 700;
      color: #f1f5f9;
    }
    .dot-solar { width: 7px; height: 7px; border-radius: 50%; background: var(--accent-solar); box-shadow: 0 0 6px var(--accent-solar); }
    .dot-thrust { width: 7px; height: 7px; border-radius: 50%; background: var(--accent-thrust); box-shadow: 0 0 6px var(--accent-thrust); }
    .dot-net { width: 7px; height: 7px; border-radius: 50%; background: var(--accent-battery); box-shadow: 0 0 6px var(--accent-battery); }

    /* 状态阶段指示条 */
    .mode-bar {
      margin-top: 4px;
      padding-top: 6px;
      border-top: 1px solid rgba(255, 255, 255, 0.08);
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
    .mode-tag {
      font-weight: 700;
      font-size: 11px;
      padding: 1px 6px;
      border-radius: 3px;
    }
    .mode-cruise {
      color: #38bdf8;
      background: rgba(56, 189, 248, 0.15);
      border: 1px solid rgba(56, 189, 248, 0.3);
    }
    .mode-vtol {
      color: #f43f5e;
      background: rgba(244, 63, 94, 0.15);
      border: 1px solid rgba(244, 63, 94, 0.3);
    }

    /* 底部控制托盘(紧凑、半透明悬浮) */
    .bottom-bar {
      position: absolute;
      bottom: 14px;
      left: 50%;
      transform: translateX(-50%);
      z-index: 10;
      display: flex;
      align-items: center;
      gap: 16px;
      background: var(--panel-bg);
      border: 1px solid var(--panel-border);
      backdrop-filter: blur(10px);
      padding: 8px 18px;
      border-radius: 30px;
      font-size: 12px;
      box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
    }
    .btn-play {
      background: #0284c7;
      border: none;
      color: #ffffff;
      width: 28px;
      height: 28px;
      border-radius: 50%;
      cursor: pointer;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 12px;
      transition: all 0.2s ease;
      outline: none;
    }
    .btn-play:hover {
      background: #0ea5e9;
      box-shadow: 0 0 10px rgba(14, 165, 233, 0.6);
      transform: scale(1.05);
    }
    .stage-tabs {
      display: flex;
      gap: 6px;
    }
    .stage-chip {
      padding: 4px 10px;
      border-radius: 14px;
      cursor: pointer;
      background: rgba(255, 255, 255, 0.05);
      border: 1px solid rgba(255, 255, 255, 0.1);
      color: var(--text-muted);
      font-size: 11px;
      transition: all 0.2s;
    }
    .stage-chip:hover {
      background: rgba(255, 255, 255, 0.12);
      color: #fff;
    }
    .stage-chip.active {
      background: rgba(56, 189, 248, 0.2);
      border-color: #38bdf8;
      color: #38bdf8;
      font-weight: 600;
      box-shadow: 0 0 8px rgba(56, 189, 248, 0.25);
    }
    .scrubber {
      width: 130px;
      accent-color: #38bdf8;
      cursor: pointer;
    }
    .legend-chip {
      display: flex;
      align-items: center;
      gap: 5px;
      font-size: 11px;
      color: var(--text-muted);
    }

    /* 动画关键帧与微动 */
    @keyframes pulseGlow {
      0%, 100% { opacity: 0.35; filter: drop-shadow(0 0 6px var(--accent-solar-glow)); }
      50% { opacity: 0.85; filter: drop-shadow(0 0 14px var(--accent-solar)); }
    }
    @keyframes propSpin {
      from { transform: rotate(0deg); }
      to { transform: rotate(360deg); }
    }
    @keyframes flowDash {
      to { stroke-dashoffset: -40; }
    }
    @keyframes flowDashReverse {
      to { stroke-dashoffset: 40; }
    }

    .solar-pulse {
      animation: pulseGlow 2.4s ease-in-out infinite;
    }
    .flow-line {
      stroke-dasharray: 6, 4;
      animation: flowDash 0.8s linear infinite;
    }
    .flow-reverse {
      stroke-dasharray: 6, 4;
      animation: flowDashReverse 0.8s linear infinite;
    }
  </style>
</head>
<body>
  <!-- 背景网格修饰 -->
  <div class="bg-grid"></div>

  <!-- 左上轻量概览说明(不遮挡主飞行器) -->
  <header class="hud-header">
    <div class="hud-title">
      <span>TANDEM-WING SOLAR VTOL</span>
      <span class="hud-badge">IFR 最终理想解</span>
    </div>
    <div class="hud-sub">串列翼气动解耦 · 旋翼悬停与翼面巡航时序分离 · 净能正收益闭环</div>
  </header>

  <!-- 右上角能量状态仪表板 -->
  <div class="hud-metrics">
    <div class="metric-row">
      <span class="metric-name"><span class="dot-solar"></span>薄膜光伏收集</span>
      <span class="metric-val" id="val-solar">126.5 W</span>
    </div>
    <div class="metric-row">
      <span class="metric-name"><span class="dot-thrust"></span>整机动力+航电</span>
      <span class="metric-val" id="val-thrust">57.0 W</span>
    </div>
    <div class="metric-row">
      <span class="metric-name"><span class="dot-net"></span>能量自持净盈余</span>
      <span class="metric-val" style="color: #34d399;" id="val-net">+69.5 W</span>
    </div>
    <div class="mode-bar">
      <span style="color: var(--text-muted);">气动模态 / 升阻比</span>
      <span class="mode-tag mode-cruise" id="val-aero">巡航 L/D = 18</span>
    </div>
  </div>

  <!-- SVG 原理核心主画布 -->
  <main class="stage-container">
    <svg id="main-svg" viewBox="0 0 1000 620" preserveAspectRatio="xMidYMid meet">
      <defs>
        <!-- 渐变定义 -->
        <linearGradient id="cigsGradient" x1="0%" y1="0%" x2="100%" y2="100%">
          <stop offset="0%" stop-color="#1e293b" />
          <stop offset="45%" stop-color="#1e3a5f" />
          <stop offset="70%" stop-color="#2563eb" />
          <stop offset="100%" stop-color="#0284c7" />
        </linearGradient>

        <linearGradient id="sunBeam" x1="0%" y1="0%" x2="0%" y2="100%">
          <stop offset="0%" stop-color="#f59e0b" stop-opacity="0.35" />
          <stop offset="100%" stop-color="#fbbf24" stop-opacity="0" />
        </linearGradient>

        <radialGradient id="sunOrigin" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stop-color="#fef08a" />
          <stop offset="40%" stop-color="#f59e0b" stop-opacity="0.8" />
          <stop offset="100%" stop-color="#b45309" stop-opacity="0" />
        </radialGradient>

        <linearGradient id="fuselageGrad" x1="0%" y1="0%" x2="100%" y2="0%">
          <stop offset="0%" stop-color="#334155" />
          <stop offset="35%" stop-color="#0f172a" />
          <stop offset="65%" stop-color="#1e293b" />
          <stop offset="100%" stop-color="#090d16" />
        </linearGradient>

        <filter id="glow" x="-30%" y="-30%" width="160%" height="160%">
          <feGaussianBlur stdDeviation="3" result="blur" />
          <feComposite in="SourceGraphic" in2="blur" operator="over" />
        </filter>

        <!-- 太阳能电池网格纹理 -->
        <pattern id="solarGrid" width="12" height="12" patternUnits="userSpaceOnUse">
          <path d="M 12 0 L 0 0 0 12" fill="none" stroke="rgba(56, 189, 248, 0.22)" stroke-width="0.75" />
        </pattern>

        <!-- 气流微粒标记 -->
        <marker id="arrowHead" viewBox="0 0 8 8" refX="4" refY="4" markerWidth="4" markerHeight="4" orient="auto">
          <polygon points="0 1, 7 4, 0 7" fill="#38bdf8" />
        </marker>
      </defs>

      <!-- 1. 光照与能量场层 -->
      <g id="sun-layer">
        <!-- 模拟高空太阳光伏射场 -->
        <circle cx="500" cy="-60" r="140" fill="url(#sunOrigin)" filter="url(#glow)" />
        <g id="photon-beams" opacity="0.6">
          <polygon points="400,0 260,260 290,260" fill="url(#sunBeam)" />
          <polygon points="460,0 380,260 410,260" fill="url(#sunBeam)" />
          <polygon points="540,0 590,260 620,260" fill="url(#sunBeam)" />
          <polygon points="600,0 710,260 740,260" fill="url(#sunBeam)" />
          <polygon points="320,0 120,380 150,380" fill="url(#sunBeam)" />
          <polygon points="680,0 850,380 880,380" fill="url(#sunBeam)" />
        </g>
        <!-- 漂浮的光子粒子 -->
        <g id="photons-particles"></g>
      </g>

      <!-- 2. 空气动力学流线层(巡航高升阻比气流) -->
      <g id="aero-streamlines" opacity="0.35">
        <path d="M 60,240 C 220,240 380,225 500,225 C 640,225 780,240 940,240" fill="none" stroke="#38bdf8" stroke-width="1.2" stroke-dasharray="8 12" class="flow-line" />
        <path d="M 40,290 C 240,290 380,270 500,270 C 640,270 760,290 960,290" fill="none" stroke="#38bdf8" stroke-width="1.5" stroke-dasharray="10 14" class="flow-line" />
        <path d="M 70,350 C 260,350 400,340 500,340 C 620,340 740,350 930,350" fill="none" stroke="#38bdf8" stroke-width="1.2" stroke-dasharray="8 10" class="flow-line" />
      </g>

      <!-- 3. 飞行器主体组(俯仰角三维轴测透视俯视) -->
      <g id="aircraft-group" transform="translate(0, 0)">
        
        <!-- ================= 后翼(上翼后掠布局,抬高布置) ================= -->
        <g id="aft-wing">
          <!-- 机翼底衬 -->
          <polygon points="210,195 500,220 790,195 770,250 500,265 230,250" fill="#0b1329" stroke="rgba(56, 189, 248, 0.4)" stroke-width="1.5" />
          <!-- CIGS 柔性薄膜光伏上表面铺覆 -->
          <polygon id="aft-cigs" points="214,198 500,222 786,198 766,247 500,262 234,247" fill="url(#cigsGradient)" />
          <polygon points="214,198 500,222 786,198 766,247 500,262 234,247" fill="url(#solarGrid)" opacity="0.65" />
          <!-- 翼展尺寸与光伏微光 -->
          <line x1="205" y1="195" x2="205" y2="250" stroke="#f59e0b" stroke-width="2" opacity="0.7" />
          <line x1="795" y1="195" x2="795" y2="250" stroke="#f59e0b" stroke-width="2" opacity="0.7" />
          <!-- 后翼两端垂直翼梢小翼 -->
          <polygon points="208,188 214,196 230,254 224,258" fill="#1e293b" stroke="#38bdf8" stroke-width="1" />
          <polygon points="792,188 786,196 770,254 776,258" fill="#1e293b" stroke="#38bdf8" stroke-width="1" />
        </g>

        <!-- ================= 尾撑杆与机体连接构架 ================= -->
        <g id="booms" stroke="#475569" stroke-width="3">
          <line x1="330" y1="230" x2="330" y2="400" />
          <line x1="670" y1="230" x2="670" y2="400" />
        </g>

        <!-- ================= 前翼(下翼前掠布局,翼展更宽,降低下洗干扰) ================= -->
        <g id="fore-wing">
          <!-- 机翼碳纤维基体 -->
          <polygon points="120,380 500,345 880,380 860,430 500,388 140,430" fill="#0f172a" stroke="rgba(56, 189, 248, 0.5)" stroke-width="1.5" />
          <!-- CIGS 柔性薄膜上表面共形贴合 -->
          <polygon id="fore-cigs" points="125,382 500,348 875,382 855,426 500,385 145,426" fill="url(#cigsGradient)" />
          <polygon points="125,382 500,348 875,382 855,426 500,385 145,426" fill="url(#solarGrid)" opacity="0.65" />
          <!-- 翼尖垂尾 -->
          <polygon points="116,370 125,380 144,435 135,440" fill="#1e293b" stroke="#38bdf8" stroke-width="1" />
          <polygon points="884,370 875,380 856,435 865,440" fill="#1e293b" stroke="#38bdf8" stroke-width="1" />
        </g>

        <!-- ================= 中央流线机身与航电设备舱 ================= -->
        <g id="fuselage">
          <!-- 流线型修长机身 -->
          <path d="M 490,175 C 490,165 510,165 510,175 L 514,440 C 514,458 507,475 500,478 C 493,475 486,458 486,440 Z" fill="url(#fuselageGrad)" stroke="#38bdf8" stroke-width="1.2" />
          
          <!-- 机身内部架构透视:MPPT与中央电池缓冲舱 -->
          <rect x="492" y="325" width="16" height="32" rx="3" fill="#065f46" stroke="#10b981" stroke-width="1.2" />
          <text x="500" y="344" fill="#a7f3d0" font-size="7" font-weight="bold" font-family="monospace" text-anchor="middle">BAT</text>
          
          <rect x="492" y="275" width="16" height="22" rx="3" fill="#854d0e" stroke="#f59e0b" stroke-width="1.2" />
          <text x="500" y="289" fill="#fde68a" font-size="7" font-weight="bold" font-family="monospace" text-anchor="middle">MPPT</text>
        </g>

        <!-- ================= 尾推电机与螺旋桨(巡航主推进器) ================= -->
        <g id="tail-pusher" transform="translate(500, 482)">
          <!-- 电机短舱圆环 -->
          <circle cx="0" cy="0" r="7" fill="#1e293b" stroke="#60a5fa" stroke-width="1.5" />
          <!-- 高速尾推桨叶动画组 -->
          <g id="pusher-blades">
            <line x1="-30" y1="0" x2="30" y2="0" stroke="#93c5fd" stroke-width="2.5" stroke-linecap="round" opacity="0.85" />
            <line x1="0" y1="-30" x2="0" y2="30" stroke="#93c5fd" stroke-width="2.5" stroke-linecap="round" opacity="0.85" />
            <circle cx="0" cy="0" r="32" fill="none" stroke="rgba(147, 197, 253, 0.25)" stroke-dasharray="4 4" />
          </g>
          <!-- 尾部推进尾迹射流 -->
          <g id="pusher-jet" opacity="0.8">
            <polygon points="-12,12 12,12 0,55" fill="url(#sunBeam)" opacity="0.4" />
            <line x1="0" y1="10" x2="0" y2="60" stroke="#38bdf8" stroke-width="1.8" stroke-dasharray="4 6" class="flow-line" />
            <line x1="-8" y1="10" x2="-16" y2="52" stroke="#60a5fa" stroke-width="1.2" stroke-dasharray="3 5" class="flow-line" />
            <line x1="8" y1="10" x2="16" y2="52" stroke="#60a5fa" stroke-width="1.2" stroke-dasharray="3 5" class="flow-line" />
          </g>
        </g>

        <!-- ================= 四个倾转旋翼短舱 (VTOL Pods) ================= -->
        <!-- 左后旋翼短舱 (Rotor 1) -->
        <g id="pod-rl" transform="translate(330, 230)">
          <rect x="-6" y="-12" width="12" height="24" rx="3" fill="#1e293b" stroke="#38bdf8" stroke-width="1" />
          <g id="rotor-rl-spinner" class="rotor-spinner">
            <!-- 桨叶(巡航时顺桨折叠成横向,垂直时旋转) -->
            <ellipse id="disk-rl" cx="0" cy="0" rx="34" ry="12" fill="rgba(56, 189, 248, 0.2)" stroke="#38bdf8" stroke-dasharray="4 2" />
            <line id="feather-rl" x1="-34" y1="0" x2="34" y2="0" stroke="#bae6fd" stroke-width="2" />
          </g>
          <!-- 悬停喷流向下箭头(VTOL阶段高亮显示) -->
          <g id="thrust-rl" opacity="0">
            <line x1="0" y1="12" x2="0" y2="40" stroke="#f43f5e" stroke-width="2.5" stroke-dasharray="4 4" class="flow-line" />
          </g>
        </g>

        <!-- 右后旋翼短舱 (Rotor 2) -->
        <g id="pod-rr" transform="translate(670, 230)">
          <rect x="-6" y="-12" width="12" height="24" rx="3" fill="#1e293b" stroke="#38bdf8" stroke-width="1" />
          <g id="rotor-rr-spinner" class="rotor-spinner">
            <ellipse id="disk-rr" cx="0" cy="0" rx="34" ry="12" fill="rgba(56, 189, 248, 0.2)" stroke="#38bdf8" stroke-dasharray="4 2" />
            <line id="feather-rr" x1="-34" y1="0" x2="34" y2="0" stroke="#bae6fd" stroke-width="2" />
          </g>
          <g id="thrust-rr" opacity="0">
            <line x1="0" y1="12" x2="0" y2="40" stroke="#f43f5e" stroke-width="2.5" stroke-dasharray="4 4" class="flow-line" />
          </g>
        </g>

        <!-- 左前旋翼短舱 (Rotor 3) -->
        <g id="pod-fl" transform="translate(330, 400)">
          <rect x="-6" y="-12" width="12" height="24" rx="3" fill="#1e293b" stroke="#38bdf8" stroke-width="1" />
          <g id="rotor-fl-spinner" class="rotor-spinner">
            <ellipse id="disk-fl" cx="0" cy="0" rx="34" ry="12" fill="rgba(56, 189, 248, 0.2)" stroke="#38bdf8" stroke-dasharray="4 2" />
            <line id="feather-fl" x1="-34" y1="0" x2="34" y2="0" stroke="#bae6fd" stroke-width="2" />
          </g>
          <g id="thrust-fl" opacity="0">
            <line x1="0" y1="12" x2="0" y2="40" stroke="#f43f5e" stroke-width="2.5" stroke-dasharray="4 4" class="flow-line" />
          </g>
        </g>

        <!-- 右前旋翼短舱 (Rotor 4) -->
        <g id="pod-fr" transform="translate(670, 400)">
          <rect x="-6" y="-12" width="12" height="24" rx="3" fill="#1e293b" stroke="#38bdf8" stroke-width="1" />
          <g id="rotor-fr-spinner" class="rotor-spinner">
            <ellipse id="disk-fr" cx="0" cy="0" rx="34" ry="12" fill="rgba(56, 189, 248, 0.2)" stroke="#38bdf8" stroke-dasharray="4 2" />
            <line id="feather-fr" x1="-34" y1="0" x2="34" y2="0" stroke="#bae6fd" stroke-width="2" />
          </g>
          <g id="thrust-fr" opacity="0">
            <line x1="0" y1="12" x2="0" y2="40" stroke="#f43f5e" stroke-width="2.5" stroke-dasharray="4 4" class="flow-line" />
          </g>
        </g>

        <!-- ================= 4. 能量流拓扑总线(动态高亮流动) ================= -->
        <g id="power-bus-layer">
          <!-- 光伏收集流 -> MPPT -->
          <path id="wire-solar-aft" d="M 360,225 L 492,282 M 640,225 L 508,282" fill="none" stroke="#f59e0b" stroke-width="2" stroke-linecap="round" class="flow-line" />
          <path id="wire-solar-fore" d="M 280,395 L 492,290 M 720,395 L 508,290" fill="none" stroke="#f59e0b" stroke-width="2" stroke-linecap="round" class="flow-line" />

          <!-- MPPT -> 尾推主母线 (巡航主供电) -->
          <path id="wire-mppt-tail" d="M 500,297 L 500,475" fill="none" stroke="#60a5fa" stroke-width="3" stroke-linecap="round" class="flow-line" />

          <!-- MPPT <-> 电池充电/放电总线 -->
          <path id="wire-mppt-bat" d="M 500,297 L 500,325" fill="none" stroke="#10b981" stroke-width="3" stroke-linecap="round" class="flow-line" />

          <!-- 电池 -> 4个旋翼短舱供电线路(VTOL爬升放电时激活) -->
          <g id="wires-vtol-power" opacity="0.1">
            <path d="M 492,340 L 330,230" fill="none" stroke="#f43f5e" stroke-width="2" class="flow-line" />
            <path d="M 508,340 L 670,230" fill="none" stroke="#f43f5e" stroke-width="2" class="flow-line" />
            <path d="M 492,345 L 330,400" fill="none" stroke="#f43f5e" stroke-width="2" class="flow-line" />
            <path d="M 508,345 L 670,400" fill="none" stroke="#f43f5e" stroke-width="2" class="flow-line" />
          </g>
        </g>
      </g>

      <!-- 4. 关键解耦机理视觉标注(极简小字、指示线,不遮挡核心飞行器) -->
      <g id="annotation-group" font-size="10" font-family="monospace">
        <!-- 后翼上表面CIGS薄膜标注 -->
        <g transform="translate(195, 170)">
          <text x="0" y="0" fill="#f59e0b" font-weight="bold">后翼 CIGS 薄膜光伏 (上后掠)</text>
          <line x1="120" y1="3" x2="160" y2="35" stroke="#f59e0b" stroke-width="0.8" opacity="0.6" />
        </g>

        <!-- 前翼下掠布局与低干扰标注 -->
        <g transform="translate(70, 465)">
          <text x="0" y="0" fill="#38bdf8" font-weight="bold">前翼下反前掠 (降低下洗干扰)</text>
          <text x="0" y="14" fill="#94a3b8" font-size="9">翼展 3.2m · 巡航升阻比 18</text>
          <line x1="160" y1="-8" x2="220" y2="-45" stroke="#38bdf8" stroke-width="0.8" opacity="0.6" />
        </g>

        <!-- 顺桨短舱机制标注 -->
        <g id="label-feather" transform="translate(730, 290)">
          <rect x="-6" y="-12" width="165" height="42" rx="4" fill="rgba(15,23,42,0.85)" stroke="rgba(56,189,248,0.3)" />
          <text x="0" y="3" fill="#e2e8f0" font-weight="bold">旋翼停转顺桨 (Feathered)</text>
          <text x="0" y="18" fill="#38bdf8" font-size="9">零风阻锁定 · 消除悬停负收益</text>
          <line x1="-6" y1="8" x2="-55" y2="-50" stroke="#38bdf8" stroke-width="0.8" opacity="0.6" />
        </g>

        <!-- 尾推高能效标注 -->
        <g transform="translate(560, 520)">
          <text x="0" y="0" fill="#60a5fa" font-weight="bold">尾推电机 (42W 巡航推进)</text>
          <text x="0" y="14" fill="#34d399" font-size="9">光伏净盈余 +69.5W 直充蓄电池</text>
          <line x1="-10" y1="-4" x2="-45" y2="-30" stroke="#60a5fa" stroke-width="0.8" opacity="0.6" />
        </g>
      </g>
    </svg>
  </main>

  <!-- 底部微型浮动控制交互栏 -->
  <footer class="bottom-bar">
    <button class="btn-play" id="btn-play" title="播放/暂停">❚❚</button>
    <div class="stage-tabs">
      <div class="stage-chip" data-phase="0">1.垂直起飞 (VTOL)</div>
      <div class="stage-chip" data-phase="1">2.倾转过渡</div>
      <div class="stage-chip active" data-phase="2">3.太阳能自持巡航 (IFR)</div>
      <div class="stage-chip" data-phase="3">4.垂直着陆</div>
    </div>
    <input type="range" id="time-scrubber" class="scrubber" min="0" max="1000" value="650" />
    <div class="legend-chip">
      <span style="display:inline-block;width:12px;height:2px;background:#f59e0b;"></span>
      <span>光伏发电</span>
    </div>
    <div class="legend-chip">
      <span style="display:inline-block;width:12px;height:2px;background:#10b981;"></span>
      <span>储能回充</span>
    </div>
  </footer>

  <script>
    // ==========================================
    // 动画状态与物理参数模型
    // ==========================================
    const DURATION = 16000; // 完整工作时序周期 16 秒
    let isPlaying = true;
    let startTime = performance.now();
    let pausedTime = 0;
    let manualProgress = null;

    // DOM 元素引用
    const playBtn = document.getElementById('btn-play');
    const scrubber = document.getElementById('time-scrubber');
    const stageChips = document.querySelectorAll('.stage-chip');
    const photonsContainer = document.getElementById('photons-particles');

    // HUD 数值指示
    const valSolar = document.getElementById('val-solar');
    const valThrust = document.getElementById('val-thrust');
    const valNet = document.getElementById('val-net');
    const valAero = document.getElementById('val-aero');

    // SVG 动态部件
    const pusherBlades = document.getElementById('pusher-blades');
    const pusherJet = document.getElementById('tail-pusher').querySelector('#pusher-jet');
    const aeroStreamlines = document.getElementById('aero-streamlines');
    const wiresVtolPower = document.getElementById('wires-vtol-power');
    const wireMpptBat = document.getElementById('wire-mppt-bat');
    const labelFeather = document.getElementById('label-feather');
    const photonBeams = document.getElementById('photon-beams');

    // 4个短舱元素
    const pods = [
      { disk: document.getElementById('disk-rl'), feather: document.getElementById('feather-rl'), thrust: document.getElementById('thrust-rl') },
      { disk: document.getElementById('disk-rr'), feather: document.getElementById('feather-rr'), thrust: document.getElementById('thrust-rr') },
      { disk: document.getElementById('disk-fl'), feather: document.getElementById('feather-fl'), thrust: document.getElementById('thrust-fl') },
      { disk: document.getElementById('disk-fr'), feather: document.getElementById('feather-fr'), thrust: document.getElementById('thrust-fr') }
    ];

    // 初始化随机漂落的太阳能光子雨
    const PHOTON_COUNT = 24;
    const photons = [];
    for (let i = 0; i < PHOTON_COUNT; i++) {
      const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
      circle.setAttribute('r', (Math.random() * 2 + 1.2).toFixed(1));
      circle.setAttribute('fill', '#fde047');
      circle.setAttribute('opacity', (Math.random() * 0.7 + 0.3).toFixed(2));
      circle.setAttribute('filter', 'url(#glow)');
      photonsContainer.appendChild(circle);
      photons.push({
        el: circle,
        x: Math.random() * 800 + 100,
        y: Math.random() * 300,
        speed: Math.random() * 1.5 + 1.2
      });
    }

    // 阶段划分:
    // 0.00 ~ 0.22 : 阶段0 - 垂直起飞 (VTOL),旋翼大功率,电池大放电
    // 0.22 ~ 0.38 : 阶段1 - 倾转过渡 (Transition),旋翼倾转并开始顺桨,尾推介入
    // 0.38 ~ 0.85 : 阶段2 - 太阳能自持巡航 (IFR 核心理想解),旋翼顺桨锁死,升阻比18,光能直供且余电反充
    // 0.85 ~ 1.00 : 阶段3 - 垂直降落 (Landing),旋翼解顺并重新启动
    function getPhaseIndex(t) {
      if (t < 0.22) return 0;
      if (t < 0.38) return 1;
      if (t < 0.85) return 2;
      return 3;
    }

    // 核心物理量与动效插值
    function renderFrame(now) {
      let elapsed;
      if (manualProgress !== null) {
        elapsed = manualProgress * DURATION;
      } else {
        elapsed = (now - startTime) % DURATION;
        scrubber.value = ((elapsed / DURATION) * 1000).toFixed(0);
      }

      const p = elapsed / DURATION;
      const phase = getPhaseIndex(p);

      // 更新下方阶段高亮按钮
      stageChips.forEach((chip, idx) => {
        chip.classList.toggle('active', idx === phase);
      });

      // 1. 太阳光子粒子下落更新
      photons.forEach(pt => {
        pt.y += pt.speed;
        if (pt.y > 450) {
          pt.y = Math.random() * 60;
          pt.x = Math.random() * 800 + 100;
        }
        pt.el.setAttribute('cx', pt.x);
        pt.el.setAttribute('cy', pt.y);
      });

      // 2. 尾推螺旋桨高速转动
      const pusherAngle = (now * 1.4) % 360;
      pusherBlades.setAttribute('transform', `rotate(${pusherAngle})`);

      // 3. 模态插值运算与组件呈现
      let solarPower = 126.5; // 恒定晴朗光照
      let thrustPower = 0;
      let netPower = 0;
      let rotorTilt = 0; // 0: 垂直旋翼盘展开, 1: 顺桨横向

      if (phase === 0) {
        // [阶段0: 垂直起飞] 旋翼全功率,电池净消耗 -380W
        thrustPower = 395;
        netPower = solarPower - thrustPower; // -268.5W
        rotorTilt = 0;

        valSolar.textContent = `${solarPower.toFixed(1)} W`;
        valThrust.textContent = `${thrustPower.toFixed(0)} W (旋翼为主)`;
        valNet.textContent = `${netPower.toFixed(1)} W (电池深度放电)`;
        valNet.style.color = '#f43f5e';
        valAero.className = 'mode-tag mode-vtol';
        valAero.textContent = '悬停模态 (能收支为负)';

        wiresVtolPower.setAttribute('opacity', '0.9');
        wireMpptBat.classList.add('flow-reverse'); // 电池放电
        aeroStreamlines.setAttribute('opacity', '0.08');
        pusherJet.setAttribute('opacity', '0.2');
        labelFeather.setAttribute('opacity', '0.25');

        // 旋翼桨盘高速旋转动效
        pods.forEach(pod => {
          pod.thrust.setAttribute('opacity', '0.9');
          pod.disk.setAttribute('opacity', '0.65');
          pod.feather.setAttribute('opacity', '0.2');
          const spinScale = Math.sin(now * 0.05);
          pod.disk.setAttribute('rx', 34 + spinScale * 2);
        });

      } else if (phase === 1) {
        // [阶段1: 模态倾转] 短舱倾转、旋翼逐渐顺桨、尾推功率跃升
        const transRatio = (p - 0.22) / (0.38 - 0.22);
        thrustPower = 395 * (1 - transRatio) + 57 * transRatio;
        netPower = solarPower - thrustPower;
        rotorTilt = transRatio;

        valSolar.textContent = `${solarPower.toFixed(1)} W`;
        valThrust.textContent = `${thrustPower.toFixed(0)} W (倾转过渡)`;
        valNet.textContent = `${netPower > 0 ? '+' : ''}${netPower.toFixed(1)} W`;
        valNet.style.color = netPower > 0 ? '#34d399' : '#f59e0b';
        valAero.className = 'mode-tag mode-cruise';
        valAero.textContent = '倾转过渡 (升力面接管)';

        wiresVtolPower.setAttribute('opacity', (0.9 * (1 - transRatio)).toFixed(2));
        aeroStreamlines.setAttribute('opacity', (0.1 + 0.35 * transRatio).toFixed(2));
        pusherJet.setAttribute('opacity', (0.2 + 0.7 * transRatio).toFixed(2));
        labelFeather.setAttribute('opacity', (transRatio).toFixed(2));

        pods.forEach(pod => {
          pod.thrust.setAttribute('opacity', ((1 - transRatio) * 0.8).toFixed(2));
          pod.disk.setAttribute('opacity', ((1 - transRatio) * 0.65).toFixed(2));
          pod.feather.setAttribute('opacity', transRatio.toFixed(2));
          pod.disk.setAttribute('rx', 34 * (1 - transRatio));
        });

      } else if (phase === 2) {
        // [阶段2: 最终理想解巡航态 (IFR)] 太阳能自持!高升阻比 L/D=18
        thrustPower = 57.0; // 尾推42W + 航电15W
        netPower = solarPower - thrustPower; // +69.5W

        valSolar.textContent = `${solarPower.toFixed(1)} W`;
        valThrust.textContent = `57.0 W (尾推42W+航电15W)`;
        valNet.textContent = `+${netPower.toFixed(1)} W (自持反充蓄电池)`;
        valNet.style.color = '#34d399';
        valAero.className = 'mode-tag mode-cruise';
        valAero.textContent = '巡航 L/D = 18 (光伏自持)';

        wiresVtolPower.setAttribute('opacity', '0.04');
        wireMpptBat.classList.remove('flow-reverse'); // 电池回充
        aeroStreamlines.setAttribute('opacity', '0.5');
        pusherJet.setAttribute('opacity', '1.0');
        labelFeather.setAttribute('opacity', '1.0');

        // 4个短舱完全顺桨(零转速、零阻力顺流锁定)
        pods.forEach(pod => {
          pod.thrust.setAttribute('opacity', '0');
          pod.disk.setAttribute('opacity', '0');
          pod.feather.setAttribute('opacity', '1.0');
        });

      } else {
        // [阶段3: 降落过渡]
        const landRatio = (p - 0.85) / (1 - 0.85);
        thrustPower = 57 * (1 - landRatio) + 380 * landRatio;
        netPower = solarPower - thrustPower;

        valSolar.textContent = `${solarPower.toFixed(1)} W`;
        valThrust.textContent = `${thrustPower.toFixed(0)} W (旋翼复位)`;
        valNet.textContent = `${netPower.toFixed(1)} W`;
        valNet.style.color = '#f43f5e';
        valAero.className = 'mode-tag mode-vtol';
        valAero.textContent = '垂直降落 (旋翼重启)';

        wiresVtolPower.setAttribute('opacity', (0.8 * landRatio).toFixed(2));
        aeroStreamlines.setAttribute('opacity', (0.4 * (1 - landRatio)).toFixed(2));
        pusherJet.setAttribute('opacity', (0.8 * (1 - landRatio)).toFixed(2));

        pods.forEach(pod => {
          pod.thrust.setAttribute('opacity', (landRatio * 0.7).toFixed(2));
          pod.disk.setAttribute('opacity', (landRatio * 0.5).toFixed(2));
          pod.feather.setAttribute('opacity', (1 - landRatio).toFixed(2));
          pod.disk.setAttribute('rx', 34 * landRatio);
        });
      }

      if (isPlaying) {
        requestAnimationFrame(renderFrame);
      }
    }

    // 交互响应:播放/暂停
    playBtn.addEventListener('click', () => {
      isPlaying = !isPlaying;
      playBtn.textContent = isPlaying ? '❚❚' : '▶';
      if (isPlaying) {
        startTime = performance.now() - pausedTime;
        requestAnimationFrame(renderFrame);
      } else {
        pausedTime = (performance.now() - startTime) % DURATION;
      }
    });

    // 交互响应:时间轴拖动
    scrubber.addEventListener('input', (e) => {
      manualProgress = parseFloat(e.target.value) / 1000;
      if (!isPlaying) {
        renderFrame(performance.now());
      }
    });

    scrubber.addEventListener('change', () => {
      if (isPlaying) {
        startTime = performance.now() - manualProgress * DURATION;
        manualProgress = null;
      }
    });

    // 交互响应:阶段芯片快速切换
    const phaseMarkers = [0.05, 0.28, 0.55, 0.92];
    stageChips.forEach(chip => {
      chip.addEventListener('click', () => {
        const ph = parseInt(chip.getAttribute('data-phase'));
        const targetP = phaseMarkers[ph];
        scrubber.value = targetP * 1000;
        startTime = performance.now() - targetP * DURATION;
        manualProgress = isPlaying ? null : targetP;
        if (!isPlaying) {
          renderFrame(performance.now());
        }
      });
    });

    // 页面加载完成后自动连续播放,重开即播
    window.addEventListener('DOMContentLoaded', () => {
      startTime = performance.now();
      isPlaying = true;
      requestAnimationFrame(renderFrame);
    });
  </script>
</body>
</html>
积分规则:每轮对话扣10分