分享图
动画工坊
引擎就绪
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>电磁直驱快关蝶阀 - 原理演示</title>
<style>
  @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Noto+Sans+SC:wght@300;500;700&display=swap');

  :root {
    --bg-color: #050914;
    --grid-color: rgba(45, 60, 90, 0.3);
    --pipe-color: #334155;
    --pipe-highlight: #64748b;
    --flow-normal: #0ea5e9;
    --flow-glow: #0284c7;
    --alert-color: #ef4444;
    --energy-color: #f59e0b;
    --text-main: #e2e8f0;
    --text-muted: #64748b;
  }

  body {
    margin: 0;
    padding: 0;
    background-color: var(--bg-color);
    color: var(--text-main);
    font-family: 'Noto Sans SC', sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    overflow: hidden;
  }

  .container {
    position: relative;
    width: 100vw;
    max-width: 1400px;
    aspect-ratio: 16 / 9;
    background: 
      linear-gradient(var(--grid-color) 1px, transparent 1px) 0 0 / 40px 40px,
      linear-gradient(90deg, var(--grid-color) 1px, transparent 1px) 0 0 / 40px 40px;
    box-shadow: inset 0 0 100px rgba(0, 0, 0, 0.8);
  }

  svg {
    width: 100%;
    height: 100%;
    display: block;
  }

  /* Typography strictly controlled and corner-aligned */
  .panel-text { font-family: 'JetBrains Mono', monospace; font-size: 12px; fill: var(--text-main); }
  .panel-title { font-weight: 700; font-size: 14px; letter-spacing: 2px; fill: var(--flow-normal); }
  .panel-value { font-weight: 700; font-size: 14px; }
  
  .status-normal { fill: var(--flow-normal); }
  .status-alert { fill: var(--alert-color); }
  .status-energy { fill: var(--energy-color); }

  /* Dynamic CSS Classes controlled by JS */
  .flow-particle {
    stroke: var(--flow-normal);
    stroke-width: 4;
    stroke-dasharray: 20 60;
    animation: flow-move 1s linear infinite;
    opacity: 0.8;
  }
  
  @keyframes flow-move {
    from { stroke-dashoffset: 80; }
    to { stroke-dashoffset: 0; }
  }

  .flow-particle.blocked {
    animation-play-state: paused;
    stroke: var(--alert-color);
    opacity: 0.4;
  }

  .fluid-body { fill: rgba(14, 165, 233, 0.15); transition: fill 0.2s; }
  .fluid-body.blocked { fill: rgba(239, 68, 68, 0.15); }

  /* Energy Line Animation */
  .signal-line {
    stroke: var(--energy-color);
    stroke-width: 2;
    stroke-dasharray: 10 10;
    opacity: 0;
    transition: opacity 0.1s;
  }
  .signal-line.active {
    opacity: 1;
    animation: signal-dash 0.3s linear infinite;
  }
  @keyframes signal-dash {
    to { stroke-dashoffset: -20; }
  }

  /* Impact Shake Effect */
  .shake {
    animation: shake-anim 0.4s cubic-bezier(.36,.07,.19,.97) both;
  }
  @keyframes shake-anim {
    0%, 100% { transform: translate3d(0, 0, 0); }
    10%, 30%, 50%, 70%, 90% { transform: translate3d(-4px, 2px, 0); }
    20%, 40%, 60%, 80% { transform: translate3d(4px, -2px, 0); }
  }

  /* Scanline Overlay for aesthetic */
  .scanlines {
    position: absolute;
    top: 0; left: 0; width: 100%; height: 100%;
    background: linear-gradient(to bottom, rgba(255,255,255,0), rgba(255,255,255,0) 50%, rgba(0,0,0,0.2) 50%, rgba(0,0,0,0.2));
    background-size: 100% 4px;
    pointer-events: none;
    z-index: 10;
  }
</style>
</head>
<body>

<div class="container">
  <div class="scanlines"></div>
  <svg viewBox="0 0 1400 787.5" preserveAspectRatio="xMidYMid meet">
    
    <!-- SVG Filters for Glow Effects -->
    <defs>
      <filter id="glow-blue" x="-20%" y="-20%" width="140%" height="140%">
        <feGaussianBlur stdDeviation="5" result="blur" />
        <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
      </filter>
      <filter id="glow-red" x="-20%" y="-20%" width="140%" height="140%">
        <feGaussianBlur stdDeviation="8" result="blur" />
        <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
      </filter>
      <filter id="glow-yellow" x="-20%" y="-20%" width="140%" height="140%">
        <feGaussianBlur stdDeviation="6" result="blur" />
        <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
      </filter>
      <linearGradient id="pipe-grad" x1="0%" y1="0%" x2="0%" y2="100%">
        <stop offset="0%" stop-color="#475569" />
        <stop offset="20%" stop-color="#94a3b8" />
        <stop offset="80%" stop-color="#334155" />
        <stop offset="100%" stop-color="#1e293b" />
      </linearGradient>
      <linearGradient id="metal-grad" x1="0%" y1="0%" x2="100%" y2="100%">
        <stop offset="0%" stop-color="#cbd5e1" />
        <stop offset="50%" stop-color="#64748b" />
        <stop offset="100%" stop-color="#334155" />
      </linearGradient>
    </defs>

    <!-- UI Overlay: Top Left Panel (System Info) -->
    <g transform="translate(40, 40)">
      <rect width="280" height="140" fill="rgba(15, 23, 42, 0.8)" stroke="#334155" rx="4"/>
      <text x="20" y="30" class="panel-title">SYS_MONITOR // V_1.0</text>
      <line x1="20" y1="40" x2="260" y2="40" stroke="#334155" stroke-width="1"/>
      
      <text x="20" y="65" class="panel-text">系统状态 : <tspan id="ui-status" class="status-normal">正常监控中</tspan></text>
      <text x="20" y="90" class="panel-text">流体流速 : <tspan id="ui-velocity" class="panel-value">12.4 m/s</tspan></text>
      <text x="20" y="115" class="panel-text">响应延时 : <tspan class="panel-value status-energy">0.2s 极速档位</tspan></text>
    </g>

    <!-- UI Overlay: Bottom Right Panel (Specs) -->
    <g transform="translate(1080, 600)">
      <rect width="280" height="140" fill="rgba(15, 23, 42, 0.8)" stroke="#334155" rx="4"/>
      <text x="20" y="30" class="panel-title">HARDWARE_SPECS</text>
      <line x1="20" y1="40" x2="260" y2="40" stroke="#334155" stroke-width="1"/>
      
      <text x="20" y="65" class="panel-text">阀门规格 : <tspan class="panel-value">DN150 直驱蝶阀</tspan></text>
      <text x="20" y="90" class="panel-text">设计承压 : <tspan class="panel-value status-alert">1.6 MPa (抗冲击)</tspan></text>
      <text x="20" y="115" class="panel-text">核心组件 : <tspan class="panel-value">直线电机/超级电容</tspan></text>
    </g>

    <!-- Central Mechanical Assembly Group -->
    <g id="main-assembly">
      
      <!-- Flow Visualizer (Background) -->
      <path d="M 0 450 L 1400 450 L 1400 570 L 0 570 Z" class="fluid-body" id="fluid-bg"/>
      
      <!-- Animated Flow Particles -->
      <g id="flow-particles">
        <line x1="0" y1="470" x2="1400" y2="470" class="flow-particle" />
        <line x1="0" y1="510" x2="1400" y2="510" class="flow-particle" style="animation-duration: 0.8s; stroke-dasharray: 40 80;" />
        <line x1="0" y1="550" x2="1400" y2="550" class="flow-particle" style="animation-duration: 1.2s;" />
      </g>

      <!-- The Pipeline -->
      <!-- Left Pipe Segment -->
      <path d="M -50 430 L 600 430 L 600 450 L -50 450 Z" fill="url(#pipe-grad)"/>
      <path d="M -50 570 L 600 570 L 600 590 L -50 590 Z" fill="url(#pipe-grad)"/>
      <!-- Flange Left -->
      <rect x="580" y="410" width="20" height="200" fill="url(#metal-grad)" rx="2"/>
      
      <!-- Right Pipe Segment -->
      <path d="M 800 430 L 1450 430 L 1450 450 L 800 450 Z" fill="url(#pipe-grad)"/>
      <path d="M 800 570 L 1450 570 L 1450 590 L 800 590 Z" fill="url(#pipe-grad)"/>
      <!-- Flange Right -->
      <rect x="800" y="410" width="20" height="200" fill="url(#metal-grad)" rx="2"/>

      <!-- Valve Body (Center) -->
      <rect x="600" y="420" width="200" height="180" fill="#1e293b" stroke="#475569" stroke-width="2"/>
      <circle cx="700" cy="510" r="85" fill="#0f172a" stroke="#334155" stroke-width="4"/>

      <!-- The Butterfly Valve Disc -->
      <!-- rx animates from 4 (open) to 80 (closed) to simulate 3D rotation in 0.2s -->
      <ellipse id="valve-disc" cx="700" cy="510" rx="4" ry="80" fill="url(#metal-grad)" stroke="#94a3b8" stroke-width="2">
        <animate id="close-anim" attributeName="rx" values="4; 80" dur="0.2s" begin="indefinite" fill="freeze" calcMode="spline" keySplines="0.25 0.1 0.25 1" />
        <animate id="open-anim" attributeName="rx" values="80; 4" dur="1s" begin="indefinite" fill="freeze" calcMode="spline" keySplines="0.4 0 0.2 1" />
      </ellipse>
      <!-- Valve Axis -->
      <rect x="696" y="400" width="8" height="220" fill="#94a3b8"/>

      <!-- Actuator Mechanism (Top) -->
      <!-- Support Columns -->
      <rect x="630" y="280" width="10" height="140" fill="#475569"/>
      <rect x="760" y="280" width="10" height="140" fill="#475569"/>
      
      <!-- Linear Motor / Electromagnet Housing -->
      <rect x="610" y="160" width="180" height="140" fill="url(#metal-grad)" rx="8" stroke="#cbd5e1" stroke-width="2"/>
      
      <!-- Internal Coils -->
      <rect x="630" y="180" width="40" height="100" fill="#b45309" stroke="#78350f" stroke-width="1"/>
      <rect x="730" y="180" width="40" height="100" fill="#b45309" stroke="#78350f" stroke-width="1"/>
      <!-- Magnetic Field Indicator (Hidden normally) -->
      <rect id="mag-field" x="620" y="170" width="160" height="120" fill="rgba(239, 68, 68, 0)" filter="url(#glow-red)" pointer-events="none" transition="fill 0.1s"/>

      <!-- Moving Stem/Armature -->
      <g id="actuator-stem">
        <rect x="685" y="170" width="30" height="250" fill="#e2e8f0" stroke="#64748b"/>
        <!-- Connection to valve axis -->
        <circle cx="700" cy="400" r="10" fill="#94a3b8"/>
        <!-- Animation for plunging down 90deg rotation equivalent -->
        <animateTransform id="stem-down" attributeName="transform" type="translate" from="0 0" to="0 30" dur="0.2s" begin="indefinite" fill="freeze" calcMode="spline" keySplines="0.25 0.1 0.25 1" />
        <animateTransform id="stem-up" attributeName="transform" type="translate" from="0 30" to="0 0" dur="1s" begin="indefinite" fill="freeze" calcMode="spline" keySplines="0.4 0 0.2 1" />
      </g>

    </g> <!-- End Main Assembly -->

    <!-- Control Systems & Wiring -->
    <!-- Wires -->
    <path d="M 400 230 L 610 230" class="signal-line" id="wire-plc" fill="none"/>
    <path d="M 1000 230 L 790 230" class="signal-line" id="wire-cap" fill="none" style="animation-direction: reverse;"/>

    <!-- PLC Controller (Left) -->
    <g transform="translate(200, 160)">
      <rect width="200" height="140" fill="#1e293b" stroke="#475569" stroke-width="2" rx="4"/>
      <text x="20" y="30" class="panel-text" font-weight="bold">PLC_PULSE_BOARD</text>
      <!-- Blinking Lights -->
      <circle cx="30" cy="60" r="6" fill="#10b981" filter="url(#glow-blue)"/>
      <text x="50" y="64" class="panel-text">监控就绪</text>
      
      <circle id="plc-alert-light" cx="30" cy="90" r="6" fill="#334155"/>
      <text x="50" y="94" class="panel-text">触发指令</text>
      
      <!-- Tiny detail lines -->
      <path d="M 160 50 L 180 50 M 160 70 L 180 70 M 160 90 L 180 90" stroke="#475569" stroke-width="2"/>
    </g>

    <!-- Capacitor Bank (Right) -->
    <g transform="translate(1000, 150)">
      <rect width="220" height="160" fill="#1e293b" stroke="#475569" stroke-width="2" rx="4"/>
      <text x="20" y="30" class="panel-text" font-weight="bold">CAPACITOR_BANK</text>
      
      <!-- Capacitors -->
      <g id="capacitors" fill="#334155" stroke="#94a3b8">
        <rect x="20" y="50" width="40" height="80" rx="4"/>
        <rect x="70" y="50" width="40" height="80" rx="4"/>
        <rect x="120" y="50" width="40" height="80" rx="4"/>
        <rect x="170" y="50" width="40" height="80" rx="4"/>
      </g>
      <!-- Energy Overlay -->
      <rect id="cap-energy" x="15" y="45" width="200" height="90" fill="rgba(245, 158, 11, 0)" filter="url(#glow-yellow)" pointer-events="none" transition="fill 0.1s"/>
      
      <text id="cap-status" x="20" y="145" class="panel-text status-energy">100% 满充等待</text>
    </g>

    <!-- Pressure Wave & Blockage Impact Graphic (Hidden initially) -->
    <g id="impact-graphic" transform="translate(600, 510)" opacity="0" transition="opacity 0.2s">
      <path d="M -20 -80 Q -60 0 -20 80 Q 0 0 -20 -80" fill="none" stroke="#ef4444" stroke-width="4" filter="url(#glow-red)"/>
      <path d="M -40 -90 Q -90 0 -40 90 Q -20 0 -40 -90" fill="none" stroke="#ef4444" stroke-width="2" filter="url(#glow-red)"/>
      <text x="-120" y="-30" class="panel-text status-alert" font-weight="bold" filter="url(#glow-red)">流体阻断</text>
      <text x="-120" y="-10" class="panel-text status-alert" font-weight="bold" filter="url(#glow-red)">1.6 MPa 承压</text>
    </g>

    <!-- Danger Indicator (Well Kick Flash) -->
    <rect id="danger-flash" x="0" y="450" width="200" height="120" fill="rgba(239, 68, 68, 0)" pointer-events="none" transition="fill 0.1s"/>
    <text id="danger-text" x="50" y="520" font-family="'JetBrains Mono', monospace" font-size="24" font-weight="bold" fill="#ef4444" filter="url(#glow-red)" opacity="0" transition="opacity 0.1s">! 井涌触发 !</text>

  </svg>
</div>

<script>
  // DOM Elements
  const uiStatus = document.getElementById('ui-status');
  const uiVelocity = document.getElementById('ui-velocity');
  
  const fluidBg = document.getElementById('fluid-bg');
  const flowParticles = document.querySelectorAll('.flow-particle');
  
  const plcAlertLight = document.getElementById('plc-alert-light');
  const wirePlc = document.getElementById('wire-plc');
  const wireCap = document.getElementById('wire-cap');
  const capEnergy = document.getElementById('cap-energy');
  const capStatus = document.getElementById('cap-status');
  
  const magField = document.getElementById('mag-field');
  const animClose = document.getElementById('close-anim');
  const animOpen = document.getElementById('open-anim');
  const stemDown = document.getElementById('stem-down');
  const stemUp = document.getElementById('stem-up');
  const mainAssembly = document.getElementById('main-assembly');
  
  const impactGraphic = document.getElementById('impact-graphic');
  const dangerFlash = document.getElementById('danger-flash');
  const dangerText = document.getElementById('danger-text');

  // Utility to pause execution
  const sleep = ms => new Promise(r => setTimeout(r, ms));

  // The main orchestration loop
  async function runSequence() {
    // Initial short delay before first loop
    await sleep(1000);

    while (true) {
      /* ========================================================
         STATE 1: NORMAL OPERATION
      ======================================================== */
      uiStatus.textContent = "正常监控中";
      uiStatus.className = "status-normal";
      uiVelocity.textContent = "12.4 m/s";
      fluidBg.classList.remove('blocked');
      flowParticles.forEach(p => p.classList.remove('blocked'));
      capStatus.textContent = "100% 满充等待";
      capStatus.className = "status-energy";
      
      // Wait for a few seconds of normal operation
      await sleep(3500);

      /* ========================================================
         STATE 2: TRIGGER (WELL KICK DETECTION)
      ======================================================== */
      uiStatus.textContent = "警告:检测到井涌!";
      uiStatus.className = "status-alert";
      
      // Flash danger at pipe inlet
      dangerFlash.style.fill = "rgba(239, 68, 68, 0.4)";
      dangerText.style.opacity = "1";
      plcAlertLight.style.fill = "#ef4444";
      plcAlertLight.style.filter = "url(#glow-red)";

      await sleep(400); // 0.4s reaction time of system

      /* ========================================================
         STATE 3: PLC SIGNAL & RESOURCE ACTIVATION (TRIZ IFR utilization)
      ======================================================== */
      // PLC sends pulse
      wirePlc.classList.add('active');
      await sleep(100);
      
      // Capacitor Bank discharges instantly to provide massive force
      wireCap.classList.add('active');
      capEnergy.style.fill = "rgba(245, 158, 11, 0.6)";
      capStatus.textContent = "瞬时放电 (0ms)";
      capStatus.className = "status-alert";
      
      // Electromagnet powers up
      magField.style.fill = "rgba(239, 68, 68, 0.5)";

      /* ========================================================
         STATE 4: INSTANT ACTION (≤0.2s CLOSURE)
      ======================================================== */
      // Trigger SVG Animations for 0.2s fast close
      animClose.beginElement();
      stemDown.beginElement();
      
      // Wait exactly 200ms to match the mechanical specification
      await sleep(200);

      /* ========================================================
         STATE 5: IMPACT & BLOCKAGE
      ======================================================== */
      // Shut off energy graphics immediately after stroke
      wirePlc.classList.remove('active');
      wireCap.classList.remove('active');
      capEnergy.style.fill = "rgba(245, 158, 11, 0)";
      magField.style.fill = "rgba(239, 68, 68, 0)";
      capStatus.textContent = "0% 需要充电";
      capStatus.className = "panel-text";
      
      // Impact effects
      mainAssembly.classList.add('shake');
      dangerFlash.style.fill = "rgba(239, 68, 68, 0)";
      dangerText.style.opacity = "0";
      
      // Update fluid physics
      fluidBg.classList.add('blocked');
      flowParticles.forEach(p => p.classList.add('blocked'));
      uiVelocity.textContent = "0.0 m/s (已切断)";
      uiVelocity.className = "panel-value status-alert";
      uiStatus.textContent = "全关完成 耗时: 0.18s";
      
      // Show pressure wave blocking graphics
      impactGraphic.style.opacity = "1";

      // Hold this state to let the user process the result
      await sleep(4000);

      /* ========================================================
         STATE 6: SYSTEM RESET (Prepping for loop)
      ======================================================== */
      uiStatus.textContent = "系统重置中...";
      uiStatus.className = "panel-text";
      uiVelocity.className = "panel-value";
      
      // Remove impact visuals
      impactGraphic.style.opacity = "0";
      mainAssembly.classList.remove('shake');
      plcAlertLight.style.fill = "#334155";
      plcAlertLight.style.filter = "none";
      
      // Slow open animation (1s)
      animOpen.beginElement();
      stemUp.beginElement();
      
      // Simulate capacitor recharging
      capStatus.textContent = "充电中...";
      await sleep(1000); // Wait for physical open
      
      // Ready for next loop
    }
  }

  // Auto-start on load per requirements
  document.addEventListener("DOMContentLoaded", () => {
    runSequence();
  });
</script>

</body>
</html>
积分规则:每轮对话扣10分