独立渲染引擎就绪引擎就绪
<!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>
:root {
--bg-color: #050914;
--grid-color: rgba(30, 55, 90, 0.3);
--machine-stroke: #4a6b8c;
--machine-fill: #0c1524;
--fluid-color: #ff6a00;
--vacuum-color: #00f0ff;
--text-main: #e0f2fe;
--text-dim: #7dd3fc;
--panel-bg: rgba(6, 14, 28, 0.85);
--panel-border: #1e3a5f;
--ui-font: 'Courier New', Courier, monospace;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-color);
color: var(--text-main);
font-family: var(--ui-font);
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
background-image:
linear-gradient(var(--grid-color) 1px, transparent 1px),
linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
background-size: 40px 40px;
background-position: center center;
}
.animation-container {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
max-width: 1400px;
}
svg {
width: 100%;
height: 100%;
max-height: 90vh;
filter: drop-shadow(0 0 20px rgba(0, 240, 255, 0.05));
}
/* HUD & Controls */
.hud-panel {
position: absolute;
background: var(--panel-bg);
border: 1px solid var(--panel-border);
border-left: 3px solid var(--vacuum-color);
padding: 16px 20px;
backdrop-filter: blur(8px);
box-shadow: 0 10px 30px rgba(0,0,0,0.5);
z-index: 10;
}
.hud-title {
font-size: 14px;
font-weight: bold;
color: var(--vacuum-color);
margin-bottom: 12px;
text-transform: uppercase;
letter-spacing: 2px;
}
.control-panel {
bottom: 40px;
left: 50%;
transform: translateX(-50%);
width: 400px;
display: flex;
flex-direction: column;
gap: 10px;
border-left: none;
border-bottom: 3px solid var(--vacuum-color);
}
.data-panel {
top: 40px;
right: 40px;
width: 260px;
}
.data-row {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
font-size: 12px;
}
.data-label { color: var(--text-dim); }
.data-value {
color: var(--vacuum-color);
font-weight: bold;
text-shadow: 0 0 5px rgba(0, 240, 255, 0.5);
}
.data-value.fluid-val {
color: var(--fluid-color);
text-shadow: 0 0 5px rgba(255, 106, 0, 0.5);
}
/* Custom Slider */
.slider-container {
display: flex;
align-items: center;
gap: 15px;
margin-top: 5px;
}
input[type=range] {
-webkit-appearance: none;
width: 100%;
background: transparent;
}
input[type=range]:focus { outline: none; }
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 4px;
cursor: pointer;
background: var(--machine-stroke);
border-radius: 2px;
}
input[type=range]::-webkit-slider-thumb {
height: 16px;
width: 8px;
border-radius: 2px;
background: var(--vacuum-color);
cursor: pointer;
-webkit-appearance: none;
margin-top: -6px;
box-shadow: 0 0 10px var(--vacuum-color);
}
/* Animations */
@keyframes rotateFan {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes flowDown {
0% { stroke-dashoffset: 40; opacity: 0; }
20% { opacity: 1; }
80% { opacity: 1; }
100% { stroke-dashoffset: 0; opacity: 0; }
}
@keyframes pulseGlow {
0% { filter: drop-shadow(0 0 5px var(--vacuum-color)); }
50% { filter: drop-shadow(0 0 15px var(--vacuum-color)); }
100% { filter: drop-shadow(0 0 5px var(--vacuum-color)); }
}
@keyframes fluidMove {
from { stroke-dashoffset: 60; }
to { stroke-dashoffset: 0; }
}
@keyframes particleDrop {
0% { transform: translateY(0); opacity: 0; }
10% { opacity: 1; }
90% { opacity: 1; }
100% { transform: translateY(150px); opacity: 0; }
}
.fan-blades {
transform-origin: 780px 420px;
animation: rotateFan 1.5s linear infinite;
}
.vacuum-flow {
stroke: var(--vacuum-color);
stroke-width: 2;
stroke-dasharray: 10 30;
animation: flowDown 1s linear infinite;
}
.fluid-stream {
stroke-dasharray: 20 40;
animation: fluidMove 2s linear infinite;
}
.drip {
fill: var(--fluid-color);
animation: particleDrop 1.2s cubic-bezier(0.4, 0, 1, 1) infinite;
}
/* Delay variations for natural look */
.d1 { animation-delay: 0.1s; } .d2 { animation-delay: 0.4s; }
.d3 { animation-delay: 0.7s; } .d4 { animation-delay: 0.2s; }
.d5 { animation-delay: 0.5s; } .d6 { animation-delay: 0.8s; }
.d7 { animation-delay: 0.3s; } .d8 { animation-delay: 0.9s; }
</style>
</head>
<body>
<div class="animation-container">
<!-- SVG Architecture -->
<svg viewBox="0 0 1000 650" preserveAspectRatio="xMidYMid meet" id="mainSvg">
<defs>
<!-- Gradients & Filters -->
<linearGradient id="fluidGrad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#ff8c00" stop-opacity="0.9"/>
<stop offset="100%" stop-color="#cc4400" stop-opacity="0.8"/>
</linearGradient>
<linearGradient id="machineGrad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#122236"/>
<stop offset="100%" stop-color="#0a121d"/>
</linearGradient>
<filter id="neonGlow" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="4" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over" />
</filter>
<filter id="orangeGlow" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="3" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over" />
</filter>
<pattern id="screenMesh" width="8" height="8" patternUnits="userSpaceOnUse">
<path d="M 8 0 L 0 0 0 8" fill="none" stroke="#5a8bba" stroke-width="0.5"/>
</pattern>
</defs>
<!-- Static Annotations / Backdrop -->
<g opacity="0.3" font-size="10" fill="var(--text-dim)">
<line x1="100" y1="280" x2="900" y2="280" stroke="var(--grid-color)" stroke-width="1" stroke-dasharray="4 4"/>
<text x="100" y="275">DATUM LINE: +0.00</text>
<text x="780" y="320">EXHAUST SYSTEM</text>
</g>
<!-- Background Machinery (Chamber Back) -->
<path d="M 250 280 L 700 280 L 700 300 L 650 450 L 300 450 L 250 300 Z" fill="var(--machine-fill)" stroke="none"/>
<!-- Vacuum Chamber Inner Effect -->
<path d="M 255 285 L 695 285 L 645 445 L 305 445 Z" fill="rgba(0, 240, 255, 0.03)" id="chamberGlow"/>
<!-- Fluid Input (Left) -->
<path d="M 120 150 L 220 150 L 220 260" fill="none" stroke="var(--machine-stroke)" stroke-width="20" stroke-linejoin="round"/>
<path d="M 120 150 L 220 150 L 220 260" fill="none" stroke="#0a121d" stroke-width="16" stroke-linejoin="round"/>
<path d="M 120 150 L 220 150 L 220 280" fill="none" stroke="var(--fluid-color)" stroke-width="12" class="fluid-stream" stroke-linejoin="round" filter="url(#orangeGlow)"/>
<!-- Main Screen (Vibrating Mesh) -->
<rect x="230" y="276" width="490" height="8" fill="url(#screenMesh)" stroke="var(--machine-stroke)" stroke-width="1"/>
<line x1="230" y1="284" x2="720" y2="284" stroke="var(--machine-stroke)" stroke-width="2"/>
<!-- Liquid Film (Dynamic Thickness) -->
<!-- The origin is set at the bottom (y=276) so scaling affects height -->
<rect id="liquidFilm" x="240" y="246" width="460" height="30" fill="url(#fluidGrad)" rx="2" ry="2" filter="url(#orangeGlow)" style="transform-origin: center 276px; transition: transform 0.3s ease;"/>
<!-- Surface wave/movement effect on fluid -->
<path id="fluidSurface" d="M 240 246 Q 355 246 470 246 T 700 246" fill="none" stroke="#ffaa55" stroke-width="1" opacity="0.6" style="transition: all 0.3s ease;"/>
<!-- Dripping Fluid Through Screen -->
<g id="dripGroup">
<!-- Generated dynamically or hardcoded delays -->
<circle cx="280" cy="285" r="3" class="drip d1"/>
<circle cx="330" cy="285" r="4" class="drip d2"/>
<circle cx="380" cy="285" r="2.5" class="drip d3"/>
<circle cx="430" cy="285" r="3.5" class="drip d4"/>
<circle cx="480" cy="285" r="3" class="drip d5"/>
<circle cx="530" cy="285" r="4" class="drip d6"/>
<circle cx="580" cy="285" r="2" class="drip d7"/>
<circle cx="630" cy="285" r="3" class="drip d8"/>
<circle cx="670" cy="285" r="2.5" class="drip d1"/>
</g>
<!-- Bottom Collected Fluid -->
<path d="M 310 445 L 640 445 Q 645 450 645 455 L 645 480 L 305 480 L 305 455 Q 305 450 310 445 Z" fill="url(#fluidGrad)" opacity="0.8"/>
<path d="M 450 480 L 450 550" fill="none" stroke="var(--fluid-color)" stroke-width="10" class="fluid-stream"/>
<rect x="430" y="480" width="40" height="10" fill="var(--machine-stroke)"/>
<!-- Negative Pressure Chamber & Pipes (Foreground) -->
<path d="M 230 284 L 720 284 L 720 300 L 650 450 L 300 450 L 230 300 Z" fill="none" stroke="var(--machine-stroke)" stroke-width="3"/>
<!-- Pipe to Fan -->
<path d="M 645 400 L 750 400 L 750 440 L 645 440" fill="var(--machine-fill)" stroke="var(--machine-stroke)" stroke-width="2"/>
<!-- Vacuum Flow Lines (Arrows pulling down) -->
<g id="vacuumFlowGroup" opacity="0.8">
<!-- Vertical pulls -->
<line x1="280" y1="310" x2="280" y2="420" class="vacuum-flow"/>
<line x1="380" y1="310" x2="380" y2="430" class="vacuum-flow"/>
<line x1="480" y1="310" x2="480" y2="430" class="vacuum-flow"/>
<line x1="580" y1="310" x2="580" y2="420" class="vacuum-flow"/>
<line x1="660" y1="310" x2="660" y2="380" class="vacuum-flow"/>
<!-- Horizontal pull to fan -->
<line x1="620" y1="420" x2="740" y2="420" class="vacuum-flow" style="animation-name: fluidMove; animation-duration: 0.5s;"/>
</g>
<!-- Centrifugal Fan -->
<g id="fanSystem" transform="translate(0, 0)">
<!-- Housing -->
<circle cx="780" cy="420" r="45" fill="var(--machine-fill)" stroke="var(--machine-stroke)" stroke-width="3"/>
<circle cx="780" cy="420" r="35" fill="#050914" stroke="var(--machine-stroke)" stroke-width="1"/>
<!-- Blades -->
<g class="fan-blades" id="blades">
<circle cx="780" cy="420" r="8" fill="var(--machine-stroke)"/>
<path d="M 780 412 L 780 385 Q 795 385 800 405 Z" fill="var(--machine-stroke)"/>
<path d="M 788 420 L 815 420 Q 815 435 795 440 Z" fill="var(--machine-stroke)"/>
<path d="M 780 428 L 780 455 Q 765 455 760 435 Z" fill="var(--machine-stroke)"/>
<path d="M 772 420 L 745 420 Q 745 405 765 400 Z" fill="var(--machine-stroke)"/>
</g>
<!-- Exhaust -->
<path d="M 780 375 L 825 330 L 850 355 L 825 380 Z" fill="var(--machine-fill)" stroke="var(--machine-stroke)" stroke-width="2"/>
<path d="M 830 340 L 870 300" fill="none" stroke="var(--vacuum-color)" stroke-width="2" stroke-dasharray="5 15" class="fluid-stream" filter="url(#neonGlow)"/>
</g>
<!-- Dry Solids (Right) -->
<path d="M 720 270 L 800 270" fill="none" stroke="var(--machine-stroke)" stroke-width="4"/>
<g id="drySolids">
<rect x="730" y="260" width="8" height="8" fill="#a09080" class="drip d2" style="animation-name: particleDrop;"/>
<rect x="750" y="262" width="6" height="6" fill="#807060" class="drip d5" style="animation-name: particleDrop;"/>
<rect x="770" y="258" width="10" height="10" fill="#908070" class="drip d1" style="animation-name: particleDrop;"/>
</g>
<!-- Callout Lines and minimal text in SVG context -->
<g font-size="11" fill="var(--text-main)" filter="url(#neonGlow)">
<line x1="550" y1="210" x2="600" y2="246" stroke="var(--vacuum-color)" stroke-width="1"/>
<circle cx="600" cy="246" r="2" fill="var(--vacuum-color)"/>
<text x="490" y="200" fill="var(--vacuum-color)">液膜厚度 (Film Thickness)</text>
<line x1="680" y1="360" x2="740" y2="380" stroke="var(--vacuum-color)" stroke-width="1"/>
<circle cx="680" cy="360" r="2" fill="var(--vacuum-color)"/>
<text x="680" y="350" fill="var(--vacuum-color)">强制抽风室 (-kPa)</text>
</g>
</svg>
<!-- Right Side Data Panel -->
<div class="hud-panel data-panel">
<div class="hud-title">系统状态监控</div>
<div class="data-row">
<span class="data-label">运行模式:</span>
<span class="data-value" style="color: #4ade80;">IFR 最优解</span>
</div>
<div class="data-row">
<span class="data-label">实时负压:</span>
<span class="data-value" id="valPressure">-4.0 kPa</span>
</div>
<div class="data-row">
<span class="data-label">排风量:</span>
<span class="data-value" id="valFlow">1000 m³/h</span>
</div>
<div class="data-row">
<span class="data-label">液膜厚度指数:</span>
<span class="data-value fluid-val" id="valFilm">50%</span>
</div>
<div class="data-row" style="margin-top: 15px; border-top: 1px solid var(--panel-border); padding-top: 10px;">
<span class="data-label" style="font-size: 10px; line-height: 1.4;">原理: 增加可调负压室,强制液相透筛,在不增加系统复杂度的前提下解决高黏液膜积聚矛盾。</span>
</div>
</div>
<!-- Bottom Control Panel -->
<div class="hud-panel control-panel">
<div class="hud-title">负压差调节 (kPa)</div>
<div class="slider-container">
<span style="font-size: 12px; color: var(--text-dim);">-3.0</span>
<input type="range" id="pressureSlider" min="3.0" max="5.0" step="0.1" value="4.0">
<span style="font-size: 12px; color: var(--text-dim);">-5.0</span>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const slider = document.getElementById('pressureSlider');
const film = document.getElementById('liquidFilm');
const filmSurface = document.getElementById('fluidSurface');
const blades = document.getElementById('blades');
const vacuumFlow = document.getElementById('vacuumFlowGroup');
const chamberGlow = document.getElementById('chamberGlow');
const drips = document.querySelectorAll('.drip');
const valPressure = document.getElementById('valPressure');
const valFlow = document.getElementById('valFlow');
const valFilm = document.getElementById('valFilm');
function updateSystem() {
const pressure = parseFloat(slider.value); // range: 3.0 to 5.0
// 1. Calculate values
// scale ratio: 0 (at 3.0) to 1 (at 5.0)
const ratio = (pressure - 3.0) / 2.0;
// Update UI text
valPressure.textContent = `-${pressure.toFixed(1)} kPa`;
const flowVol = 800 + (ratio * 400); // 800 to 1200
valFlow.textContent = `${Math.round(flowVol)} m³/h`;
// 2. Liquid Film Thickness (Thickest at 3.0, thinnest at 5.0)
// Using transform scaleY. Default height is 30.
// At 3.0 (ratio=0), scale = 1.2 (thick)
// At 5.0 (ratio=1), scale = 0.3 (very thin)
const scaleY = 1.2 - (ratio * 0.9);
film.style.transform = `scaleY(${scaleY})`;
// Update surface wave position mapping
const baseHeight = 246; // y coord of top
const actualHeight = 30 * scaleY;
const newY = 276 - actualHeight;
filmSurface.setAttribute('d', `M 240 ${newY} Q 355 ${newY - 5} 470 ${newY} T 700 ${newY}`);
valFilm.textContent = `${Math.round(scaleY * 100)}%`;
// 3. Fan Speed (Faster at 5.0)
// duration: 2s (at 3.0) to 0.5s (at 5.0)
const fanSpeed = 2.0 - (ratio * 1.5);
blades.style.animationDuration = `${fanSpeed}s`;
// 4. Vacuum Visual Intensity
const opacity = 0.4 + (ratio * 0.6);
vacuumFlow.style.opacity = opacity;
chamberGlow.style.fill = `rgba(0, 240, 255, ${0.02 + ratio * 0.08})`;
const flowSpeed = 1.2 - (ratio * 0.8); // 1.2s to 0.4s
const flowLines = document.querySelectorAll('.vacuum-flow');
flowLines.forEach(line => {
if(!line.style.animationName) {
line.style.animationDuration = `${flowSpeed}s`;
}
});
// 5. Drip Rate (Faster processing at high vacuum)
const dripSpeed = 1.5 - (ratio * 0.9); // 1.5s to 0.6s
drips.forEach(drip => {
drip.style.animationDuration = `${dripSpeed}s`;
});
}
// Bind events
slider.addEventListener('input', updateSystem);
// Initial call to set states
updateSystem();
});
</script>
</body>
</html>
<!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>
:root {
--bg-color: #050914;
--panel-bg: rgba(15, 23, 42, 0.75);
--panel-border: #1e293b;
--text-main: #f8fafc;
--text-muted: #94a3b8;
--accent-blue: #00e5ff;
--accent-orange: #ffab00;
--flow-speed: 1s;
--flow-opacity: 0.7;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
body, html {
width: 100%;
height: 100%;
background-color: var(--bg-color);
overflow: hidden;
color: var(--text-main);
}
.container {
position: relative;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-image:
linear-gradient(rgba(255,255,255,0.02) 1px, transparent 1px),
linear-gradient(90deg, rgba(255,255,255,0.02) 1px, transparent 1px);
background-size: 40px 40px;
}
#main-svg {
width: 100%;
height: 100%;
max-width: 1400px;
}
/* UI Control Panel */
.control-panel {
position: absolute;
top: 40px;
left: 40px;
width: 340px;
background: var(--panel-bg);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid var(--panel-border);
border-radius: 12px;
padding: 24px;
box-shadow: 0 20px 40px rgba(0,0,0,0.5), inset 0 1px 0 rgba(255,255,255,0.1);
z-index: 10;
}
.control-panel h2 {
font-size: 18px;
font-weight: 600;
margin-bottom: 8px;
color: #ffffff;
letter-spacing: 0.5px;
}
.control-panel p.subtitle {
font-size: 12px;
color: var(--accent-blue);
margin-bottom: 24px;
display: flex;
align-items: center;
gap: 6px;
}
.control-panel p.subtitle::before {
content: '';
display: inline-block;
width: 8px;
height: 8px;
background: var(--accent-blue);
border-radius: 50%;
box-shadow: 0 0 8px var(--accent-blue);
}
.slider-group {
margin-bottom: 24px;
}
.slider-group label {
display: flex;
justify-content: space-between;
font-size: 13px;
color: var(--text-muted);
margin-bottom: 12px;
}
input[type=range] {
-webkit-appearance: none;
width: 100%;
background: transparent;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
height: 20px;
width: 20px;
border-radius: 50%;
background: var(--accent-blue);
cursor: pointer;
margin-top: -8px;
box-shadow: 0 0 15px rgba(0, 229, 255, 0.6);
border: 2px solid #fff;
transition: transform 0.1s;
}
input[type=range]::-webkit-slider-thumb:active {
transform: scale(1.1);
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 4px;
cursor: pointer;
background: #334155;
border-radius: 2px;
}
.stats-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-top: 24px;
padding-top: 24px;
border-top: 1px solid rgba(255,255,255,0.05);
}
.stat-box {
display: flex;
flex-direction: column;
gap: 4px;
}
.stat-box .label {
font-size: 12px;
color: var(--text-muted);
}
.stat-box .value {
font-size: 20px;
font-weight: 700;
color: #fff;
font-variant-numeric: tabular-nums;
}
.stat-box .value.highlight {
color: var(--accent-blue);
text-shadow: 0 0 10px rgba(0, 229, 255, 0.3);
}
/* SVG Animations */
.flow-line {
stroke-dasharray: 12 18;
animation: flow var(--flow-speed) linear infinite;
opacity: var(--flow-opacity);
}
@keyframes flow {
to { stroke-dashoffset: -30; }
}
.spin {
transform-origin: 1020px 220px;
animation: spin 0.5s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.liquid-wave {
animation: wave 3s ease-in-out infinite alternate;
}
@keyframes wave {
0% { transform: translateY(0); }
100% { transform: translateY(4px); }
}
/* Data transmission line animation */
.data-line {
stroke-dasharray: 4 8;
animation: data-flow 20s linear infinite;
}
@keyframes data-flow {
to { stroke-dashoffset: -400; }
}
</style>
</head>
<body>
<div class="container">
<!-- 控制面板 -->
<div class="control-panel">
<h2>强制排液筛控制系统</h2>
<p class="subtitle">IFR: 最终理想解状态运行中</p>
<div class="slider-group">
<label>
<span>排液吸力调节</span>
<span id="label-power">75%</span>
</label>
<input type="range" id="power-slider" min="0" max="100" value="75">
</div>
<div class="stats-grid">
<div class="stat-box">
<span class="label">筛下负压差</span>
<span class="value highlight" id="val-pressure">-4.5 kPa</span>
</div>
<div class="stat-box">
<span class="label">风机排量</span>
<span class="value" id="val-volume">1100 m³/h</span>
</div>
<div class="stat-box">
<span class="label">液膜脱水率</span>
<span class="value" id="val-eff">92.5 %</span>
</div>
<div class="stat-box">
<span class="label">固相含水</span>
<span class="value" id="val-moisture">极低</span>
</div>
</div>
</div>
<!-- 主体 SVG 动画 -->
<svg viewBox="0 0 1200 700" id="main-svg" preserveAspectRatio="xMidYMid meet">
<defs>
<!-- 霓虹发光滤镜 -->
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="3" result="blur" />
<feMerge>
<feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<filter id="glow-strong" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="6" result="blur" />
<feMerge>
<feMergeNode in="blur" />
<feMergeNode in="blur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<!-- 渐变定义 -->
<linearGradient id="metal-grad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#1e293b" />
<stop offset="100%" stop-color="#0f172a" />
</linearGradient>
<linearGradient id="liquid-grad" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="rgba(0, 229, 255, 0.9)" />
<stop offset="100%" stop-color="rgba(0, 229, 255, 0.1)" />
</linearGradient>
<!-- 箭头标记 -->
<marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto">
<path d="M 0 1 L 8 5 L 0 9 z" fill="#00e5ff" opacity="0.8"/>
</marker>
</defs>
<!-- 连线:传感器到面板 -->
<path d="M 500 380 L 380 380 L 380 200 L 380 200" fill="none" stroke="#00e5ff" stroke-width="1" class="data-line" opacity="0.4"/>
<circle cx="500" cy="380" r="3" fill="#00e5ff" filter="url(#glow)" />
<!-- 设备主体结构 -->
<g id="equipment">
<!-- 固相接收箱 (背景) -->
<path d="M 660 300 L 740 300 L 710 520 L 630 520 Z" fill="#0f172a" stroke="#1e293b" stroke-width="2"/>
<!-- 筛下密闭罩 (负压室)外壳 -->
<path d="M 140 240 L 660 280 L 660 330 L 460 500 L 250 500 L 140 300 Z" fill="url(#metal-grad)" stroke="#334155" stroke-width="3" stroke-linejoin="round"/>
<!-- 密闭罩内部暗区 -->
<path d="M 155 250 L 645 288 L 645 320 L 450 485 L 260 485 L 155 295 Z" fill="#050b14"/>
<!-- 排液管与下部液池 -->
<rect x="330" y="500" width="80" height="40" fill="#1e293b" stroke="#334155" stroke-width="2"/>
<rect x="250" y="540" width="240" height="110" rx="8" fill="url(#metal-grad)" stroke="#334155" stroke-width="3"/>
<!-- 池内液体 -->
<path class="liquid-wave" d="M 255 570 Q 310 565 370 570 T 485 570 L 485 645 L 255 645 Z" fill="#00e5ff" opacity="0.5"/>
<path class="liquid-wave" d="M 255 575 Q 310 580 370 575 T 485 575 L 485 645 L 255 645 Z" fill="#00e5ff" opacity="0.3" style="animation-delay: -1.5s"/>
<!-- 进料斗 -->
<path d="M 100 80 L 100 180 L 140 230 L 180 230 L 180 80 Z" fill="url(#metal-grad)" stroke="#334155" stroke-width="2" stroke-linejoin="round"/>
<!-- 进料泥浆背景 -->
<path d="M 110 80 L 110 180 C 110 210 130 220 150 225 L 150 210 C 130 205 125 190 125 80 Z" fill="#00e5ff" opacity="0.3"/>
<!-- 筛网 -->
<line x1="150" y1="245" x2="650" y2="285" stroke="#94a3b8" stroke-width="5" stroke-dasharray="10 4" stroke-linecap="round"/>
<!-- 抽风管道口与挡板 (筛下) -->
<path d="M 645 290 L 620 310 L 645 320 Z" fill="#1e293b"/>
<!-- 抽排风主管道 -->
<path d="M 645 305 L 700 305 L 700 200 L 780 200" fill="none" stroke="#1e293b" stroke-width="24" stroke-linejoin="round"/>
<path d="M 645 305 L 700 305 L 700 200 L 780 200" fill="none" stroke="#050914" stroke-width="18" stroke-linejoin="round"/>
<!-- 水雾分离器 -->
<rect x="780" y="140" width="100" height="130" rx="4" fill="url(#metal-grad)" stroke="#334155" stroke-width="3"/>
<!-- 分离器内部折流板 -->
<line x1="810" y1="140" x2="810" y2="230" stroke="#475569" stroke-width="4" stroke-linecap="round"/>
<line x1="850" y1="270" x2="850" y2="180" stroke="#475569" stroke-width="4" stroke-linecap="round"/>
<!-- 分离器排液管(极细) -->
<path d="M 830 270 L 830 570 L 490 570" fill="none" stroke="#334155" stroke-width="6" stroke-linejoin="round"/>
<!-- 连接分离器与风机的管道 -->
<path d="M 880 220 L 980 220" fill="none" stroke="#1e293b" stroke-width="24"/>
<path d="M 880 220 L 980 220" fill="none" stroke="#050914" stroke-width="18"/>
<!-- 防爆离心风机 -->
<g id="fan" transform="translate(1020, 220)">
<!-- 支撑底座 -->
<path d="M -20 60 L 20 60 L 40 120 L -40 120 Z" fill="#0f172a" stroke="#1e293b" stroke-width="2"/>
<!-- 向上排气管 -->
<rect x="-55" y="-140" width="36" height="90" fill="#1e293b" stroke="#334155" stroke-width="3"/>
<!-- 蜗壳 -->
<path d="M -50,-30 C -80,-80 70,-100 80,-10 C 90,80 -10,100 -50,60 C -70,40 -70,-10 -50,-30 Z" fill="url(#metal-grad)" stroke="#334155" stroke-width="3"/>
<!-- 旋转叶轮 -->
<g id="impeller" class="spin">
<circle cx="5" cy="0" r="50" fill="#050914" stroke="#475569" stroke-width="2"/>
<path d="M 5,-50 L 5,50 M -45,0 L 55,0 M -30,-35 L 40,35 M -30,35 L 40,-35" stroke="#94a3b8" stroke-width="5"/>
<circle cx="5" cy="0" r="12" fill="#e2e8f0"/>
</g>
<!-- 风机外壳标识 -->
<text x="35" y="-30" fill="#ff3366" font-size="14" font-weight="bold" font-family="Arial" opacity="0.8">EX</text>
</g>
<!-- 负压传感器表盘 -->
<rect x="470" y="360" width="40" height="40" rx="4" fill="#0f172a" stroke="#00e5ff" stroke-width="1" filter="url(#glow)"/>
<text x="490" y="385" fill="#00e5ff" font-size="10" text-anchor="middle" font-family="monospace">P-S</text>
</g>
<!-- 动态流线 (气流) -->
<g id="flow-lines">
<!-- 筛下空间吸气流线 -->
<path d="M 220 310 Q 400 330 645 305 L 700 305 L 700 200 L 780 200" fill="none" stroke="#00e5ff" stroke-width="2" class="flow-line" marker-end="url(#arrow)"/>
<path d="M 350 400 Q 500 360 645 305" fill="none" stroke="#00e5ff" stroke-width="2" class="flow-line" />
<path d="M 480 460 Q 580 400 645 305" fill="none" stroke="#00e5ff" stroke-width="2" class="flow-line" />
<!-- 管道与风机流线 -->
<path d="M 880 220 L 960 220" fill="none" stroke="#00e5ff" stroke-width="2" class="flow-line" marker-end="url(#arrow)"/>
<path d="M 985 200 Q 985 130 1005 100" fill="none" stroke="#00e5ff" stroke-width="2.5" class="flow-line" marker-end="url(#arrow)" filter="url(#glow)"/>
</g>
<!-- 钻井液液膜 (由 JS 控制路径) -->
<path id="liquid-film" fill="url(#liquid-grad)" opacity="0.9" filter="url(#glow)"/>
<!-- 粒子系统容器 -->
<g id="particles-group"></g>
</svg>
</div>
<script>
// DOM Elements
const slider = document.getElementById('power-slider');
const valPressure = document.getElementById('val-pressure');
const valVolume = document.getElementById('val-volume');
const valEff = document.getElementById('val-eff');
const labelPower = document.getElementById('label-power');
const rootStyle = document.documentElement.style;
const film = document.getElementById('liquid-film');
const pGroup = document.getElementById('particles-group');
const impeller = document.getElementById('impeller');
// 系统参数状态
let state = {
power: 75,
pressure: -4.5,
volume: 1100,
eff: 92.5
};
const NS = "http://www.w3.org/2000/svg";
const particles = [];
// 初始化粒子池
function initParticles() {
// 固相颗粒 (橙色)
for(let i=0; i<40; i++){
let c = document.createElementNS(NS, 'circle');
c.setAttribute('r', 2 + Math.random()*2.5);
c.setAttribute('fill', '#ffab00');
pGroup.appendChild(c);
particles.push({el: c, type: 'solid', active: false});
}
// 透筛液滴 (青色)
for(let i=0; i<70; i++){
let c = document.createElementNS(NS, 'circle');
c.setAttribute('r', 1.5 + Math.random()*1.5);
c.setAttribute('fill', '#00e5ff');
c.setAttribute('filter', 'url(#glow)');
pGroup.appendChild(c);
particles.push({el: c, type: 'liquid', active: false});
}
// 分离器排出液滴
for(let i=0; i<5; i++){
let c = document.createElementNS(NS, 'circle');
c.setAttribute('r', 2);
c.setAttribute('fill', '#00e5ff');
pGroup.appendChild(c);
particles.push({el: c, type: 'sep_liquid', active: false});
}
}
// 激活特定类型的粒子
function spawnParticle(type) {
let p = particles.find(pt => pt.type === type && !pt.active);
if(!p) return;
p.active = true;
if(type === 'solid') {
p.x = 130 + Math.random()*15;
p.y = 200;
p.vx = 1.0 + Math.random()*0.5;
p.vy = 0;
} else if (type === 'liquid') {
// 动态计算透筛落点,负压越大,越靠前脱水
// state.power 0-100
let p_ratio = state.power / 100;
let dry_length = 350 - 200 * p_ratio; // 液膜覆盖长度 150 到 350
p.x = 150 + Math.random() * dry_length;
p.y = 245 + (p.x - 150) * 0.08 + 5; // 筛网正下方
p.vx = 0;
p.vy = 0.5 + Math.random();
} else if (type === 'sep_liquid') {
p.x = 830;
p.y = 270;
p.vx = 0;
p.vy = 2;
p.state = 1; // 1: 垂直向下, 2: 水平向左
}
}
// 每帧更新粒子位置
function updateParticles() {
particles.forEach(p => {
if(!p.active) {
p.el.setAttribute('display', 'none');
return;
}
p.el.setAttribute('display', 'inline');
if(p.type === 'solid') {
if(p.x < 650) {
// 在筛网上
let targetY = 245 + (p.x - 150) * 0.08 - p.el.getAttribute('r');
if(p.y < targetY) {
p.y += p.vy;
p.vy += 0.2;
} else {
p.y = targetY;
p.x += p.vx;
p.vy = 0;
}
} else {
// 抛出筛网,掉入回收箱
p.x += p.vx;
p.y += p.vy;
p.vy += 0.2;
if(p.y > 520) p.active = false;
}
}
else if (p.type === 'liquid') {
// 判断是否撞击密闭罩左侧斜面 (155,295) -> (260,485)
// 斜率 k = (485-295)/(260-155) = 1.809
let wallY = 1.809 * (p.x - 155) + 295;
if (p.x < 260 && p.y >= wallY) {
// 沿壁滑落
p.x += 1.0;
p.y += 1.0 * 1.809;
} else {
// 自由落体
p.y += p.vy;
p.vy += 0.15;
}
// 落入液池
if(p.y >= 570) p.active = false;
}
else if (p.type === 'sep_liquid') {
if(p.state === 1) {
p.y += p.vy;
if(p.y >= 570) {
p.y = 570;
p.state = 2;
}
} else if (p.state === 2) {
p.x -= 2;
if(p.x <= 490) p.active = false;
}
}
// 实际更新 DOM 坐标
p.el.setAttribute('cx', p.x);
p.el.setAttribute('cy', p.y);
});
}
// 更新控制面板状态与 SVG 图形
function updateSystemState() {
let p_val = state.power / 100;
// 数据映射:负压 -3 到 -5 kPa
state.pressure = -3.0 - p_val * 2.0;
// 风量 800 - 1200
state.volume = 800 + p_val * 400;
// 效率 75% - 98%
state.eff = 75 + p_val * 23;
// 更新 UI 文字
labelPower.textContent = Math.round(state.power) + '%';
valPressure.textContent = state.pressure.toFixed(1) + ' kPa';
valVolume.textContent = Math.round(state.volume) + ' m³/h';
valEff.textContent = state.eff.toFixed(1) + ' %';
// 更新气流与风机动画速度
let speed = 1.5 - p_val * 1.0; // 0.5s 到 1.5s
rootStyle.setProperty('--flow-speed', speed + 's');
rootStyle.setProperty('--flow-opacity', 0.4 + p_val * 0.6);
impeller.style.animationDuration = (speed * 0.5) + 's';
// 更新液膜形态 (动态缩短、变薄)
// 模拟负压抽干过程:p_val 越大,液膜在越靠前的地方消失
let dry_length = 350 - 200 * p_val; // 液膜存在长度
let endX = 150 + dry_length;
let endY = 245 + (endX - 150) * 0.08;
let path = `
M 150 245
L 150 215
Q ${150 + dry_length*0.4} 220
${endX} ${endY - 2}
L ${endX} ${endY}
Z
`;
film.setAttribute('d', path);
}
// 主循环
function loop() {
// 随机产生固相 (持续进料)
if(Math.random() < 0.4) spawnParticle('solid');
// 产生液滴 (脱水过程,与系统排量正相关)
let dropsPerFrame = Math.floor(1 + state.power/25);
for(let k=0; k<dropsPerFrame; k++) {
if(Math.random() < 0.8) spawnParticle('liquid');
}
// 偶尔产生分离器排液
if(Math.random() < 0.02) spawnParticle('sep_liquid');
updateParticles();
requestAnimationFrame(loop);
}
// 绑定事件与初始化
function init() {
initParticles();
slider.addEventListener('input', (e) => {
state.power = parseInt(e.target.value);
updateSystemState();
});
// 初始状态更新
updateSystemState();
// 预热粒子系统,避免初始画面空洞
for(let i=0; i<150; i++) {
if(Math.random() < 0.4) spawnParticle('solid');
let drops = Math.floor(1 + state.power/25);
for(let k=0; k<drops; k++) spawnParticle('liquid');
updateParticles();
}
// 启动渲染循环
requestAnimationFrame(loop);
}
// 页面加载完成后立即自动播放 (不依赖点击)
window.addEventListener('DOMContentLoaded', init);
</script>
</body>
</html>
积分规则:每轮对话扣10分
等待动画代码生成...
