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

这个方案非常精妙——利用磁流变液的"固-液相变"为刚性孔壁增加柔性自对准过渡层,完全契合 TRIZ 的最终理想解(IFR):问题自身消失,资源自我服务。下面是完整的交互式原理动画:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>静电转移 + 磁流变液辅助定位 — 原理动画</title>
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=IBM+Plex+Mono:wght@300;400;500;600&display=swap" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css" rel="stylesheet">
<style>
:root {
  --bg: #050910;
  --surface: #0b1120;
  --card: #0f1729;
  --border: rgba(0,229,255,0.1);
  --text: #c4d3e4;
  --text-dim: #556677;
  --accent: #00e5ff;
  --amber: #ffa726;
  --amber-dim: rgba(255,167,38,0.15);
  --copper: #cd8032;
  --mr-liquid: rgba(0,200,180,0.22);
  --mr-solid: #00c8b4;
  --funnel-glow: #00ffe0;
  --magnetic: #9c6cff;
  --success: #00e676;
}
*{margin:0;padding:0;box-sizing:border-box;}
body{
  background:var(--bg);
  color:var(--text);
  font-family:'IBM Plex Mono',monospace;
  min-height:100vh;
  display:flex;
  flex-direction:column;
  align-items:center;
  overflow-x:hidden;
}
/* 背景网格 */
body::before{
  content:'';position:fixed;inset:0;
  background-image:
    linear-gradient(rgba(0,229,255,0.03) 1px,transparent 1px),
    linear-gradient(90deg,rgba(0,229,255,0.03) 1px,transparent 1px);
  background-size:60px 60px;
  pointer-events:none;z-index:0;
}
body::after{
  content:'';position:fixed;inset:0;
  background:radial-gradient(ellipse at 50% 30%,rgba(0,229,255,0.04) 0%,transparent 60%);
  pointer-events:none;z-index:0;
}

.container{
  position:relative;z-index:1;
  width:100%;max-width:1100px;
  padding:28px 20px 40px;
  display:flex;flex-direction:column;align-items:center;gap:20px;
}

/* 标题区 */
.header{text-align:center;margin-bottom:4px;}
.header h1{
  font-family:'Syne',sans-serif;
  font-weight:800;font-size:clamp(22px,3.2vw,36px);
  letter-spacing:-0.5px;
  background:linear-gradient(135deg,#e0eaf4 0%,var(--accent) 60%,var(--funnel-glow) 100%);
  -webkit-background-clip:text;-webkit-text-fill-color:transparent;
  background-clip:text;
}
.header .sub{
  font-size:13px;color:var(--text-dim);margin-top:6px;letter-spacing:0.5px;
}
.header .ifrtag{
  display:inline-block;margin-top:8px;
  padding:3px 12px;border-radius:20px;
  background:rgba(0,229,255,0.08);border:1px solid rgba(0,229,255,0.2);
  font-size:11px;color:var(--accent);letter-spacing:1px;
}

/* 主动画区 */
.anim-wrap{
  width:100%;
  background:var(--surface);
  border:1px solid var(--border);
  border-radius:16px;
  overflow:hidden;
  position:relative;
}
.anim-wrap svg{display:block;width:100%;height:auto;}

/* 控制面板 */
.controls{
  width:100%;
  display:flex;flex-wrap:wrap;align-items:center;gap:12px;
  padding:16px 20px;
  background:var(--card);
  border:1px solid var(--border);
  border-radius:12px;
}
.ctrl-group{display:flex;align-items:center;gap:8px;}
.ctrl-group.sep{margin-left:auto;}
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  padding:8px 16px;border-radius:8px;border:1px solid var(--border);
  background:rgba(0,229,255,0.06);color:var(--accent);
  font-family:inherit;font-size:12px;cursor:pointer;
  transition:all .2s;
}
.btn:hover{background:rgba(0,229,255,0.14);border-color:rgba(0,229,255,0.3);}
.btn:active{transform:scale(0.96);}
.btn.primary{background:rgba(0,229,255,0.15);border-color:rgba(0,229,255,0.35);}
.btn i{font-size:13px;}

/* 进度条 */
.timeline-wrap{
  flex:1;min-width:200px;
  display:flex;align-items:center;gap:10px;
}
.timeline-wrap label{font-size:11px;color:var(--text-dim);white-space:nowrap;}
input[type=range]{
  -webkit-appearance:none;appearance:none;
  flex:1;height:6px;border-radius:3px;
  background:rgba(0,229,255,0.1);outline:none;cursor:pointer;
}
input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none;width:16px;height:16px;border-radius:50%;
  background:var(--accent);border:2px solid var(--bg);
  box-shadow:0 0 8px rgba(0,229,255,0.4);
}

/* 速度 */
.speed-btns{display:flex;gap:4px;}
.speed-btns .btn{padding:6px 10px;font-size:11px;min-width:36px;justify-content:center;}
.speed-btns .btn.active{background:rgba(0,229,255,0.2);border-color:var(--accent);}

/* 阶段指示器 */
.phase-bar{
  width:100%;display:flex;gap:4px;
}
.phase-step{
  flex:1;padding:10px 8px;border-radius:8px;
  background:var(--card);border:1px solid var(--border);
  text-align:center;transition:all .4s;
  position:relative;overflow:hidden;
}
.phase-step::before{
  content:'';position:absolute;inset:0;
  background:linear-gradient(135deg,rgba(0,229,255,0.08),transparent);
  opacity:0;transition:opacity .4s;
}
.phase-step.active::before{opacity:1;}
.phase-step.active{border-color:rgba(0,229,255,0.35);}
.phase-step.done{border-color:rgba(0,230,118,0.25);}
.phase-step .num{
  font-size:10px;color:var(--text-dim);margin-bottom:3px;
  font-weight:600;letter-spacing:1px;position:relative;
}
.phase-step.active .num{color:var(--accent);}
.phase-step.done .num{color:var(--success);}
.phase-step .label{
  font-size:11px;color:var(--text-dim);position:relative;
  font-weight:500;
}
.phase-step.active .label{color:#e0eaf4;}
.phase-step.done .label{color:rgba(0,230,118,0.7);}

/* 参数面板 */
.param-panel{
  width:100%;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:10px;
}
.param-card{
  padding:12px 16px;border-radius:10px;
  background:var(--card);border:1px solid var(--border);
  transition:all .5s;opacity:0.4;
}
.param-card.visible{opacity:1;border-color:rgba(0,229,255,0.2);}
.param-card .p-label{font-size:10px;color:var(--text-dim);letter-spacing:0.8px;margin-bottom:4px;text-transform:uppercase;}
.param-card .p-value{font-size:15px;font-weight:600;color:#e0eaf4;}
.param-card .p-value span{color:var(--accent);font-weight:700;}
.param-card .p-note{font-size:10px;color:var(--text-dim);margin-top:4px;line-height:1.5;}

@media(max-width:640px){
  .container{padding:16px 10px 30px;}
  .controls{flex-direction:column;align-items:stretch;}
  .ctrl-group.sep{margin-left:0;}
  .phase-bar{flex-wrap:wrap;}
  .phase-step{min-width:calc(33% - 4px);}
}
</style>
</head>
<body>
<div class="container">
  <div class="header">
    <h1>静电转移 + 磁流变液辅助定位</h1>
    <p class="sub">细长铜柱(长径比 11:1)无卡死插入原理演示</p>
    <span class="ifrtag">IFR:孔壁自身成为柔性导向 — 问题自行消失</span>
  </div>

  <div class="anim-wrap">
    <svg id="scene" viewBox="0 0 800 920" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <!-- 金属渐变 -->
        <linearGradient id="gMetal" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stop-color="#4a5060"/>
          <stop offset="50%" stop-color="#363c4a"/>
          <stop offset="100%" stop-color="#2a2f3a"/>
        </linearGradient>
        <!-- 铜渐变 -->
        <linearGradient id="gCopper" x1="0" y1="0" x2="1" y2="0">
          <stop offset="0%" stop-color="#b06820"/>
          <stop offset="30%" stop-color="#daa050"/>
          <stop offset="70%" stop-color="#e8b868"/>
          <stop offset="100%" stop-color="#b07028"/>
        </linearGradient>
        <!-- 玻璃渐变 -->
        <linearGradient id="gGlass" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stop-color="rgba(160,200,240,0.1)"/>
          <stop offset="100%" stop-color="rgba(120,170,220,0.06)"/>
        </linearGradient>
        <!-- 磁场线渐变 -->
        <linearGradient id="gMag" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stop-color="rgba(156,108,255,0.6)"/>
          <stop offset="100%" stop-color="rgba(156,108,255,0)"/>
        </linearGradient>
        <!-- 发光滤镜 -->
        <filter id="fGlow" x="-50%" y="-50%" width="200%" height="200%">
          <feGaussianBlur stdDeviation="6" result="b"/>
          <feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
        </filter>
        <filter id="fGlowBig" x="-80%" y="-80%" width="260%" height="260%">
          <feGaussianBlur stdDeviation="14" result="b"/>
          <feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
        </filter>
        <filter id="fGlowSm" x="-50%" y="-50%" width="200%" height="200%">
          <feGaussianBlur stdDeviation="3" result="b"/>
          <feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
        </filter>
        <!-- MR流体纹理 -->
        <pattern id="mrPattern" width="8" height="8" patternUnits="userSpaceOnUse">
          <circle cx="4" cy="4" r="1" fill="rgba(0,210,190,0.3)"/>
        </pattern>
      </defs>

      <!-- 背景装饰 -->
      <rect x="0" y="0" width="800" height="920" fill="none"/>

      <!-- ====== 磁场线组(Phase 3 可见) ====== -->
      <g id="magLines" opacity="0">
        <path d="M230,480 Q260,440 270,400" stroke="url(#gMag)" stroke-width="2" fill="none" stroke-dasharray="4,4"/>
        <path d="M230,520 Q240,480 250,440" stroke="url(#gMag)" stroke-width="2" fill="none" stroke-dasharray="4,4"/>
        <path d="M570,480 Q540,440 530,400" stroke="url(#gMag)" stroke-width="2" fill="none" stroke-dasharray="4,4"/>
        <path d="M570,520 Q560,480 550,440" stroke="url(#gMag)" stroke-width="2" fill="none" stroke-dasharray="4,4"/>
        <!-- 磁极标记 -->
        <text x="210" y="510" font-size="16" fill="rgba(156,108,255,0.7)" font-family="Syne,sans-serif" font-weight="700">N</text>
        <text x="575" y="510" font-size="16" fill="rgba(156,108,255,0.7)" font-family="Syne,sans-serif" font-weight="700">S</text>
      </g>

      <!-- ====== 玻璃板 ====== -->
      <g id="glassGroup">
        <!-- 左半玻璃 -->
        <rect x="220" y="460" width="174" height="300" rx="2" fill="url(#gGlass)" stroke="rgba(140,180,220,0.15)" stroke-width="1"/>
        <!-- 右半玻璃 -->
        <rect x="406" y="460" width="174" height="300" rx="2" fill="url(#gGlass)" stroke="rgba(140,180,220,0.15)" stroke-width="1"/>
        <!-- 玻璃标签 -->
        <text x="306" y="620" font-size="10" fill="rgba(140,180,220,0.35)" text-anchor="middle" font-family="IBM Plex Mono,monospace" transform="rotate(-90,306,620)">玻璃基板</text>
        <text x="494" y="620" font-size="10" fill="rgba(140,180,220,0.35)" text-anchor="middle" font-family="IBM Plex Mono,monospace" transform="rotate(90,494,620)">玻璃基板</text>
      </g>

      <!-- ====== MR流体 — 液态(浅槽 + 孔内) ====== -->
      <rect id="mrTrough" x="220" y="430" width="360" height="30" rx="3" fill="rgba(0,200,180,0.18)" stroke="rgba(0,210,190,0.1)" stroke-width="0.5"/>
      <rect id="mrHole" x="394" y="460" width="12" height="300" fill="rgba(0,200,180,0.22)"/>

      <!-- ====== MR流体 — 固态漏斗(Phase 3 出现) ====== -->
      <g id="funnelGroup" opacity="0">
        <!-- 漏斗主体 -->
        <path id="funnelShape" d="M374,430 L426,430 L404,510 L396,510 Z" fill="rgba(0,210,190,0.35)" stroke="rgba(0,255,224,0.3)" stroke-width="1"/>
        <!-- 漏斗发光轮廓 -->
        <path d="M374,430 L426,430 L404,510 L396,510 Z" fill="none" stroke="rgba(0,255,224,0.5)" stroke-width="1.5" filter="url(#fGlowSm)"/>
        <!-- 漏斗内导向线 -->
        <line x1="380" y1="445" x2="397" y2="505" stroke="rgba(0,255,224,0.15)" stroke-width="0.5" stroke-dasharray="3,3"/>
        <line x1="420" y1="445" x2="403" y2="505" stroke="rgba(0,255,224,0.15)" stroke-width="0.5" stroke-dasharray="3,3"/>
        <!-- 漏斗高亮脉冲 -->
        <path id="funnelPulse" d="M374,430 L426,430 L404,510 L396,510 Z" fill="none" stroke="rgba(0,255,224,0.8)" stroke-width="2" filter="url(#fGlow)" opacity="0"/>
      </g>

      <!-- ====== MR流体粒子组 ====== -->
      <g id="mrParticles"></g>

      <!-- ====== 铜柱 ====== -->
      <g id="pillarGroup">
        <rect id="copperPillar" x="395" y="238" width="10" height="110" rx="1.5" fill="url(#gCopper)"/>
        <!-- 铜柱顶端与电极接触面 -->
        <rect id="pillarTop" x="395" y="236" width="10" height="4" rx="1" fill="#daa050"/>
      </g>

      <!-- ====== 静电转移头 ====== -->
      <g id="headGroup">
        <!-- 主体 -->
        <rect x="280" y="80" width="240" height="140" rx="6" fill="url(#gMetal)" stroke="rgba(255,255,255,0.06)" stroke-width="1"/>
        <!-- 内部电路纹理 -->
        <line x1="300" y1="100" x2="500" y2="100" stroke="rgba(255,255,255,0.04)" stroke-width="0.5"/>
        <line x1="300" y1="120" x2="500" y2="120" stroke="rgba(255,255,255,0.04)" stroke-width="0.5"/>
        <line x1="300" y1="140" x2="500" y2="140" stroke="rgba(255,255,255,0.04)" stroke-width="0.5"/>
        <line x1="300" y1="160" x2="500" y2="160" stroke="rgba(255,255,255,0.04)" stroke-width="0.5"/>
        <line x1="300" y1="180" x2="500" y2="180" stroke="rgba(255,255,255,0.04)" stroke-width="0.5"/>
        <!-- 微电极凸起 -->
        <path d="M388,220 L412,220 L406,238 L394,238 Z" fill="#4a5060" stroke="rgba(255,255,255,0.08)" stroke-width="0.5"/>
        <!-- 转移头标签 -->
        <text x="400" y="158" font-size="11" fill="rgba(255,255,255,0.25)" text-anchor="middle" font-family="IBM Plex Mono,monospace" font-weight="500">静电转移头</text>
      </g>

      <!-- ====== 静电场发光 ====== -->
      <g id="electroGlow" opacity="0">
        <ellipse cx="400" cy="240" rx="28" ry="12" fill="rgba(255,167,38,0.3)" filter="url(#fGlow)"/>
        <ellipse cx="400" cy="238" rx="14" ry="5" fill="rgba(255,200,80,0.5)" filter="url(#fGlowSm)"/>
        <!-- 静电力线 -->
        <line x1="394" y1="238" x2="395" y2="250" stroke="rgba(255,167,38,0.4)" stroke-width="0.8" stroke-dasharray="2,3"/>
        <line x1="400" y1="238" x2="400" y2="252" stroke="rgba(255,167,38,0.5)" stroke-width="0.8" stroke-dasharray="2,3"/>
        <line x1="406" y1="238" x2="405" y2="250" stroke="rgba(255,167,38,0.4)" stroke-width="0.8" stroke-dasharray="2,3"/>
      </g>

      <!-- ====== 阵列缩略图(右上角) ====== -->
      <g id="arrayInset" transform="translate(610,60)">
        <rect x="0" y="0" width="150" height="150" rx="8" fill="rgba(11,17,32,0.85)" stroke="rgba(0,229,255,0.15)" stroke-width="1"/>
        <text x="75" y="18" font-size="8" fill="var(--text-dim)" text-anchor="middle" font-family="IBM Plex Mono,monospace">22500根并行阵列</text>
        <!-- 小点阵列 -->
        <g id="arrayDots"></g>
        <!-- 高亮当前操作列 -->
        <rect id="arrayHighlight" x="69" y="27" width="12" height="12" rx="2" fill="none" stroke="var(--amber)" stroke-width="1.2" opacity="0"/>
      </g>

      <!-- ====== 参数标注(动态显示) ====== -->
      <g id="callouts">
        <!-- DC 50V 标注 -->
        <g id="calloutVoltage" opacity="0">
          <line x1="420" y1="200" x2="480" y2="175" stroke="rgba(255,167,38,0.4)" stroke-width="0.8" stroke-dasharray="3,2"/>
          <rect x="480" y="164" width="80" height="22" rx="4" fill="rgba(255,167,38,0.1)" stroke="rgba(255,167,38,0.3)" stroke-width="0.8"/>
          <text x="520" y="179" font-size="10" fill="#ffa726" text-anchor="middle" font-family="IBM Plex Mono,monospace" font-weight="600">DC 50V</text>
        </g>
        <!-- 0.05mm 间隙标注 -->
        <g id="calloutGap" opacity="0">
          <line x1="410" y1="428" x2="470" y2="415" stroke="rgba(0,229,255,0.4)" stroke-width="0.8" stroke-dasharray="3,2"/>
          <rect x="470" y="404" width="96" height="22" rx="4" fill="rgba(0,229,255,0.08)" stroke="rgba(0,229,255,0.25)" stroke-width="0.8"/>
          <text x="518" y="419" font-size="10" fill="var(--accent)" text-anchor="middle" font-family="IBM Plex Mono,monospace" font-weight="600">间隙 0.05mm</text>
        </g>
        <!-- 50kPa 标注 -->
        <g id="calloutYield" opacity="0">
          <line x1="426" y1="470" x2="490" y2="455" stroke="rgba(0,255,224,0.4)" stroke-width="0.8" stroke-dasharray="3,2"/>
          <rect x="490" y="444" width="110" height="22" rx="4" fill="rgba(0,255,224,0.08)" stroke="rgba(0,255,224,0.25)" stroke-width="0.8"/>
          <text x="545" y="459" font-size="10" fill="var(--funnel-glow)" text-anchor="middle" font-family="IBM Plex Mono,monospace" font-weight="600">50kPa 屈服强度</text>
        </g>
      </g>

      <!-- ====== 阶段标题(SVG内) ====== -->
      <g id="phaseTitle" transform="translate(50,45)">
        <text id="phaseTitleText" font-size="14" fill="rgba(0,229,255,0.6)" font-family="Syne,sans-serif" font-weight="700" letter-spacing="1"></text>
      </g>

      <!-- ====== 成功指示 ====== -->
      <g id="successMark" opacity="0" transform="translate(400,790)">
        <circle cx="0" cy="0" r="16" fill="rgba(0,230,118,0.12)" stroke="rgba(0,230,118,0.4)" stroke-width="1.5"/>
        <path d="M-6,0 L-2,5 L7,-5" stroke="#00e676" stroke-width="2.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
      </g>

      <!-- ====== 铜柱下落轨迹 ====== -->
      <g id="trailGroup" opacity="0">
        <line id="fallTrail" x1="400" y1="350" x2="400" y2="500" stroke="rgba(205,128,50,0.15)" stroke-width="10" stroke-linecap="round" filter="url(#fGlowSm)"/>
      </g>
    </svg>
  </div>

  <!-- 控制面板 -->
  <div class="controls">
    <div class="ctrl-group">
      <button class="btn primary" id="btnPlay"><i class="fa-solid fa-play"></i> 播放</button>
      <button class="btn" id="btnStep"><i class="fa-solid fa-forward-step"></i> 下一阶段</button>
      <button class="btn" id="btnReset"><i class="fa-solid fa-rotate-left"></i> 重置</button>
    </div>
    <div class="timeline-wrap">
      <label>进度</label>
      <input type="range" id="timeline" min="0" max="1000" value="0"/>
    </div>
    <div class="ctrl-group sep">
      <label style="font-size:11px;color:var(--text-dim)">速度</label>
      <div class="speed-btns">
        <button class="btn" data-speed="0.5">0.5x</button>
        <button class="btn active" data-speed="1">1x</button>
        <button class="btn" data-speed="2">2x</button>
      </div>
    </div>
  </div>

  <!-- 阶段指示器 -->
  <div class="phase-bar">
    <div class="phase-step" data-idx="0"><div class="num">01</div><div class="label">静电吸取</div></div>
    <div class="phase-step" data-idx="1"><div class="num">02</div><div class="label">移至对位</div></div>
    <div class="phase-step" data-idx="2"><div class="num">03</div><div class="label">磁场固化</div></div>
    <div class="phase-step" data-idx="3"><div class="num">04</div><div class="label">释放下落</div></div>
    <div class="phase-step" data-idx="4"><div class="num">05</div><div class="label">撤磁排液</div></div>
    <div class="phase-step" data-idx="5"><div class="num">06</div><div class="label">精准就位</div></div>
  </div>

  <!-- 参数面板 -->
  <div class="param-panel">
    <div class="param-card" id="pcVoltage">
      <div class="p-label">静电转移头电压</div>
      <div class="p-value"><span>DC 50V</span></div>
      <div class="p-note">微电极凸起 Φ0.09mm,尺寸略小于铜柱</div>
    </div>
    <div class="param-card" id="pcGap">
      <div class="p-label">对合间隙</div>
      <div class="p-value"><span>0.05mm</span></div>
      <div class="p-note">转移头与玻璃板精确对合距离</div>
    </div>
    <div class="param-card" id="pcYield">
      <div class="p-label">磁流变液剪切屈服强度</div>
      <div class="p-value"><span>50kPa</span>(励磁后)</div>
      <div class="p-note">纳米级颗粒,固态形成柔性锥度漏斗</div>
    </div>
    <div class="param-card" id="pcIFR">
      <div class="p-label">IFR 核心原理</div>
      <div class="p-value">孔壁<span>自我导向</span></div>
      <div class="p-note">磁流变液相变 → 刚性孔变为柔性自对准孔,硬接触卡死矛盾自行消失</div>
    </div>
  </div>
</div>

<script>
(function(){
  // ========== 常量与状态 ==========
  const PHASES = [
    { name:'静电吸取', dur:2200, title:'PHASE 01 — 静电吸取铜柱' },
    { name:'移至对位', dur:1800, title:'PHASE 02 — 转移头移至对位' },
    { name:'磁场固化', dur:2500, title:'PHASE 03 — 磁场固化 · 柔性漏斗成形' },
    { name:'释放下落', dur:2000, title:'PHASE 04 — 释放静电 · 铜柱下落' },
    { name:'撤磁排液', dur:2200, title:'PHASE 05 — 撤去磁场 · 液化排液' },
    { name:'精准就位', dur:1800, title:'PHASE 06 — 铜柱精准就位' },
  ];

  let currentPhase = 0;
  let phaseProgress = 0;   // 0~1
  let playing = false;
  let speed = 1;
  let lastTime = 0;
  let manualMode = false;  // 拖动进度条时

  // ========== DOM 元素 ==========
  const svg = document.getElementById('scene');
  const headGroup = document.getElementById('headGroup');
  const pillarGroup = document.getElementById('pillarGroup');
  const copperPillar = document.getElementById('copperPillar');
  const pillarTop = document.getElementById('pillarTop');
  const electroGlow = document.getElementById('electroGlow');
  const mrTrough = document.getElementById('mrTrough');
  const mrHole = document.getElementById('mrHole');
  const funnelGroup = document.getElementById('funnelGroup');
  const funnelPulse = document.getElementById('funnelPulse');
  const magLines = document.getElementById('magLines');
  const calloutVoltage = document.getElementById('calloutVoltage');
  const calloutGap = document.getElementById('calloutGap');
  const calloutYield = document.getElementById('calloutYield');
  const phaseTitleText = document.getElementById('phaseTitleText');
  const successMark = document.getElementById('successMark');
  const trailGroup = document.getElementById('trailGroup');
  const fallTrail = document.getElementById('fallTrail');
  const arrayHighlight = document.getElementById('arrayHighlight');

  const btnPlay = document.getElementById('btnPlay');
  const btnStep = document.getElementById('btnStep');
  const btnReset = document.getElementById('btnReset');
  const timeline = document.getElementById('timeline');
  const phaseSteps = document.querySelectorAll('.phase-step');
  const speedBtns = document.querySelectorAll('.speed-btns .btn');
  const paramCards = {
    voltage: document.getElementById('pcVoltage'),
    gap: document.getElementById('pcGap'),
    yield: document.getElementById('pcYield'),
    ifr: document.getElementById('pcIFR'),
  };

  // ========== 初始化阵列缩略图 ==========
  (function initArrayDots(){
    const g = document.getElementById('arrayDots');
    const cols = 11, rows = 11, spacing = 11, ox = 14, oy = 27;
    for(let r=0;r<rows;r++){
      for(let c=0;c<cols;c++){
        const dot = document.createElementNS('http://www.w3.org/2000/svg','rect');
        dot.setAttribute('x', ox + c*spacing);
        dot.setAttribute('y', oy + r*spacing);
        dot.setAttribute('width', 4);
        dot.setAttribute('height', 4);
        dot.setAttribute('rx', 0.8);
        dot.setAttribute('fill', 'rgba(0,229,255,0.2)');
        g.appendChild(dot);
      }
    }
  })();

  // ========== 初始化MR流体粒子 ==========
  const mrParticles = [];
  (function initParticles(){
    const g = document.getElementById('mrParticles');
    // 浅槽中的粒子
    for(let i=0;i<20;i++){
      const c = document.createElementNS('http://www.w3.org/2000/svg','circle');
      const x = 230 + Math.random()*340;
      const y = 433 + Math.random()*24;
      c.setAttribute('cx', x);
      c.setAttribute('cy', y);
      c.setAttribute('r', 1.5 + Math.random()*1.5);
      c.setAttribute('fill', 'rgba(0,210,190,0.25)');
      g.appendChild(c);
      mrParticles.push({el:c, ox:x, oy:y, baseR:parseFloat(c.getAttribute('r')), zone:'trough'});
    }
    // 孔内粒子
    for(let i=0;i<15;i++){
      const c = document.createElementNS('http://www.w3.org/2000/svg','circle');
      const x = 395 + Math.random()*10;
      const y = 465 + Math.random()*280;
      c.setAttribute('cx', x);
      c.setAttribute('cy', y);
      c.setAttribute('r', 1.2 + Math.random()*1.2);
      c.setAttribute('fill', 'rgba(0,210,190,0.25)');
      g.appendChild(c);
      mrParticles.push({el:c, ox:x, oy:y, baseR:parseFloat(c.getAttribute('r')), zone:'hole'});
    }
  })();

  // ========== 工具函数 ==========
  function lerp(a,b,t){ return a + (b-a) * Math.max(0, Math.min(1, t)); }
  function easeInOut(t){ return t<0.5 ? 2*t*t : -1+(4-2*t)*t; }
  function easeOut(t){ return 1 - Math.pow(1-t, 3); }
  function easeIn(t){ return t*t*t; }

  function setOp(el, v){ el.setAttribute('opacity', Math.max(0,Math.min(1,v))); }
  function setTy(el, dy){ el.setAttribute('transform', 'translate(0,'+dy+')'); }

  // ========== 核心渲染 ==========
  // 铜柱状态
  let pillarDy = 0;        // 铜柱相对初始位置的Y偏移
  let pillarReleased = false;
  let pillarFallProgress = 0;

  // 转移头状态
  let headDy = 0;

  function render(){
    const p = currentPhase;
    const t = phaseProgress;
    const et = easeInOut(t);

    // ------ Phase 0: 静电吸取 ------
    if(p === 0){
      // 静电发光渐入
      setOp(electroGlow, et);
      // 铜柱微微振动(被吸取的抖动)
      const jitter = Math.sin(t * Math.PI * 8) * (1-t) * 2;
      setTy(pillarGroup, jitter);
      pillarDy = 0;
      headDy = 0;
      // 标注
      setOp(calloutVoltage, et);
      setOp(calloutGap, 0);
      setOp(calloutYield, 0);
      // 参数卡
      paramCards.voltage.classList.toggle('visible', t > 0.3);
      paramCards.gap.classList.remove('visible');
      paramCards.yield.classList.remove('visible');
      paramCards.ifr.classList.remove('visible');
      // 阵列高亮
      setOp(arrayHighlight, et * 0.8);
    }

    // ------ Phase 1: 移至对位 ------
    if(p === 1){
      setOp(electroGlow, 1);
      setOp(calloutVoltage, 1 - et);
      headDy = et * 28;  // 下移28px
      setTy(headGroup, headDy);
      setTy(pillarGroup, headDy);
      // 间隙标注渐入
      setOp(calloutGap, et);
      paramCards.gap.classList.toggle('visible', t > 0.3);
    }

    // ------ Phase 2: 磁场固化(核心创新) ------
    if(p === 2){
      setOp(electroGlow, 1);
      headDy = 28;
      setTy(headGroup, headDy);
      setTy(pillarGroup, headDy);

      // 磁场线渐入
      setOp(magLines, et);

      // MR流体从液态到固态
      // 浅槽MR流体变浓
      mrTrough.setAttribute('fill', 'rgba(0,200,180,'+lerp(0.18,0.4,et)+')');
      mrHole.setAttribute('fill', 'rgba(0,200,180,'+lerp(0.22,0.5,et)+')');

      // 粒子对齐(从随机到有序)
      mrParticles.forEach((pt,i) => {
        const alignT = easeOut(Math.max(0, (t - 0.2) / 0.8));
        if(pt.zone === 'hole'){
          // 孔内粒子排列成垂直线
          const alignedX = (i % 2 === 0) ? 396 : 404;
          const nx = lerp(pt.ox, alignedX, alignT);
          pt.el.setAttribute('cx', nx);
          pt.el.setAttribute('fill', 'rgba(0,230,200,'+lerp(0.25,0.6,alignT)+')');
        } else {
          // 浅槽粒子向孔口聚集
          const alignedX = lerp(pt.ox, 395 + (i%3)*5, alignT * 0.6);
          pt.el.setAttribute('cx', alignedX);
          pt.el.setAttribute('fill', 'rgba(0,230,200,'+lerp(0.25,0.5,alignT)+')');
        }
      });

      // 漏斗出现(关键!)
      const funnelT = easeOut(Math.max(0, (t - 0.3) / 0.7));
      setOp(funnelGroup, funnelT);
      // 漏斗脉冲发光
      const pulse = (Math.sin(t * Math.PI * 4) * 0.5 + 0.5) * funnelT;
      setOp(funnelPulse, pulse * 0.6);

      // 标注
      setOp(calloutGap, 1 - et);
      setOp(calloutYield, funnelT);

      paramCards.yield.classList.toggle('visible', t > 0.4);
      paramCards.ifr.classList.toggle('visible', t > 0.6);
    }

    // ------ Phase 3: 释放下落 ------
    if(p === 3){
      headDy = 28;
      setTy(headGroup, headDy);

      // 静电消失
      setOp(electroGlow, 1 - et);

      // 铜柱释放下落
      const fallT = easeIn(t);
      const fallDist = fallT * 260;  // 下落260px
      pillarDy = headDy + fallDist;
      setTy(pillarGroup, pillarDy);

      // 下落轨迹
      setOp(trailGroup, t < 0.8 ? 0.6 : (1-t)*3);
      fallTrail.setAttribute('y1', 268 + headDy);
      fallTrail.setAttribute('y2', 268 + pillarDy);

      // 漏斗引导发光增强
      const guideGlow = Math.sin(t * Math.PI) * 0.8;
      setOp(funnelPulse, guideGlow);

      // 磁场仍保持
      setOp(magLines, 1);
      setOp(funnelGroup, 1);

      setOp(calloutYield, 1 - et * 0.5);
    }

    // ------ Phase 4: 撤磁排液 ------
    if(p === 4){
      headDy = 28;
      setTy(headGroup, headDy);

      // 铜柱在最终位置
      pillarDy = 288; // 最终位置
      setTy(pillarGroup, pillarDy);

      // 静电已关
      setOp(electroGlow, 0);
      setOp(trailGroup, 0);

      // 磁场消失
      setOp(magLines, 1 - et);
      setOp(funnelGroup, 1 - et);

      // MR流体恢复液态
      mrTrough.setAttribute('fill', 'rgba(0,200,180,'+lerp(0.4,0.1,et)+')');
      mrHole.setAttribute('fill', 'rgba(0,200,180,'+lerp(0.5,0.08,et)+')');

      // 粒子恢复随机
      mrParticles.forEach((pt) => {
        pt.el.setAttribute('cx', lerp(parseFloat(pt.el.getAttribute('cx')), pt.ox, et * 0.5));
        pt.el.setAttribute('fill', 'rgba(0,210,190,'+lerp(0.6,0.15,et)+')');
      });

      // MR流体"流出"效果
      const drainT = easeIn(t);
      const troughH = lerp(30, 8, drainT);
      const troughY = lerp(430, 452, drainT);
      mrTrough.setAttribute('y', troughY);
      mrTrough.setAttribute('height', troughH);

      setOp(calloutYield, 0);
    }

    // ------ Phase 5: 精准就位 ------
    if(p === 5){
      headDy = 28;
      setTy(headGroup, headDy);
      pillarDy = 288;
      setTy(pillarGroup, pillarDy);

      setOp(electroGlow, 0);
      setOp(magLines, 0);
      setOp(funnelGroup, 0);
      setOp(trailGroup, 0);
      setOp(mrParticles, 0);

      // MR流体几乎消失
      mrTrough.setAttribute('fill', 'rgba(0,200,180,0.05)');
      mrHole.setAttribute('fill', 'rgba(0,200,180,0.05)');

      // 成功标记出现
      setOp(successMark, et);

      // 铜柱微微确认闪烁
      const confirmPulse = Math.sin(t * Math.PI * 2) * 0.3 + 0.7;
      copperPillar.setAttribute('opacity', confirmPulse);
    }

    // ------ 全局:阶段标题 ------
    phaseTitleText.textContent = PHASES[Math.min(p, PHASES.length-1)].title;

    // ------ 全局:进度条同步 ------
    if(!manualMode){
      const totalPhases = PHASES.length;
      const globalProgress = (currentPhase + phaseProgress) / totalPhases;
      timeline.value = Math.round(globalProgress * 1000);
    }

    // ------ 全局:阶段指示器 ------
    phaseSteps.forEach((el, i) => {
      el.classList.remove('active','done');
      if(i < currentPhase) el.classList.add('done');
      else if(i === currentPhase) el.classList.add('active');
    });
  }

  // ========== 动画循环 ==========
  function tick(now){
    if(!playing){ lastTime = now; requestAnimationFrame(tick); return; }
    if(lastTime === 0) lastTime = now;
    const dt = (now - lastTime) * speed;
    lastTime = now;

    const dur = PHASES[currentPhase].dur;
    phaseProgress += dt / dur;

    if(phaseProgress >= 1){
      phaseProgress = 0;
      currentPhase++;
      if(currentPhase >= PHASES.length){
        currentPhase = PHASES.length - 1;
        phaseProgress = 1;
        playing = false;
        btnPlay.innerHTML = '<i class="fa-solid fa-play"></i> 播放';
      }
    }

    render();
    requestAnimationFrame(tick);
  }

  // ========== 交互控制 ==========
  btnPlay.addEventListener('click', () => {
    if(playing){
      playing = false;
      btnPlay.innerHTML = '<i class="fa-solid fa-play"></i> 播放';
    } else {
      // 如果已完成,重新开始
      if(currentPhase >= PHASES.length - 1 && phaseProgress >= 1){
        resetAnim();
      }
      playing = true;
      btnPlay.innerHTML = '<i class="fa-solid fa-pause"></i> 暂停';
    }
  });

  btnStep.addEventListener('click', () => {
    playing = false;
    btnPlay.innerHTML = '<i class="fa-solid fa-play"></i> 播放';
    currentPhase = Math.min(currentPhase + 1, PHASES.length - 1);
    phaseProgress = 0;
    // 快速渲染到该阶段起始状态
    renderAtPhaseStart(currentPhase);
    // 然后自动播放当前阶段
    playing = true;
    btnPlay.innerHTML = '<i class="fa-solid fa-pause"></i> 暂停';
  });

  btnReset.addEventListener('click', resetAnim);

  function resetAnim(){
    playing = false;
    currentPhase = 0;
    phaseProgress = 0;
    headDy = 0;
    pillarDy = 0;
    btnPlay.innerHTML = '<i class="fa-solid fa-play"></i> 播放';

    // 重置所有元素状态
    setTy(headGroup, 0);
    setTy(pillarGroup, 0);
    setOp(electroGlow, 0);
    setOp(magLines, 0);
    setOp(funnelGroup, 0);
    setOp(funnelPulse, 0);
    setOp(successMark, 0);
    setOp(trailGroup, 0);
    setOp(calloutVoltage, 0);
    setOp(calloutGap, 0);
    setOp(calloutYield, 0);
    setOp(arrayHighlight, 0);
    copperPillar.setAttribute('opacity', 1);
    mrTrough.setAttribute('fill', 'rgba(0,200,180,0.18)');
    mrTrough.setAttribute('y', 430);
    mrTrough.setAttribute('height', 30);
    mrHole.setAttribute('fill', 'rgba(0,200,180,0.22)');
    setOp(mrParticles, 1);

    mrParticles.forEach(pt => {
      pt.el.setAttribute('cx', pt.ox);
      pt.el.setAttribute('cy', pt.oy);
      pt.el.setAttribute('fill', 'rgba(0,210,190,0.25)');
    });

    Object.values(paramCards).forEach(c => c.classList.remove('visible'));
    render();
  }

  // 渲染某阶段起始状态(快速跳转到该阶段前)
  function renderAtPhaseStart(targetPhase){
    // 先重置
    resetAnim();
    // 逐阶段快进到目标阶段的起始
    currentPhase = targetPhase;
    phaseProgress = 0;
    // 快速应用之前阶段的终态
    for(let i = 0; i < targetPhase; i++){
      currentPhase = i;
      phaseProgress = 1;
      render();
    }
    currentPhase = targetPhase;
    phaseProgress = 0;
  }

  // 进度条拖动
  let draggingTimeline = false;
  timeline.addEventListener('mousedown', () => { manualMode = true; draggingTimeline = true; });
  timeline.addEventListener('touchstart', () => { manualMode = true; draggingTimeline = true; }, {passive:true});
  window.addEventListener('mouseup', () => { draggingTimeline = false; manualMode = false; });
  window.addEventListener('touchend', () => { draggingTimeline = false; manualMode = false; });

  timeline.addEventListener('input', () => {
    playing = false;
    btnPlay.innerHTML = '<i class="fa-solid fa-play"></i> 播放';
    const val = parseFloat(timeline.value) / 1000;
    const totalPhases = PHASES.length;
    const rawPhase = val * totalPhases;
    currentPhase = Math.min(Math.floor(rawPhase), totalPhases - 1);
    phaseProgress = rawPhase - currentPhase;
    render();
  });

  // 速度按钮
  speedBtns.forEach(btn => {
    btn.addEventListener('click', () => {
      speed = parseFloat(btn.dataset.speed);
      speedBtns.forEach(b => b.classList.remove('active'));
      btn.classList.add('active');
    });
  });

  // ========== 启动 ==========
  render();
  requestAnimationFrame(tick);

  // 自动开始播放(延迟500ms)
  setTimeout(() => {
    playing = true;
    btnPlay.innerHTML = '<i class="fa-solid fa-pause"></i> 暂停';
  }, 600);

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

实现说明

设计美学方向:深空实验室风格(Dark Lab Instrument),深邃的暗蓝黑底色搭配青色(MR流体)与琥珀色(静电场)双主色调,所有标注和参数使用等宽字体,营造精密仪器感。

动画六阶段时序

阶段 核心视觉事件 IFR 体现
01 静电吸取 琥珀色电场发光渐亮,铜柱微振被吸 资源利用:电场力并行抓取 22500 根
02 移至对位 转移头整体下移 28px,间隙标注出现 精确对合 0.05mm
03 磁场固化 MR 粒子从随机→有序排列,漏斗形发光轮廓成形 核心:孔壁自我变为柔性导向,问题自行消失
04 释放下落 静电消隐,铜柱沿漏斗壁滑入,轨迹线显现 柔性壁自对准,无硬接触
05 撤磁排液 磁场线消隐,粒子散开,流体变透明流出 相变逆转,资源释放
06 精准就位 成功勾号出现,铜柱确认脉冲 IFR 最终态达成

交互控制:播放/暂停、逐阶段步进、重置、进度条拖拽、0.5x/1x/2x 变速,以及底部四张参数卡随阶段联动亮显。

视觉引导重点:Phase 03 的漏斗成形是全动画的"记忆锚点"——粒子从混沌到有序的相变、漏斗轮廓的脉冲发光、50kPa 屈服强度 标注同时出现,将 IFR 思想(刚性孔壁 → 柔性自对准,卡死矛盾自我消灭)可视化到极致。

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