独立渲染引擎就绪引擎就绪
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>射流放大器 - 最终理想解原理可视化</title>
<link href="https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap" rel="stylesheet">
<style>
:root {
--bg-color: #050914;
--grid-color: rgba(30, 55, 90, 0.3);
--struct-fill: #111827;
--struct-stroke: #2c426b;
--primary-cyan: #00e5ff;
--secondary-blue: #4da6ff;
--text-color: #8ab4f8;
/* 动态变量,由JS控制 */
--flow-speed: 1.5s;
--glow-intensity: 1;
--entrainment-opacity: 0.8;
--pulse-speed: 1s;
}
* { box-sizing: border-box; }
body {
margin: 0;
padding: 0;
width: 100vw;
height: 100vh;
background-color: var(--bg-color);
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;
font-family: 'Share Tech Mono', 'Courier New', monospace;
color: var(--text-color);
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
}
/* 绝对防遮挡容器,承载所有UI和说明文字,固定在四周边缘 */
.hud-layer {
position: absolute;
inset: 24px;
pointer-events: none; /* 让鼠标穿透,不影响底层交互 */
display: flex;
flex-direction: column;
justify-content: space-between;
z-index: 10;
}
.hud-row {
display: flex;
justify-content: space-between;
align-items: flex-start;
width: 100%;
}
/* 面板基础样式 */
.panel {
background: rgba(5, 9, 20, 0.6);
border: 1px solid rgba(44, 66, 107, 0.8);
padding: 12px 16px;
backdrop-filter: blur(8px);
pointer-events: auto; /* 恢复面板本身的交互 */
position: relative;
font-size: 13px;
max-width: 320px;
line-height: 1.6;
}
/* 科技感边角装饰 */
.panel::before, .panel::after {
content: '';
position: absolute;
width: 6px;
height: 6px;
border-color: var(--primary-cyan);
border-style: solid;
transition: all 0.3s ease;
}
.panel-tl::before { top: -1px; left: -1px; border-width: 2px 0 0 2px; }
.panel-tl::after { bottom: -1px; right: -1px; border-width: 0 2px 2px 0; }
.panel-br::before { bottom: -1px; left: -1px; border-width: 0 0 2px 2px; }
.panel-br::after { top: -1px; right: -1px; border-width: 2px 2px 0 0; }
.title {
color: #fff;
font-size: 14px;
font-weight: bold;
letter-spacing: 1px;
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 8px;
}
.title::before {
content: '';
display: block;
width: 8px;
height: 8px;
background: var(--primary-cyan);
box-shadow: 0 0 8px var(--primary-cyan);
}
.highlight { color: var(--primary-cyan); }
.muted { color: #5c7b99; font-size: 11px; }
/* 交互滑块控制区 */
.controls {
display: flex;
flex-direction: column;
gap: 8px;
width: 240px;
}
.slider-header {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 12px;
}
input[type=range] {
-webkit-appearance: none;
width: 100%;
background: transparent;
margin: 8px 0;
}
input[type=range]:focus { outline: none; }
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 2px;
cursor: pointer;
background: var(--struct-stroke);
}
input[type=range]::-webkit-slider-thumb {
height: 14px;
width: 8px;
border-radius: 0;
background: var(--primary-cyan);
cursor: pointer;
-webkit-appearance: none;
margin-top: -6px;
box-shadow: 0 0 10px calc(2px * var(--glow-intensity)) var(--primary-cyan);
}
/* 动画核心容器 */
.svg-container {
width: 100%;
max-width: 1200px;
height: 100%;
position: absolute;
z-index: 1;
display: flex;
justify-content: center;
align-items: center;
}
svg {
width: 100%;
height: 100%;
max-height: 80vh;
overflow: visible;
}
/* SVG 元素动画样式 */
.flow-primary {
fill: none;
stroke: var(--primary-cyan);
stroke-linecap: round;
stroke-linejoin: round;
stroke-dasharray: 60 40 20 40;
animation: dash-move var(--flow-speed) linear infinite;
filter: drop-shadow(0 0 calc(6px * var(--glow-intensity)) var(--primary-cyan));
opacity: calc(0.3 + 0.7 * var(--glow-intensity));
}
.flow-core {
fill: none;
stroke: #fff;
stroke-width: 1.5;
stroke-linecap: round;
stroke-dasharray: 100 100;
animation: dash-move calc(var(--flow-speed) * 0.8) linear infinite;
opacity: var(--glow-intensity);
}
.flow-secondary {
fill: none;
stroke: var(--secondary-blue);
stroke-width: 1.5;
stroke-linecap: round;
stroke-dasharray: 15 25;
animation: dash-move calc(var(--flow-speed) * 1.5) linear infinite;
opacity: var(--entrainment-opacity);
}
.flow-mixed {
fill: none;
stroke: #66c2ff;
stroke-width: 3;
stroke-linecap: round;
stroke-dasharray: 40 30;
animation: dash-move calc(var(--flow-speed) * 1.2) linear infinite;
opacity: calc(var(--entrainment-opacity) * 0.8 + 0.2);
}
@keyframes dash-move {
from { stroke-dashoffset: 200; }
to { stroke-dashoffset: 0; }
}
.pulse-ring {
transform-origin: 450px 300px;
animation: pulse var(--pulse-speed) ease-out infinite;
}
@keyframes pulse {
0% { transform: scale(0.5); opacity: 0; }
50% { opacity: calc(0.4 * var(--glow-intensity)); }
100% { transform: scale(1.5); opacity: 0; }
}
/* SVG 内引线与文字标注 */
.svg-label-line {
fill: none;
stroke: rgba(138, 180, 248, 0.5);
stroke-width: 1;
stroke-dasharray: 2 2;
}
.svg-label-text {
fill: #8ab4f8;
font-size: 12px;
font-family: 'Share Tech Mono', monospace;
letter-spacing: 1px;
}
.svg-label-highlight {
fill: var(--primary-cyan);
font-weight: bold;
}
</style>
</head>
<body>
<!-- 外围UI层,绝不遮挡中央 -->
<div class="hud-layer">
<!-- 顶栏 -->
<div class="hud-row">
<div class="panel panel-tl">
<div class="title">IFR: 射流放大结构</div>
<div>状态: <span class="highlight">最终理想解 (理想化运作中)</span></div>
<div class="muted" style="margin-top:6px;">
破除物理矛盾:化整为零<br>
消除主通道强制缩口阻力<br>
利用极少资源实现高风量输出
</div>
</div>
<div class="panel panel-br" style="text-align: right; max-width: 200px;">
<div class="highlight">SYS.STATUS: ONLINE</div>
<div class="muted">AERODYNAMIC SIMULATION</div>
<div class="muted">COANDA EFFECT ACTIVE</div>
</div>
</div>
<!-- 底栏 -->
<div class="hud-row" style="align-items: flex-end;">
<div class="panel panel-br" style="max-width: 280px;">
<div style="color:#fff; margin-bottom:4px;">核心运作机理</div>
<div class="muted">
1. 增压气流从 1mm 环形细缝高速挤出<br>
2. 附壁效应使其贴紧 16° 曲面流出<br>
3. 中心形成强负压区 (低压核)<br>
4. 大量卷吸后方静止空气混合喷出
</div>
</div>
<div class="panel panel-br controls">
<div class="slider-header">
<span>系统供气静压 (前端风机)</span>
<span id="pressureValue" class="highlight">85%</span>
</div>
<!-- 交互控件:滑块调节静压,体验边界条件 -->
<input type="range" id="pressureSlider" min="0" max="100" value="85">
<div class="muted" style="display:flex; justify-content:space-between;">
<span>不足(失效)</span>
<span>额定</span>
</div>
</div>
</div>
</div>
<!-- 核心动画层,独占中央最大空间 -->
<div class="svg-container">
<svg viewBox="0 0 1000 600" preserveAspectRatio="xMidYMid meet">
<defs>
<!-- 发光滤镜 -->
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="3" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over" />
</filter>
<filter id="strong-glow" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="8" result="blur1" />
<feGaussianBlur stdDeviation="3" result="blur2" />
<feMerge>
<feMergeNode in="blur1" />
<feMergeNode in="blur2" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<!-- 负压区渐变 -->
<radialGradient id="neg-pressure" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#00e5ff" stop-opacity="0.3" />
<stop offset="70%" stop-color="#00e5ff" stop-opacity="0.05" />
<stop offset="100%" stop-color="#00e5ff" stop-opacity="0" />
</radialGradient>
<!-- 箭头标记 -->
<marker id="arrow-blue" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 1 L 10 5 L 0 9 z" fill="var(--secondary-blue)" opacity="0.8"/>
</marker>
<marker id="arrow-mixed" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="5" markerHeight="5" orient="auto-start-reverse">
<path d="M 0 1 L 10 5 L 0 9 z" fill="#66c2ff" opacity="0.8"/>
</marker>
</defs>
<!-- ================= 背景装饰线 ================= -->
<line x1="100" y1="300" x2="900" y2="300" stroke="rgba(44, 66, 107, 0.4)" stroke-width="1" stroke-dasharray="10 5" />
<circle cx="450" cy="300" r="140" fill="none" stroke="rgba(44, 66, 107, 0.2)" stroke-width="1" />
<circle cx="450" cy="300" r="180" fill="none" stroke="rgba(44, 66, 107, 0.1)" stroke-width="1" stroke-dasharray="4 8" />
<!-- ================= 负压核心可视化 ================= -->
<!-- 静态底色 -->
<ellipse cx="430" cy="300" rx="80" ry="130" fill="url(#neg-pressure)" opacity="0.8"/>
<!-- 脉冲动画环 -->
<ellipse cx="430" cy="300" rx="40" ry="80" fill="none" stroke="var(--primary-cyan)" stroke-width="1" class="pulse-ring" />
<ellipse cx="430" cy="300" rx="60" ry="100" fill="none" stroke="var(--primary-cyan)" stroke-width="0.5" class="pulse-ring" style="animation-delay: -0.5s;" />
<!-- ================= 次级气流 (环境静空气卷吸) 左侧到中心 ================= -->
<g class="entrainment-flows">
<!-- 顶部卷吸 -->
<path d="M 50,150 C 200,150 300,220 400,260 C 450,280 500,280 650,260" class="flow-secondary" marker-end="url(#arrow-blue)" />
<path d="M 100,200 C 250,200 320,250 400,275 C 450,290 550,290 700,270" class="flow-secondary" marker-end="url(#arrow-blue)" style="animation-delay: -0.3s;" />
<!-- 中心卷吸 -->
<path d="M 50,300 L 750,300" class="flow-secondary" marker-end="url(#arrow-blue)" style="stroke-width: 2; animation-delay: -0.7s;" />
<!-- 底部卷吸 -->
<path d="M 100,400 C 250,400 320,350 400,325 C 450,310 550,310 700,330" class="flow-secondary" marker-end="url(#arrow-blue)" style="animation-delay: -0.1s;" />
<path d="M 50,450 C 200,450 300,380 400,340 C 450,320 500,320 650,340" class="flow-secondary" marker-end="url(#arrow-blue)" style="animation-delay: -0.5s;" />
</g>
<!-- ================= 核心结构剖面 (环形放大器) ================= -->
<g id="structure-top">
<!-- 供气腔体 (外壳) -->
<path d="M 220,100 L 370,100 C 390,100 410,140 410,210 L 406,210 C 406,145 385,115 220,115 Z" fill="var(--struct-fill)" stroke="var(--struct-stroke)" stroke-width="1.5" />
<!-- 内部导流曲面 (康达效应面) 16度偏转 -->
<path d="M 406,214 C 426,214 470,155 600,150 L 600,140 C 460,145 410,208 396,208 L 410,208 Z" fill="#1e2a40" stroke="#48628f" stroke-width="1.5" />
<!-- 供气管截面示意 -->
<rect x="200" y="100" width="20" height="15" fill="var(--struct-fill)" stroke="var(--struct-stroke)" />
</g>
<!-- 底部结构 (垂直镜像) -->
<g id="structure-bottom" transform="scale(1, -1) translate(0, -600)">
<path d="M 220,100 L 370,100 C 390,100 410,140 410,210 L 406,210 C 406,145 385,115 220,115 Z" fill="var(--struct-fill)" stroke="var(--struct-stroke)" stroke-width="1.5" />
<path d="M 406,214 C 426,214 470,155 600,150 L 600,140 C 460,145 410,208 396,208 L 410,208 Z" fill="#1e2a40" stroke="#48628f" stroke-width="1.5" />
<rect x="200" y="100" width="20" height="15" fill="var(--struct-fill)" stroke="var(--struct-stroke)" />
</g>
<!-- ================= 主气流 (从缝隙喷出贴壁) ================= -->
<!-- 顶部缝隙射流 -->
<g filter="url(#glow)">
<path d="M 230,107 L 365,107 C 395,107 408,160 408,212 C 408,212 435,212 650,143" class="flow-primary" stroke-width="3" />
<!-- 中心极亮流线 -->
<path d="M 390,180 C 408,180 408,212 408,212 C 408,212 435,212 600,145" class="flow-core" />
</g>
<!-- 底部缝隙射流 -->
<g filter="url(#glow)">
<path d="M 230,493 L 365,493 C 395,493 408,440 408,388 C 408,388 435,388 650,457" class="flow-primary" stroke-width="3" style="animation-delay: -0.2s;" />
<path d="M 390,420 C 408,420 408,388 408,388 C 408,388 435,388 600,455" class="flow-core" style="animation-delay: -0.2s;" />
</g>
<!-- ================= 混合输出气流 (右侧大风量) ================= -->
<g class="mixed-flows">
<path d="M 450,220 C 600,220 750,180 900,180" class="flow-mixed" marker-end="url(#arrow-mixed)" />
<path d="M 500,250 C 650,250 800,220 950,220" class="flow-mixed" marker-end="url(#arrow-mixed)" style="animation-delay: -0.4s;" />
<path d="M 550,280 C 700,280 850,260 1000,260" class="flow-mixed" marker-end="url(#arrow-mixed)" style="animation-delay: -0.8s;" />
<path d="M 550,320 C 700,320 850,340 1000,340" class="flow-mixed" marker-end="url(#arrow-mixed)" style="animation-delay: -0.1s;" />
<path d="M 500,350 C 650,350 800,380 950,380" class="flow-mixed" marker-end="url(#arrow-mixed)" style="animation-delay: -0.5s;" />
<path d="M 450,380 C 600,380 750,420 900,420" class="flow-mixed" marker-end="url(#arrow-mixed)" style="animation-delay: -0.9s;" />
</g>
<!-- ================= 图形标注 (极简风格,避开核心区) ================= -->
<!-- 标注:环形细缝 -->
<g>
<polyline points="408,212 450,170 520,170" class="svg-label-line" />
<circle cx="408" cy="212" r="3" fill="var(--primary-cyan)" filter="url(#glow)"/>
<text x="525" y="174" class="svg-label-text">
<tspan class="svg-label-highlight">1.0mm</tspan> 环形细缝
</text>
</g>
<!-- 标注:康达效应曲面 -->
<g>
<polyline points="480,180 520,210 600,210" class="svg-label-line" />
<text x="605" y="214" class="svg-label-text">
<tspan class="svg-label-highlight">16°</tspan> 附壁导流面
</text>
</g>
<!-- 标注:负压区 -->
<g>
<polyline points="430,300 480,360 550,360" class="svg-label-line" />
<circle cx="430" cy="300" r="2" fill="var(--primary-cyan)" />
<text x="555" y="364" class="svg-label-text">低压核 / <tspan class="svg-label-highlight">强负压卷吸区</tspan></text>
</g>
<!-- 宏观状态文本 -->
<text x="80" y="304" class="svg-label-text" fill="var(--secondary-blue)" opacity="0.6">静止空气被卷入 >></text>
<text x="750" y="304" class="svg-label-text" fill="#66c2ff" opacity="0.8" font-size="14" font-weight="bold">大风量混合输出 >>></text>
</svg>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const slider = document.getElementById('pressureSlider');
const pressureValue = document.getElementById('pressureValue');
const root = document.documentElement;
// 核心逻辑:根据前端风压计算各动态参数
function updateSimulation() {
const val = parseInt(slider.value, 10);
const normalized = val / 100;
pressureValue.textContent = val + '%';
// 颜色警告:风压极低时标红,表示失效边界
if (val < 20) {
pressureValue.style.color = '#ff4d4d';
} else {
pressureValue.style.color = 'var(--primary-cyan)';
}
// 1. 气流速度映射 (风压越高,流速越快,动画周期越短)
// 限制在 0.4s (极快) 到 3s (极慢) 之间
let speed = 3 - (normalized * 2.6);
if (val < 15) speed = 5; // 几乎停止
root.style.setProperty('--flow-speed', `${speed}s`);
// 2. 射流发光强度 (模拟气流动能)
// 风压不足时急剧衰减
let glow = val < 20 ? 0 : Math.pow(normalized, 1.5) * 1.5;
root.style.setProperty('--glow-intensity', glow);
// 3. 卷吸效应透明度 (展现失效条件:风压不足无法从狭缝挤出气流,卷吸失效)
// 采用阈值非线性映射
let entrainment = 0;
if (val >= 20) {
entrainment = 0.2 + (normalized - 0.2) * 1.25;
} else {
entrainment = 0.05; // 仅存一点微弱流动
}
root.style.setProperty('--entrainment-opacity', Math.min(entrainment, 1));
// 4. 负压脉冲速度
root.style.setProperty('--pulse-speed', `${1.5 - (normalized * 0.8)}s`);
}
// 监听滑块交互
slider.addEventListener('input', updateSimulation);
// 初始化动画状态 (页面加载完毕自动播放,无需人为点击)
updateSimulation();
});
</script>
</body>
</html>
积分规则:第一轮对话扣减8分,后续每轮扣6分
等待动画代码生成...
