独立渲染引擎就绪引擎就绪
<!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分
等待动画代码生成...
