独立渲染引擎就绪引擎就绪
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>被动分流器均布原理 (TRIZ 理想解)</title>
<link href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@400;600;700&family=Noto+Sans+SC:wght@300;500;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-color: #060913;
--grid-color: #121A2F;
--accent-cyan: #00F3FF;
--accent-magenta: #FF2A6D;
--text-main: #D1F2EB;
--text-muted: #5B7586;
--panel-bg: rgba(10, 15, 30, 0.7);
}
body, html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
background-color: var(--bg-color);
color: var(--text-main);
font-family: 'Noto Sans SC', sans-serif;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
}
/* 背景网格与纹理 */
.bg-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
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;
opacity: 0.4;
z-index: 0;
pointer-events: none;
}
.bg-glow {
position: absolute;
width: 800px;
height: 800px;
background: radial-gradient(circle, rgba(0, 243, 255, 0.05) 0%, transparent 60%);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 0;
pointer-events: none;
}
/* 主容器 */
.dashboard {
position: relative;
width: 100%;
max-width: 1400px;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
z-index: 1;
}
/* SVG 动画区域 */
svg {
width: 100%;
height: 100%;
max-height: 900px;
filter: drop-shadow(0 0 20px rgba(0, 243, 255, 0.1));
}
/* 浮动控制面板 */
.control-panel {
position: absolute;
bottom: 40px;
left: 40px;
background: var(--panel-bg);
border: 1px solid rgba(0, 243, 255, 0.2);
border-radius: 8px;
padding: 20px;
width: 280px;
backdrop-filter: blur(10px);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
font-family: 'Chakra Petch', 'Noto Sans SC', sans-serif;
z-index: 10;
}
.panel-title {
font-size: 14px;
font-weight: 700;
color: var(--accent-magenta);
margin-bottom: 15px;
text-transform: uppercase;
letter-spacing: 1px;
display: flex;
align-items: center;
gap: 8px;
}
.panel-title::before {
content: '';
display: block;
width: 8px;
height: 8px;
background: var(--accent-magenta);
box-shadow: 0 0 10px var(--accent-magenta);
}
.control-group {
margin-bottom: 15px;
}
.control-label {
font-size: 12px;
color: var(--text-muted);
margin-bottom: 8px;
display: flex;
justify-content: space-between;
}
.val-display {
color: var(--accent-cyan);
font-weight: 600;
}
/* 自定义滑块 */
input[type=range] {
-webkit-appearance: none;
width: 100%;
background: transparent;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
height: 14px;
width: 14px;
border-radius: 50%;
background: var(--accent-cyan);
cursor: pointer;
margin-top: -5px;
box-shadow: 0 0 10px var(--accent-cyan);
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 4px;
cursor: pointer;
background: rgba(255, 255, 255, 0.1);
border-radius: 2px;
}
/* 标题区域 */
.header-title {
position: absolute;
top: 40px;
left: 40px;
z-index: 10;
pointer-events: none;
}
.header-title h1 {
margin: 0;
font-size: 24px;
font-weight: 700;
color: #fff;
letter-spacing: 2px;
font-family: 'Chakra Petch', 'Noto Sans SC', sans-serif;
text-shadow: 0 0 15px rgba(0, 243, 255, 0.5);
}
.header-title p {
margin: 5px 0 0 0;
font-size: 12px;
color: var(--text-muted);
letter-spacing: 1px;
}
/* SVG 样式 */
.svg-text {
font-family: 'Chakra Petch', 'Noto Sans SC', sans-serif;
font-size: 12px;
fill: var(--text-muted);
letter-spacing: 1px;
}
.svg-text-highlight {
fill: var(--accent-magenta);
font-weight: 700;
}
.svg-text-cyan {
fill: var(--accent-cyan);
}
.svg-line-guide {
stroke: var(--text-muted);
stroke-width: 1;
stroke-dasharray: 2, 2;
}
.vibrating-screen {
animation: vibrate 0.1s linear infinite alternate;
}
@keyframes vibrate {
0% { transform: translateY(0); }
100% { transform: translateY(1.5px); }
}
@keyframes pulse-glow {
0% { filter: drop-shadow(0 0 5px var(--accent-magenta)); }
100% { filter: drop-shadow(0 0 15px var(--accent-magenta)); }
}
.weir-plate {
animation: pulse-glow 2s infinite alternate;
}
</style>
</head>
<body>
<div class="bg-layer"></div>
<div class="bg-glow"></div>
<div class="dashboard">
<div class="header-title">
<h1>被动分流均布系统</h1>
<p>TRIZ 最终理想解 (IFR) · 核心原理演示</p>
</div>
<div class="control-panel">
<div class="panel-title">流体边界条件模拟</div>
<div class="control-group">
<div class="control-label">
<span>流体粘度 (Viscosity)</span>
<span class="val-display" id="vis-val">低</span>
</div>
<input type="range" id="viscosity-slider" min="1" max="10" step="0.5" value="2">
<div style="font-size: 10px; color: var(--text-muted); margin-top: 6px; line-height: 1.4;">
* 观察失效边界:粘度升高会导致水平展布受阻,流体集中于中部,体现该方案“适用于低粘度钻井液”的物理约束。
</div>
</div>
</div>
<svg viewBox="0 0 1200 800" preserveAspectRatio="xMidYMid meet">
<defs>
<filter id="glow-cyan" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="3" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over" />
</filter>
<filter id="glow-magenta" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="5" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over" />
</filter>
<linearGradient id="chute-grad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#121A2F" stop-opacity="0.8" />
<stop offset="100%" stop-color="#060913" stop-opacity="0" />
</linearGradient>
</defs>
<!-- 物理结构背景 -->
<g id="infrastructure">
<!-- 进料溜槽 (外壳轮廓) -->
<path d="M 500 50 L 500 200 L 250 280 L 250 650" fill="none" stroke="#1C2A43" stroke-width="2" />
<path d="M 700 50 L 700 200 L 950 280 L 950 650" fill="none" stroke="#1C2A43" stroke-width="2" />
<path d="M 500 50 L 700 50 L 700 200 L 950 280 L 950 650 L 250 650 L 250 280 L 500 200 Z" fill="url(#chute-grad)" opacity="0.3" />
<!-- 整流栅格 -->
<g stroke="#1C2A43" stroke-width="1" stroke-dasharray="4, 4" opacity="0.6">
<line x1="250" y1="320" x2="950" y2="320" />
<line x1="250" y1="340" x2="950" y2="340" />
<line x1="250" y1="360" x2="950" y2="360" />
</g>
<!-- 底部筛面 -->
<g class="vibrating-screen">
<line x1="200" y1="650" x2="1000" y2="650" stroke="#39FF14" stroke-width="4" filter="url(#glow-cyan)" />
<line x1="200" y1="660" x2="1000" y2="660" stroke="#1C2A43" stroke-width="2" />
<!-- 筛孔指示 -->
<path d="M 220 650 L 230 670 M 260 650 L 270 670 M 300 650 L 310 670 M 340 650 L 350 670 M 380 650 L 390 670 M 420 650 L 430 670 M 460 650 L 470 670 M 500 650 L 510 670 M 540 650 L 550 670 M 580 650 L 590 670 M 620 650 L 630 670 M 660 650 L 670 670 M 700 650 L 710 670 M 740 650 L 750 670 M 780 650 L 790 670 M 820 650 L 830 670 M 860 650 L 870 670 M 900 650 L 910 670 M 940 650 L 950 670 M 980 650 L 990 670" stroke="#39FF14" stroke-width="1" opacity="0.3" />
</g>
</g>
<!-- 动态粒子层(通过 JS 填充) -->
<g id="fluid-particles"></g>
<!-- 核心创新件:锯齿堰板 (放置在流体之上以突显切割作用) -->
<g id="weir-system" class="weir-plate">
<!-- 由 JS 动态生成精确的锯齿路径 -->
<path id="weir-path" fill="none" stroke="var(--accent-magenta)" stroke-width="4" stroke-linejoin="miter" filter="url(#glow-magenta)" />
<path id="weir-base" fill="none" stroke="var(--accent-magenta)" stroke-width="2" opacity="0.5" />
</g>
<!-- 注释与引线 (严控位置,不遮挡中心) -->
<g id="annotations">
<!-- 顶部:集中液流 -->
<line x1="550" y1="120" x2="680" y2="80" class="svg-line-guide" />
<circle cx="550" cy="120" r="3" fill="var(--text-muted)" />
<text x="690" y="75" class="svg-text svg-text-cyan">集中入料液流</text>
<text x="690" y="90" class="svg-text" style="font-size:10px;">初始状态:分布极不均匀</text>
<!-- 核心:锯齿堰板 -->
<line x1="850" y1="280" x2="980" y2="240" class="svg-line-guide" stroke="var(--accent-magenta)" />
<circle cx="850" cy="280" r="3" fill="var(--accent-magenta)" />
<text x="990" y="235" class="svg-text svg-text-highlight">IFR: 被动锯齿堰板</text>
<text x="990" y="255" class="svg-text" style="font-size:10px;">利用重力与几何构型切割流体</text>
<text x="990" y="270" class="svg-text" style="font-size:10px;">开孔率: 45%~65% | 齿距: 50mm</text>
<text x="990" y="285" class="svg-text" style="font-size:10px;">零能耗实现宽度方向均匀分配</text>
<!-- 下部:多股细流 -->
<line x1="800" y1="500" x2="980" y2="500" class="svg-line-guide" />
<circle cx="800" cy="500" r="3" fill="var(--text-muted)" />
<text x="990" y="495" class="svg-text svg-text-cyan">多股均匀射流</text>
<text x="990" y="510" class="svg-text" style="font-size:10px;">消除局部过载矛盾</text>
<!-- 底部:筛面 -->
<line x1="280" y1="650" x2="150" y2="600" class="svg-line-guide" />
<circle cx="280" cy="650" r="3" fill="var(--text-muted)" />
<text x="50" y="590" class="svg-text" style="fill:#39FF14">均布作业筛面</text>
</g>
</svg>
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
// 系统参数配置
const config = {
particleCount: 500, // 粒子总数
chuteTop: 50, // 进料高度
weirY: 280, // 堰板基础高度
toothHeight: 30, // 锯齿高度 (250 到 280)
screenY: 650, // 筛面高度
weirStartX: 250, // 堰板左边界
weirEndX: 950, // 堰板右边界
valleyCount: 14 // 谷底(细流)数量
};
// 计算锯齿几何坐标
const width = config.weirEndX - config.weirStartX;
const pitch = width / config.valleyCount;
const valleys = [];
const peaks = [];
let pathD = `M ${config.weirStartX} ${config.weirY}`;
let baseY = config.weirY;
let peakY = config.weirY - config.toothHeight;
for (let i = 0; i < config.valleyCount; i++) {
let peakX = config.weirStartX + i * pitch + pitch / 2;
let valleyX = config.weirStartX + (i + 1) * pitch;
peaks.push(peakX);
valleys.push(valleyX - pitch/2); // 将细流位置对准谷底
pathD += ` L ${peakX} ${peakY} L ${valleyX} ${baseY}`;
}
// 绘制静态锯齿堰板
document.getElementById('weir-path').setAttribute('d', pathD);
document.getElementById('weir-base').setAttribute('d', `M ${config.weirStartX} ${config.weirY} L ${config.weirEndX} ${config.weirY}`);
// 交互控制
const visSlider = document.getElementById('viscosity-slider');
const visDisplay = document.getElementById('vis-val');
let fluidViscosity = parseFloat(visSlider.value);
visSlider.addEventListener('input', (e) => {
fluidViscosity = parseFloat(e.target.value);
if (fluidViscosity < 4) visDisplay.textContent = '低 (理想工作区)';
else if (fluidViscosity < 7) visDisplay.textContent = '中 (展布受限)';
else visDisplay.textContent = '高 (边界失效警告)';
});
// 粒子系统类
const svgns = "http://www.w3.org/2000/svg";
const particleGroup = document.getElementById('fluid-particles');
const particles = [];
class Particle {
constructor() {
this.el = document.createElementNS(svgns, "circle");
this.el.setAttribute("fill", "var(--accent-cyan)");
this.el.setAttribute("filter", "url(#glow-cyan)");
particleGroup.appendChild(this.el);
this.reset(true);
}
reset(initial = false) {
// 集中入料:位于 550 到 650 之间
this.x = 550 + Math.random() * 100;
this.y = initial ? Math.random() * 200 : config.chuteTop;
this.vx = (Math.random() - 0.5) * 1.5;
this.vy = 4 + Math.random() * 3;
this.state = 'falling_in'; // falling_in, spreading, falling_out
this.r = 2 + Math.random() * 2.5;
this.el.setAttribute("r", this.r);
this.el.setAttribute("opacity", 0.8 + Math.random() * 0.2);
}
update() {
// 物理状态机
if (this.state === 'falling_in') {
// 触及堰板液面区域 (蓄水池效果)
if (this.y > config.weirY - config.toothHeight - 10) {
this.state = 'spreading';
// 赋予水平展布速度,受粘度直接制约
const dir = this.x < 600 ? -1 : 1;
// 粘度越大,vx 越小,越难到达两侧
this.vx = dir * (2 + Math.random() * 8) / (fluidViscosity * 0.8);
this.vy = 0.8; // 缓冲区的缓慢垂直下沉
}
}
else if (this.state === 'spreading') {
// 寻找最近的锯齿谷底
let inValley = false;
for (let v of valleys) {
if (Math.abs(this.x - v) < 6) { // 谷底捕获宽度
inValley = true;
this.vx = this.vx * 0.2; // 阻尼
break;
}
}
// 如果到达谷底高度,或被谷底捕获
if (inValley || this.y >= config.weirY - 2) {
this.state = 'falling_out';
this.vx = (Math.random() - 0.5) * 0.5; // 保持细流垂直
this.vy = 5 + Math.random() * 4; // 加速下落
}
// 边界处理:防止溢出溜槽
const leftBound = 500 - ((this.y - 50) / 230) * 250;
const rightBound = 700 + ((this.y - 50) / 230) * 250;
if (this.x < leftBound || this.x > rightBound) {
this.vx *= -1;
}
}
// 运动更新
this.x += this.vx;
this.y += this.vy;
// 到达筛面:产生细微溅射后重置
if (this.y > config.screenY) {
this.reset();
}
// 渲染更新
this.el.setAttribute("cx", this.x);
this.el.setAttribute("cy", this.y);
}
}
// 初始化粒子群
for (let i = 0; i < config.particleCount; i++) {
particles.push(new Particle());
}
// 动画循环 (自动播放,重载即播)
function animate() {
for (let p of particles) {
p.update();
}
requestAnimationFrame(animate);
}
// 启动
requestAnimationFrame(animate);
});
</script>
</body>
</html>
积分规则:每轮对话扣10分
等待动画代码生成...
