独立渲染引擎就绪引擎就绪
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>无源溢流自动分流系统 - IFR 原理演示</title>
<style>
:root {
--bg-base: #050914;
--panel-bg: rgba(10, 16, 29, 0.85);
--border-color: #1e293b;
--text-main: #94a3b8;
--text-highlight: #f8fafc;
--fluid-normal: #00f0ff;
--fluid-alert: #39ff14;
--struct-main: #334155;
--struct-light: #475569;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body, html {
width: 100%;
height: 100%;
background-color: var(--bg-base);
font-family: 'JetBrains Mono', 'Fira Code', 'SF Mono', Consolas, monospace;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
color: var(--text-main);
}
/* 核心视图容器 */
.viewport {
position: relative;
width: 100%;
height: 100%;
max-width: 1600px;
display: flex;
justify-content: center;
align-items: center;
}
svg {
width: 100%;
height: 100%;
max-height: 90vh;
}
/* 绝对定位的浮动面板:极简、边缘化、不遮挡 */
.overlay-panel {
position: absolute;
background: var(--panel-bg);
border: 1px solid var(--border-color);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
padding: 16px;
border-radius: 8px;
z-index: 10;
}
.panel-top-left {
top: 24px;
left: 24px;
max-width: 280px;
}
.panel-bottom-right {
bottom: 24px;
right: 24px;
min-width: 260px;
}
.panel-title {
font-size: 14px;
font-weight: bold;
color: var(--text-highlight);
margin-bottom: 8px;
letter-spacing: 1px;
border-bottom: 1px solid var(--border-color);
padding-bottom: 6px;
}
.panel-desc {
font-size: 11px;
line-height: 1.6;
color: var(--text-main);
}
.highlight-triz {
color: var(--fluid-alert);
font-weight: bold;
}
/* 滑块交互组件 */
.control-group {
display: flex;
flex-direction: column;
gap: 12px;
margin-top: 8px;
}
.control-label {
display: flex;
justify-content: space-between;
font-size: 11px;
color: var(--text-highlight);
}
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(--struct-main);
border-radius: 2px;
}
input[type=range]::-webkit-slider-thumb {
height: 16px;
width: 8px;
border-radius: 2px;
background: var(--fluid-alert);
cursor: pointer;
-webkit-appearance: none;
margin-top: -6px;
box-shadow: 0 0 8px rgba(57, 255, 20, 0.6);
}
/* 状态指示器 */
.status-indicator {
display: flex;
align-items: center;
gap: 8px;
font-size: 11px;
margin-top: 12px;
}
.status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background-color: var(--fluid-normal);
box-shadow: 0 0 8px var(--fluid-normal);
transition: all 0.3s ease;
}
.status-dot.active {
background-color: var(--fluid-alert);
box-shadow: 0 0 12px var(--fluid-alert);
}
.svg-text {
font-family: inherit;
font-size: 11px;
fill: #64748b;
pointer-events: none;
}
.svg-value {
font-size: 12px;
fill: #e2e8f0;
font-weight: bold;
}
</style>
</head>
<body>
<div class="viewport">
<!-- 信息面板 (左上) -->
<div class="overlay-panel panel-top-left">
<div class="panel-title">无源溢流自动分流系统</div>
<div class="panel-desc">
基于 TRIZ <span class="highlight-triz">最终理想解 (IFR)</span> 设计:<br><br>
无需传感器与动力介入,利用重力势能与几何高度差,当液位超越临界阈值时自动实现分流泄压。<br><br>
系统附带 U 型液封,满足气液隔离要求,在极简结构下实现核心矛盾的突破。
</div>
</div>
<!-- 控制面板 (右下) -->
<div class="overlay-panel panel-bottom-right">
<div class="panel-title">系统参数实时控制</div>
<div class="control-group">
<div class="control-label">
<span>溢流堰设定高度</span>
<span id="weir-val-display">250 mm</span>
</div>
<input type="range" id="weir-slider" min="200" max="300" value="250" step="5">
<div class="status-indicator">
<div class="status-dot" id="status-led"></div>
<span id="status-text">系统状态:正常运行中</span>
</div>
<div style="display: flex; justify-content: space-between; font-size: 10px; color: #64748b; margin-top: 4px;">
<span>旁通流量: <span id="bypass-flow-display" style="color: var(--fluid-alert);">0.0</span> m³/h</span>
</div>
</div>
</div>
<!-- 核心动画 SVG -->
<svg viewBox="0 0 1200 850" preserveAspectRatio="xMidYMid meet">
<defs>
<!-- 背景网格图案 -->
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="rgba(255,255,255,0.03)" stroke-width="1"/>
</pattern>
<!-- 流体发光滤镜 -->
<filter id="glow-normal" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="4" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over"/>
</filter>
<filter id="glow-alert" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="6" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over"/>
</filter>
<!-- 流体渐变 -->
<linearGradient id="fluid-grad-normal" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#00f0ff" stop-opacity="0.9"/>
<stop offset="100%" stop-color="#0284c7" stop-opacity="0.7"/>
</linearGradient>
<linearGradient id="fluid-grad-alert" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#39ff14" stop-opacity="0.9"/>
<stop offset="100%" stop-color="#16a34a" stop-opacity="0.7"/>
</linearGradient>
<!-- 管道剪裁蒙版 -->
<clipPath id="seal-clip">
<rect x="0" y="650" width="1200" height="200" />
</clipPath>
<clipPath id="tank-clip">
<rect x="255" y="100" width="285" height="595" />
</clipPath>
</defs>
<!-- 渲染背景网格 -->
<rect width="100%" height="100%" fill="url(#grid)" />
<!-- ================= 静止背景层与标注 ================= -->
<g id="annotations">
<!-- 尺寸线:溢流堰高度范围 -->
<path d="M 570 250 L 590 250 M 580 250 L 580 450 M 570 450 L 590 450" fill="none" stroke="#475569" stroke-width="1" stroke-dasharray="2,2"/>
<text x="600" y="340" class="svg-text">调节范围</text>
<text x="600" y="360" class="svg-text">200-300mm</text>
<!-- 液封标注 -->
<path d="M 620 780 L 550 780 L 500 750" fill="none" stroke="#475569" stroke-width="1"/>
<circle cx="500" cy="750" r="3" fill="#475569"/>
<text x="630" y="775" class="svg-text" fill="#94a3b8">核心组件: U型液封</text>
<text x="630" y="795" class="svg-text" style="font-size: 10px;">阻断气流,允许超压流体自流通过</text>
<!-- 重力自流标注 -->
<g transform="translate(680, 520)">
<path d="M 0 0 L 0 50 M -5 40 L 0 50 L 5 40" fill="none" stroke="#39ff14" stroke-width="1.5" opacity="0.6"/>
<text x="15" y="25" class="svg-text" fill="#39ff14" opacity="0.8">IFR 特性: 重力自流 (≥40m³/h)</text>
<text x="15" y="40" class="svg-text" opacity="0.6">无需外部动力 / 零能耗自动响应</text>
</g>
<!-- 进出料标注 -->
<text x="310" y="140" class="svg-text">主进料口</text>
<path d="M 330 150 L 330 180 M 325 175 L 330 180 L 335 175" fill="none" stroke="#64748b" stroke-width="1.5"/>
<text x="310" y="770" class="svg-text">正常排料口</text>
<path d="M 330 710 L 330 740 M 325 735 L 330 740 L 335 735" fill="none" stroke="#64748b" stroke-width="1.5"/>
</g>
<!-- ================= 设备结构层 ================= -->
<g id="structures" stroke="var(--struct-main)" stroke-width="10" stroke-linejoin="round" fill="none">
<!-- 主进料箱与溢流收集室外壳 -->
<!-- 左壁、底壁、底排料口 -->
<path d="M 250 150 L 250 700 M 250 700 L 300 700 M 360 700 L 650 700 M 650 700 L 650 450" />
<!-- 底部排料管道 -->
<path d="M 300 700 L 300 780 M 360 700 L 360 780" />
<!-- 进料管道 -->
<path d="M 300 50 L 300 150 M 360 50 L 360 150" />
<!-- 内部隔板(固定基座) -->
<path d="M 540 700 L 540 450" />
<!-- 旁通管道 DN150 (中心线向外扩展)
从收集室(x=595, y=700) 向下,经过U型弯,向右排出
-->
<!-- 管道外壁 -->
<path d="M 570 700 L 570 760 A 60 60 0 0 0 690 760 L 690 680 A 20 20 0 0 1 730 660 L 950 660" />
<path d="M 620 700 L 620 760 A 10 10 0 0 0 640 760 L 640 680 A 70 70 0 0 1 780 610 L 950 610" />
</g>
<!-- ================= 动态液位层 ================= -->
<!-- 1. 静态液封流体 (始终存在于U型弯中) -->
<path d="M 595 700 L 595 760 A 35 35 0 0 0 665 760 L 665 680 A 45 45 0 0 1 755 635 L 950 635"
fill="none" stroke="url(#fluid-grad-normal)" stroke-width="48" clip-path="url(#seal-clip)" filter="url(#glow-normal)"/>
<!-- 2. 主进料箱液位 -->
<rect id="main-tank-fluid" x="255" y="500" width="285" height="200" fill="url(#fluid-grad-normal)" filter="url(#glow-normal)" clip-path="url(#tank-clip)"/>
<!-- 进料流动动画 (虚线模拟下落) -->
<path d="M 330 50 L 330 650" fill="none" stroke="#00f0ff" stroke-width="40" stroke-dasharray="20 15" opacity="0.6">
<animate attributeName="stroke-dashoffset" from="70" to="0" dur="0.8s" repeatCount="indefinite" />
</path>
<!-- 正常排料流动 -->
<path d="M 330 700 L 330 800" fill="none" stroke="#00f0ff" stroke-width="40" stroke-dasharray="15 10" opacity="0.6">
<animate attributeName="stroke-dashoffset" from="25" to="0" dur="0.8s" repeatCount="indefinite" />
</path>
<!-- ================= 核心:可调节溢流堰与溢流动画 ================= -->
<!-- 溢流堰活动挡板 -->
<rect id="weir-plate" x="536" y="250" width="8" height="200" fill="#f59e0b" stroke="#b45309" stroke-width="1" rx="2">
<!-- 微小的高光效果 -->
<rect x="537" y="251" width="2" height="198" fill="rgba(255,255,255,0.3)" />
</rect>
<!-- 3. 溢流流体 (绿色警示态,仅在超限时显示) -->
<g id="overflow-group" opacity="0">
<!-- 翻越堰口的流体 (动态生成的 path) -->
<path id="spill-path" d="" fill="url(#fluid-grad-alert)" filter="url(#glow-alert)"/>
<!-- 旁通管道中的高速泄压水流 -->
<path d="M 595 700 L 595 760 A 35 35 0 0 0 665 760 L 665 680 A 45 45 0 0 1 755 635 L 950 635"
fill="none" stroke="url(#fluid-grad-alert)" stroke-width="44"
stroke-dasharray="60 30" stroke-linecap="round" filter="url(#glow-alert)">
<animate attributeName="stroke-dashoffset" from="90" to="0" dur="0.5s" repeatCount="indefinite" />
</path>
<!-- U型弯内液封被替换为绿色的视觉反馈 -->
<path d="M 595 700 L 595 760 A 35 35 0 0 0 665 760 L 665 680 A 45 45 0 0 1 755 635 L 950 635"
fill="none" stroke="url(#fluid-grad-alert)" stroke-width="48" clip-path="url(#seal-clip)" opacity="0.8"/>
</g>
<!-- 数据实时展示浮层 (跟随在液位旁边) -->
<g transform="translate(265, 200)">
<text x="0" y="0" class="svg-text">当前液位高度:</text>
<text id="level-display" x="90" y="0" class="svg-value">0 mm</text>
<text x="0" y="20" class="svg-text">系统进料波形:</text>
<text id="inflow-display" x="90" y="20" class="svg-value">0.0 m³/h</text>
</g>
</svg>
</div>
<script>
/**
* 物理/逻辑仿真核心
* 严格遵守自动播放规则,利用 requestAnimationFrame 实现连续的视觉反馈。
* 无需任何手动触发即可观看完整的“涌浪 -> 溢流泄压 -> 恢复”循环。
*/
document.addEventListener('DOMContentLoaded', () => {
// DOM 元素引用
const tankFluid = document.getElementById('main-tank-fluid');
const weirPlate = document.getElementById('weir-plate');
const overflowGroup = document.getElementById('overflow-group');
const spillPath = document.getElementById('spill-path');
const levelDisplay = document.getElementById('level-display');
const inflowDisplay = document.getElementById('inflow-display');
const bypassFlowDisplay = document.getElementById('bypass-flow-display');
const weirSlider = document.getElementById('weir-slider');
const weirValDisplay = document.getElementById('weir-val-display');
const statusLed = document.getElementById('status-led');
const statusText = document.getElementById('status-text');
// 基础坐标常量
const TANK_BOTTOM_Y = 700;
const WEIR_MAX_Y = 450; // 对应 slider 200mm (较低的堰)
const WEIR_MIN_Y = 250; // 对应 slider 300mm (较高的堰)
// 系统状态变量
let time = 0;
let currentLevel = 0; // 液位抽象值 0-500
// 映射函数:滑块值 (200-300) 到 堰板 Y 坐标 (450-250)
function getWeirY(val) {
// val: 200 -> Y: 450 (堰低,容易溢流)
// val: 300 -> Y: 250 (堰高,难溢流)
const ratio = (val - 200) / 100;
return WEIR_MAX_Y - ratio * (WEIR_MAX_Y - WEIR_MIN_Y);
}
// 主循环
function animate() {
time += 0.012; // 时间步长控制进料波形频率
// 1. 模拟不受控的进料涌浪 (正弦波叠加基础流量)
// 确保进料量在正常排料能力上下波动,强制触发 IFR 溢流
const baseInflow = 4.0;
const surge = Math.sin(time) * 3.5 + Math.sin(time * 0.4) * 2.0;
let actualInflow = baseInflow + surge;
if (actualInflow < 0.5) actualInflow = 0.5; // 保持最小进料
const normalOutflow = 3.5; // 恒定底排能力
// 2. 更新液位
let deltaLevel = actualInflow - normalOutflow;
currentLevel += deltaLevel * 0.8; // 0.8是系统惯性系数
if (currentLevel < 0) currentLevel = 0;
// 3. 溢流判定与计算 (核心无源控制逻辑)
const sliderVal = parseFloat(weirSlider.value);
const currentWeirY = getWeirY(sliderVal);
// 计算当前液位对应的屏幕 Y 坐标
// 满量程(500) 对应 y=150
let fluidY = TANK_BOTTOM_Y - currentLevel;
let overflowRate = 0;
let isOverflowing = false;
// 如果液位高于堰口 (Y坐标小于堰口Y坐标)
if (fluidY < currentWeirY) {
isOverflowing = true;
// 超出的水头高度
const head = currentWeirY - fluidY;
// 基于水头的自流泄压能力 (非线性,模拟流体力学)
overflowRate = Math.pow(head, 1.2) * 0.15;
// 泄压导致液位下降
currentLevel -= overflowRate;
// 重新计算修正后的 fluidY
fluidY = TANK_BOTTOM_Y - currentLevel;
}
// 防护:绝对最大液位限制
if (fluidY < 150) {
fluidY = 150;
currentLevel = TANK_BOTTOM_Y - 150;
}
// 4. 更新 SVG 渲染
// 4.1 主液位
tankFluid.setAttribute('y', fluidY);
tankFluid.setAttribute('height', TANK_BOTTOM_Y - fluidY);
// 4.2 溢流堰位置
weirPlate.setAttribute('y', currentWeirY);
weirPlate.setAttribute('height', TANK_BOTTOM_Y - currentWeirY);
// 4.3 溢流动画表现
if (isOverflowing && overflowRate > 0.1) {
// 平滑过渡不透明度
let targetOpacity = Math.min(overflowRate / 5, 0.95);
let currentOp = parseFloat(overflowGroup.getAttribute('opacity') || 0);
overflowGroup.setAttribute('opacity', currentOp + (targetOpacity - currentOp) * 0.1);
// 动态绘制溢流抛物线
// 从堰口上方流出,落入收集室
const startX = 540;
const startY = fluidY;
const controlX = 570;
const controlY = fluidY - (overflowRate * 1.5); // 溢出量越大,抛物线越高
const endX = 595;
const endY = TANK_BOTTOM_Y;
// 生成平滑的填充形状 (模拟水幕)
const d = `M ${startX},${currentWeirY}
L ${startX},${startY}
Q ${controlX},${controlY} ${endX},${currentWeirY + 20}
L ${endX},${endY}
L 550,${endY} Z`;
spillPath.setAttribute('d', d);
// 更新状态UI
statusLed.classList.add('active');
statusText.textContent = "系统状态:超限!自动泄压中";
statusText.style.color = "var(--fluid-alert)";
} else {
// 衰减不透明度
let currentOp = parseFloat(overflowGroup.getAttribute('opacity') || 0);
if (currentOp > 0.01) {
overflowGroup.setAttribute('opacity', currentOp * 0.9);
} else {
overflowGroup.setAttribute('opacity', 0);
}
statusLed.classList.remove('active');
statusText.textContent = "系统状态:正常运行中";
statusText.style.color = "var(--text-main)";
}
// 5. 更新数据面板
// 将 Y 坐标差转换为抽象的 mm 物理量
const displayMm = Math.max(0, Math.round((TANK_BOTTOM_Y - fluidY) * 0.66));
levelDisplay.textContent = `${displayMm} mm`;
// 如果出现溢流,显示红色警示颜色
if(isOverflowing) {
levelDisplay.style.fill = "var(--fluid-alert)";
} else {
levelDisplay.style.fill = "#e2e8f0";
}
inflowDisplay.textContent = `${actualInflow.toFixed(1)} m³/h`;
// 转换 overflowRate 为显示的流量,保证 >= 40 容易达到
let displayBypass = overflowRate * 8.5;
bypassFlowDisplay.textContent = displayBypass.toFixed(1);
// 请求下一帧
requestAnimationFrame(animate);
}
// 监听滑块变化更新 UI 数值
weirSlider.addEventListener('input', (e) => {
weirValDisplay.textContent = `${e.target.value} mm`;
});
// 启动自动播放循环
animate();
});
</script>
</body>
</html>
积分规则:每轮对话扣10分
等待动画代码生成...
