独立渲染引擎就绪引擎就绪
<!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>
<style>
:root {
--bg-color: #050508;
--panel-bg: rgba(15, 20, 30, 0.75);
--panel-border: rgba(6, 182, 212, 0.3);
--text-main: #e2e8f0;
--text-muted: #94a3b8;
--accent-cyan: #06b6d4;
--accent-green: #10b981;
--accent-yellow: #f59e0b;
--accent-red: #ef4444;
--mesh-color: #475569;
--fluid-dirty: rgba(245, 158, 11, 0.4);
--fluid-clean: rgba(16, 185, 129, 0.4);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background-color: var(--bg-color);
color: var(--text-main);
font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
overflow: hidden;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-image:
linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px),
linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
background-size: 40px 40px;
}
/* 绝对定位的信息面板,严格控制尺寸和位置,避免遮挡 */
.info-panel {
position: absolute;
top: 24px;
left: 24px;
width: 280px;
background: var(--panel-bg);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid var(--panel-border);
border-radius: 8px;
padding: 16px;
z-index: 10;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}
.info-panel h1 {
font-size: 14px;
font-weight: 600;
color: var(--accent-cyan);
margin-bottom: 12px;
letter-spacing: 1px;
display: flex;
align-items: center;
gap: 8px;
}
.info-panel h1::before {
content: '';
display: block;
width: 6px;
height: 6px;
background-color: var(--accent-cyan);
border-radius: 50%;
box-shadow: 0 0 8px var(--accent-cyan);
}
.info-list {
list-style: none;
font-size: 11px;
line-height: 1.6;
color: var(--text-muted);
font-family: 'JetBrains Mono', 'Fira Code', Consolas, monospace;
}
.info-list li {
margin-bottom: 8px;
padding-bottom: 8px;
border-bottom: 1px dashed rgba(255, 255, 255, 0.1);
}
.info-list li:last-child {
border-bottom: none;
margin-bottom: 0;
padding-bottom: 0;
}
.highlight {
color: var(--text-main);
font-weight: 500;
}
/* 状态指示器 */
.status-indicator {
position: absolute;
bottom: 24px;
left: 24px;
display: flex;
align-items: center;
gap: 16px;
background: var(--panel-bg);
border: 1px solid rgba(255,255,255,0.1);
padding: 10px 16px;
border-radius: 30px;
font-family: 'JetBrains Mono', monospace;
font-size: 11px;
z-index: 10;
}
.timer-circle {
width: 24px;
height: 24px;
transform: rotate(-90deg);
}
.timer-circle circle {
fill: none;
stroke-width: 3;
}
.timer-bg { stroke: rgba(255,255,255,0.1); }
.timer-progress {
stroke: var(--accent-cyan);
stroke-dasharray: 63; /* 2 * pi * r (approx r=10) */
stroke-dashoffset: 0;
transition: stroke-dashoffset 0.1s linear;
}
.status-text {
color: var(--accent-cyan);
text-transform: uppercase;
letter-spacing: 1px;
min-width: 80px;
}
/* 动画容器 */
.anim-container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
svg {
width: 85%;
max-width: 1200px;
height: auto;
max-height: 85vh;
filter: drop-shadow(0 0 30px rgba(6, 182, 212, 0.05));
}
/* 粒子和流体样式 */
.particle {
fill: #94a3b8;
transition: fill 0.3s ease;
}
.particle.stuck {
fill: var(--accent-red);
filter: drop-shadow(0 0 4px var(--accent-red));
}
.blast-wave {
fill: url(#blast-grad);
opacity: 0;
mix-blend-mode: screen;
transform-origin: bottom center;
}
/* CSS 动画类 */
.pulse-active .blast-wave {
animation: blast-anim 0.5s cubic-bezier(0.1, 0.9, 0.2, 1) forwards;
}
@keyframes blast-anim {
0% { opacity: 0; transform: scaleY(0.1); }
20% { opacity: 0.9; transform: scaleY(1.2); }
80% { opacity: 0.5; transform: scaleY(1); }
100% { opacity: 0; transform: scaleY(0.8); }
}
.nozzle-glow {
fill: var(--accent-cyan);
opacity: 0;
transition: opacity 0.1s;
}
.pulse-active .nozzle-glow {
opacity: 0.8;
filter: blur(4px);
}
.valve-indicator {
fill: #333;
transition: fill 0.1s;
}
.pulse-active .valve-indicator {
fill: var(--accent-cyan);
}
/* 扫描线效果增加科技感 */
.scanline {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, transparent 50%, rgba(0, 0, 0, 0.25) 51%);
background-size: 100% 4px;
pointer-events: none;
z-index: 999;
opacity: 0.3;
}
</style>
</head>
<body>
<div class="scanline"></div>
<!-- 信息面板 (紧凑, 边缘) -->
<div class="info-panel">
<h1>TRIZ 理想解: 逆向脉冲清网</h1>
<ul class="info-list">
<li><span class="highlight">最终理想解 (IFR):</span> 系统利用筛网下部的冗余空间与流体介质,自行清除孔隙堵塞,维持 100% 理想透液率。</li>
<li><span class="highlight">核心机理:</span> 周期性高压脉冲射流 (0.4-0.6MPa) 从底层向上冲击,克服颗粒卡滞力。</li>
<li><span class="highlight">资源利用:</span> 巧用下方死区布置 2mm 雾化排管,极少增加体积复杂度解决“透液”与“糊网”的物理矛盾。</li>
<li><span class="highlight">参数设定:</span> 脉冲周期 10s (动画以 4s 演示), 爆发持续 0.5s。</li>
</ul>
</div>
<!-- 底部状态指示 -->
<div class="status-indicator">
<svg class="timer-circle" viewBox="0 0 24 24">
<circle class="timer-bg" cx="12" cy="12" r="10"></circle>
<circle class="timer-progress" cx="12" cy="12" r="10" id="timerProgress"></circle>
</svg>
<div class="status-text" id="statusText">SYS.NORMAL</div>
<div style="color: var(--text-muted);">P: <span id="pressureVal">0.1</span> MPa</div>
</div>
<!-- 核心动画区 -->
<div class="anim-container">
<svg viewBox="0 0 1000 500" preserveAspectRatio="xMidYMid meet" id="mainSvg">
<defs>
<!-- 渐变与滤镜 -->
<linearGradient id="blast-grad" x1="0" y1="1" x2="0" y2="0">
<stop offset="0%" stop-color="#06b6d4" stop-opacity="0.9"/>
<stop offset="50%" stop-color="#2dd4bf" stop-opacity="0.5"/>
<stop offset="100%" stop-color="#fff" stop-opacity="0"/>
</linearGradient>
<linearGradient id="slurry-grad" x1="0" y1="0" x2="1" y2="0">
<stop offset="0%" stop-color="#f59e0b" stop-opacity="0.8"/>
<stop offset="100%" stop-color="#f59e0b" stop-opacity="0.1"/>
</linearGradient>
<linearGradient id="clean-grad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#10b981" stop-opacity="0.6"/>
<stop offset="100%" stop-color="#10b981" stop-opacity="0.0"/>
</linearGradient>
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="6" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over" />
</filter>
<filter id="mesh-shadow" x="-10%" y="-10%" width="120%" height="120%">
<feDropShadow dx="0" dy="4" stdDeviation="4" flood-color="#000" flood-opacity="0.6"/>
</filter>
<!-- 网格图案 -->
<pattern id="mesh-pattern" width="20" height="20" patternUnits="userSpaceOnUse">
<rect width="20" height="20" fill="none" />
<path d="M 20 0 L 0 0 0 20" fill="none" stroke="#64748b" stroke-width="2" />
<circle cx="0" cy="0" r="1.5" fill="#94a3b8" />
</pattern>
<!-- 喷嘴形状复用 -->
<g id="nozzle">
<rect x="-6" y="0" width="12" height="15" fill="#334155" rx="2"/>
<polygon points="-4,0 4,0 2,-6 -2,-6" fill="#94a3b8" />
<circle cx="0" cy="8" r="3" fill="#1e293b" />
<!-- 喷嘴发光底座 -->
<circle cx="0" cy="-6" r="4" class="nozzle-glow" />
</g>
</defs>
<!-- 背景辅助线 -->
<g stroke="rgba(255,255,255,0.05)" stroke-width="1" stroke-dasharray="4 4">
<line x1="100" y1="100" x2="900" y2="100" />
<line x1="100" y1="400" x2="900" y2="400" />
</g>
<!-- 上层脏浆流体背景区 -->
<path d="M 50 180 Q 250 170 450 185 T 950 180 L 950 240 L 50 240 Z" fill="url(#slurry-grad)" opacity="0.3">
<animate attributeName="d"
values="M 50 180 Q 250 170 450 185 T 950 180 L 950 240 L 50 240 Z;
M 50 185 Q 250 195 450 175 T 950 185 L 950 240 L 50 240 Z;
M 50 180 Q 250 170 450 185 T 950 180 L 950 240 L 50 240 Z"
dur="3s" repeatCount="indefinite"/>
</path>
<!-- 下层透液流体背景区 -->
<rect x="150" y="260" width="700" height="150" fill="url(#clean-grad)" opacity="0.4" />
<!-- 透液波纹动画 -->
<g opacity="0.2" stroke="#10b981" stroke-width="2" fill="none">
<path d="M 200 300 Q 220 320 200 340"><animate attributeName="stroke-dashoffset" values="40;0" dur="1s" repeatCount="indefinite" stroke-dasharray="40"/></path>
<path d="M 500 280 Q 520 310 500 350"><animate attributeName="stroke-dashoffset" values="50;0" dur="1.2s" repeatCount="indefinite" stroke-dasharray="50"/></path>
<path d="M 800 320 Q 820 340 800 360"><animate attributeName="stroke-dashoffset" values="30;0" dur="0.8s" repeatCount="indefinite" stroke-dasharray="30"/></path>
</g>
<!-- 中间核心筛网结构 -->
<g transform="translate(100, 240)" filter="url(#mesh-shadow)">
<!-- 筛网框架 -->
<rect x="0" y="0" width="800" height="20" fill="#1e293b" rx="4" stroke="#475569" stroke-width="2"/>
<!-- 筛网网孔面 -->
<rect x="10" y="0" width="780" height="8" fill="url(#mesh-pattern)" />
</g>
<!-- 脉冲装置与管道 (筛网下方) -->
<g transform="translate(100, 380)">
<!-- 进气/水主管道 -->
<path d="M -50 0 L 820 0" stroke="#334155" stroke-width="16" stroke-linecap="round"/>
<path d="M -50 0 L 820 0" stroke="#64748b" stroke-width="6" stroke-linecap="round"/>
<!-- 电磁脉冲阀 (左侧) -->
<rect x="-20" y="-15" width="30" height="30" fill="#1e293b" rx="4" stroke="#475569" stroke-width="2"/>
<circle cx="-5" cy="0" r="8" class="valve-indicator" />
<text x="-5" y="4" font-size="10" font-family="monospace" fill="#050508" text-anchor="middle" font-weight="bold">V</text>
<!-- 喷嘴阵列与气流脉冲爆发区 (使用循环生成) -->
<g transform="translate(100, -8)"><use href="#nozzle" /></g>
<g transform="translate(250, -8)"><use href="#nozzle" /></g>
<g transform="translate(400, -8)"><use href="#nozzle" /></g>
<g transform="translate(550, -8)"><use href="#nozzle" /></g>
<g transform="translate(700, -8)"><use href="#nozzle" /></g>
</g>
<!-- 脉冲爆发流场 (隐藏,在脉冲时显示) -->
<g id="pulseLayer" transform="translate(100, 360)">
<!-- 对应喷嘴位置的向上射流 -->
<path d="M 80 0 L 120 0 L 150 -130 L 50 -130 Z" class="blast-wave" />
<path d="M 230 0 L 270 0 L 300 -130 L 200 -130 Z" class="blast-wave" />
<path d="M 380 0 L 420 0 L 450 -130 L 350 -130 Z" class="blast-wave" />
<path d="M 530 0 L 570 0 L 600 -130 L 500 -130 Z" class="blast-wave" />
<path d="M 680 0 L 720 0 L 750 -130 L 650 -130 Z" class="blast-wave" />
</g>
<!-- 动态粒子层,JS将在此注入粒子 -->
<g id="particlesLayer"></g>
<!-- UI 标尺与参数标识,增强工程感 -->
<g font-family="monospace" font-size="10" fill="#64748b" opacity="0.8">
<text x="50" y="245">SLURRY IN</text>
<text x="920" y="245">SOLIDS OUT</text>
<line x1="90" y1="250" x2="50" y2="250" stroke="#64748b" stroke-width="1" marker-end="url(#arrow)"/>
<line x1="910" y1="250" x2="950" y2="250" stroke="#64748b" stroke-width="1" marker-end="url(#arrow)"/>
<text x="50" y="420">PULSE MEDIA</text>
<path d="M 50 405 L 80 405 L 80 380" stroke="#06b6d4" stroke-width="1" fill="none" opacity="0.5"/>
<text x="920" y="340">FILTRATE</text>
<line x1="900" y1="337" x2="950" y2="337" stroke="#10b981" stroke-width="1" stroke-dasharray="2 2"/>
</g>
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="4" markerHeight="4" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z" fill="#64748b" />
</marker>
</defs>
</svg>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const svg = document.getElementById('mainSvg');
const particlesLayer = document.getElementById('particlesLayer');
const pulseLayer = document.getElementById('pulseLayer');
const timerProgress = document.getElementById('timerProgress');
const statusText = document.getElementById('statusText');
const pressureVal = document.getElementById('pressureVal');
// 系统参数设定
const CYCLE_DURATION = 4000; // 总周期 4秒 (加速演示)
const PULSE_DURATION = 500; // 脉冲爆发 0.5秒
const MAX_PRESSURE = 0.6;
// 粒子状态存储
let particles = [];
let isPulsing = false;
let cycleStartTime = performance.now();
// 生成随机数
const random = (min, max) => Math.random() * (max - min) + min;
// 创建粒子
function spawnParticle() {
// 限制最大粒子数量以保证性能
if (particles.length > 80) return;
const isStuckType = Math.random() > 0.6; // 40% 的概率产生会糊网的大颗粒
const r = isStuckType ? random(4, 7) : random(1.5, 3);
const startY = random(180, 220);
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
circle.setAttribute("cx", 50);
circle.setAttribute("cy", startY);
circle.setAttribute("r", r);
circle.setAttribute("class", "particle");
particlesLayer.appendChild(circle);
const particleData = {
el: circle,
x: 50,
y: startY,
vx: random(1.5, 3), // 水平流速
vy: 0,
r: r,
isStuckType: isStuckType,
state: 'flowing' // flowing, stuck, blasted, falling
};
particles.push(particleData);
}
// 动画主循环
function animateSystem(timestamp) {
// 1. 周期时间计算
let elapsed = timestamp - cycleStartTime;
if (elapsed >= CYCLE_DURATION) {
cycleStartTime = timestamp;
elapsed = 0;
triggerPulse();
}
// UI 更新: 倒计时环
const progressRatio = elapsed / CYCLE_DURATION;
const dashoffset = 63 * (1 - progressRatio);
timerProgress.style.strokeDashoffset = isPulsing ? 0 : dashoffset;
// 压力表模拟
if (isPulsing) {
pressureVal.innerText = (0.4 + Math.random()*0.2).toFixed(2);
} else {
// 缓慢充能
const p = 0.1 + (0.3 * progressRatio);
pressureVal.innerText = p.toFixed(2);
}
// 2. 持续生成粒子
if (!isPulsing && Math.random() > 0.4) {
spawnParticle();
}
// 3. 更新粒子物理状态
const meshY = 236; // 筛网表面高度
for (let i = particles.length - 1; i >= 0; i--) {
let p = particles[i];
if (p.state === 'flowing') {
// 在流体中向右运动,同时受到重力缓慢下沉
p.x += p.vx;
p.y += 0.3; // 重力下沉倾向
// 碰到筛网
if (p.y + p.r >= meshY) {
if (p.isStuckType) {
// 大颗粒糊网
p.y = meshY - p.r;
p.state = 'stuck';
p.el.classList.add('stuck');
} else {
// 小颗粒透网
p.state = 'falling';
p.vy = random(1, 3);
}
}
// 正常流出屏幕右侧
if (p.x > 950) p.state = 'dead';
} else if (p.state === 'stuck') {
// 糊网颗粒,随筛网微小震动缓慢右移 (模拟实际振动筛)
p.x += 0.2;
if (p.x > 900) p.state = 'dead'; // 最终排渣
} else if (p.state === 'falling') {
// 透网后加速下落
p.y += p.vy;
p.vy += 0.1; // 重力加速度
p.el.style.fill = '#10b981'; // 变色表示干净液体
p.el.style.opacity = '0.5';
if (p.y > 450) p.state = 'dead';
} else if (p.state === 'blasted') {
// 被脉冲吹起
p.x += p.vx;
p.y += p.vy;
p.vy += 0.2; // 重新受重力
p.el.classList.remove('stuck');
// 重新落回流体层变为 flowing,或者直接吹出
if (p.y >= meshY - p.r && p.vy > 0) {
p.state = 'flowing';
p.y = meshY - p.r - 2; // 防止穿模
}
}
// 应用位置
if (p.state !== 'dead') {
p.el.setAttribute("cx", p.x);
p.el.setAttribute("cy", p.y);
} else {
// 移除死亡粒子
p.el.remove();
particles.splice(i, 1);
}
}
requestAnimationFrame(animateSystem);
}
// 触发反向脉冲
function triggerPulse() {
if (isPulsing) return;
isPulsing = true;
// UI 状态
statusText.innerText = "SYS.PULSE";
statusText.style.color = "var(--accent-red)";
timerProgress.style.stroke = "var(--accent-red)";
svg.classList.add('pulse-active');
// 物理影响:吹飞卡住的颗粒
particles.forEach(p => {
if (p.state === 'stuck') {
// 赋予向上的爆炸初速度和随机水平偏移
p.state = 'blasted';
p.vy = random(-8, -12);
p.vx = p.vx + random(0, 2);
}
});
// 结束脉冲
setTimeout(() => {
isPulsing = false;
statusText.innerText = "SYS.NORMAL";
statusText.style.color = "var(--accent-cyan)";
timerProgress.style.stroke = "var(--accent-cyan)";
svg.classList.remove('pulse-active');
}, PULSE_DURATION);
}
// 启动引擎
requestAnimationFrame(animateSystem);
});
</script>
</body>
</html>
积分规则:每轮对话扣10分
等待动画代码生成...
