<!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=Orbitron:wght@400;700;900&family=Noto+Sans+SC:wght@300;400;600;700&display=swap" rel="stylesheet">
<style>
:root {
--bg: #060a14;
--flame-hot: #ff3d00;
--flame-warm: #ff8f00;
--ceramic-glow: #e65100;
--ir-cyan: #00e5ff;
--ir-teal: #00bcd4;
--water-blue: #42a5f5;
--water-deep: #1565c0;
--reflector-silver: #b0bec5;
--accent-green: #76ff03;
--text: #eceff1;
--text-dim: #607d8b;
--panel-bg: rgba(10, 18, 32, 0.92);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: var(--bg);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-family: 'Noto Sans SC', sans-serif;
color: var(--text);
overflow-x: hidden;
padding: 12px;
}
.container {
width: 100%;
max-width: 1100px;
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
}
.title-bar {
text-align: center;
margin-bottom: 4px;
}
.title-bar h1 {
font-family: 'Orbitron', sans-serif;
font-size: clamp(16px, 2.4vw, 26px);
font-weight: 700;
letter-spacing: 2px;
color: var(--ir-cyan);
text-shadow: 0 0 20px rgba(0,229,255,0.35);
}
.title-bar p {
font-size: clamp(11px, 1.3vw, 14px);
color: var(--text-dim);
margin-top: 4px;
font-weight: 300;
}
.svg-wrap {
width: 100%;
border: 1px solid rgba(0,229,255,0.12);
border-radius: 12px;
overflow: hidden;
background: linear-gradient(180deg, #080e1c 0%, #0a1222 100%);
box-shadow: 0 0 60px rgba(0,229,255,0.06), inset 0 0 80px rgba(0,0,0,0.3);
}
#mainSvg { display: block; width: 100%; height: auto; }
.controls {
width: 100%;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
gap: 20px;
padding: 14px 24px;
background: var(--panel-bg);
border: 1px solid rgba(0,229,255,0.1);
border-radius: 10px;
}
.ctrl-group {
display: flex;
align-items: center;
gap: 10px;
}
.ctrl-group label {
font-size: 13px;
color: var(--text-dim);
white-space: nowrap;
}
.ctrl-group .val {
font-family: 'Orbitron', sans-serif;
font-size: 15px;
font-weight: 700;
min-width: 68px;
text-align: right;
}
input[type=range] {
-webkit-appearance: none;
appearance: none;
width: 180px;
height: 6px;
border-radius: 3px;
background: linear-gradient(90deg, #ff6f00 0%, var(--ir-cyan) 60%, var(--accent-green) 100%);
outline: none;
cursor: pointer;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 18px; height: 18px;
border-radius: 50%;
background: var(--text);
border: 2px solid var(--ir-cyan);
box-shadow: 0 0 8px rgba(0,229,255,0.5);
}
.phase-indicator {
display: flex;
gap: 6px;
align-items: center;
}
.phase-dot {
width: 10px; height: 10px;
border-radius: 50%;
background: var(--text-dim);
transition: all 0.4s;
}
.phase-dot.active {
background: var(--ir-cyan);
box-shadow: 0 0 10px var(--ir-cyan);
transform: scale(1.3);
}
.phase-label {
font-size: 11px;
color: var(--text-dim);
max-width: 56px;
text-align: center;
line-height: 1.2;
}
.phase-step { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.match-badge {
font-family: 'Orbitron', sans-serif;
font-size: 12px;
padding: 4px 12px;
border-radius: 20px;
font-weight: 700;
transition: all 0.5s;
}
.match-badge.optimal {
background: rgba(118,255,3,0.15);
color: var(--accent-green);
border: 1px solid var(--accent-green);
box-shadow: 0 0 12px rgba(118,255,3,0.3);
}
.match-badge.mismatch {
background: rgba(255,61,0,0.12);
color: var(--flame-hot);
border: 1px solid rgba(255,61,0,0.4);
}
/* SVG 内部动画 */
@keyframes flameFlicker {
0%, 100% { opacity: 0.85; transform: scaleY(1) translateY(0); }
25% { opacity: 1; transform: scaleY(1.08) translateY(-2px); }
50% { opacity: 0.75; transform: scaleY(0.94) translateY(1px); }
75% { opacity: 0.95; transform: scaleY(1.04) translateY(-1px); }
}
@keyframes glowPulse {
0%, 100% { opacity: 0.6; }
50% { opacity: 1; }
}
@keyframes moleculeVibrate {
0%, 100% { transform: translate(var(--mx), var(--my)) rotate(0deg); }
25% { transform: translate(calc(var(--mx) + var(--vx)), calc(var(--my) - var(--vy))) rotate(3deg); }
75% { transform: translate(calc(var(--mx) - var(--vx)), calc(var(--my) + var(--vy))) rotate(-3deg); }
}
@keyframes waveDash {
to { stroke-dashoffset: -40; }
}
@keyframes radExpand {
0% { r: 0; opacity: 0.7; }
100% { r: 60; opacity: 0; }
}
@keyframes particleFlow {
0% { offset-distance: 0%; opacity: 0; }
10% { opacity: 1; }
90% { opacity: 1; }
100% { offset-distance: 100%; opacity: 0; }
}
</style>
</head>
<body>
<div class="container">
<div class="title-bar">
<h1>FAR-IR RADIATION FOCUSING PRINCIPLE</h1>
<p>梯度发射率多孔陶瓷火盖 + 微晶抛物面聚能盘 — 维恩位移定律驱动的光谱匹配传热</p>
</div>
<div class="svg-wrap">
<svg id="mainSvg" viewBox="0 0 1200 880" xmlns="http://www.w3.org/2000/svg">
<defs>
<!-- 渐变定义 -->
<radialGradient id="bgGlow" cx="50%" cy="55%" r="55%">
<stop offset="0%" stop-color="#0d1a30" />
<stop offset="100%" stop-color="#060a14" />
</radialGradient>
<linearGradient id="flameGrad" x1="0" y1="1" x2="0" y2="0">
<stop offset="0%" stop-color="#ff6f00" />
<stop offset="40%" stop-color="#ff3d00" />
<stop offset="80%" stop-color="#ffab00" stop-opacity="0.7" />
<stop offset="100%" stop-color="#fff176" stop-opacity="0.3" />
</linearGradient>
<linearGradient id="ceramicGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#a1887f" />
<stop offset="50%" stop-color="#8d6e63" />
<stop offset="100%" stop-color="#6d4c41" />
</linearGradient>
<linearGradient id="coatingGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#ff8f00" />
<stop offset="100%" stop-color="#e65100" />
</linearGradient>
<linearGradient id="reflectorGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#cfd8dc" />
<stop offset="30%" stop-color="#90a4ae" />
<stop offset="70%" stop-color="#b0bec5" />
<stop offset="100%" stop-color="#78909c" />
</linearGradient>
<linearGradient id="potGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#546e7a" />
<stop offset="100%" stop-color="#37474f" />
</linearGradient>
<linearGradient id="waterGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="rgba(66,165,245,0.12)" />
<stop offset="100%" stop-color="rgba(21,101,192,0.25)" />
</linearGradient>
<!-- 滤镜 -->
<filter id="glowCyan" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="4" result="blur" />
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="glowOrange" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur in="SourceGraphic" stdDeviation="6" result="blur" />
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="glowStrong" x="-80%" y="-80%" width="260%" height="260%">
<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
<feMerge><feMergeNode in="blur"/><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="softGlow" x="-30%" y="-30%" width="160%" height="160%">
<feGaussianBlur in="SourceGraphic" stdDeviation="3" result="blur" />
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<!-- 多孔陶瓷纹理 -->
<pattern id="porePattern" x="0" y="0" width="14" height="14" patternUnits="userSpaceOnUse">
<circle cx="4" cy="4" r="1.8" fill="#4e342e" opacity="0.5"/>
<circle cx="11" cy="10" r="1.5" fill="#4e342e" opacity="0.4"/>
<circle cx="8" cy="2" r="1" fill="#3e2723" opacity="0.3"/>
</pattern>
<!-- 锅底微孔纹理 -->
<pattern id="microPorePattern" x="0" y="0" width="8" height="8" patternUnits="userSpaceOnUse">
<circle cx="2" cy="2" r="0.8" fill="#263238" opacity="0.6"/>
<circle cx="6" cy="6" r="0.6" fill="#263238" opacity="0.5"/>
</pattern>
<!-- 网格背景 -->
<pattern id="gridPattern" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse">
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="rgba(0,229,255,0.04)" stroke-width="0.5"/>
</pattern>
<!-- 光线运动路径 -->
<path id="rayDirect1" d="M 560,505 L 560,240" fill="none"/>
<path id="rayDirect2" d="M 600,505 L 600,240" fill="none"/>
<path id="rayDirect3" d="M 640,505 L 640,240" fill="none"/>
<path id="rayReflectL1" d="M 510,540 Q 300,470 460,240" fill="none"/>
<path id="rayReflectL2" d="M 500,580 Q 240,530 400,240" fill="none"/>
<path id="rayReflectR1" d="M 690,540 Q 900,470 740,240" fill="none"/>
<path id="rayReflectR2" d="M 700,580 Q 960,530 800,240" fill="none"/>
</defs>
<!-- 背景 -->
<rect width="1200" height="880" fill="url(#bgGlow)"/>
<rect width="1200" height="880" fill="url(#gridPattern)"/>
<!-- ====== 聚能盘 (抛物面反射器) ====== -->
<g id="reflectorGroup">
<!-- 抛物面外壳 -->
<path d="M 230,430 C 290,630 440,720 600,738 C 760,720 910,630 970,430"
fill="none" stroke="url(#reflectorGrad)" stroke-width="28" stroke-linecap="round"
opacity="0.85"/>
<!-- 内反射面高光 -->
<path d="M 245,435 C 300,620 445,710 600,726 C 755,710 900,620 955,435"
fill="none" stroke="rgba(255,255,255,0.12)" stroke-width="4" stroke-linecap="round"/>
<!-- 标注线 -->
<line x1="970" y1="430" x2="1030" y2="380" stroke="rgba(176,190,197,0.4)" stroke-width="1" stroke-dasharray="4,3"/>
<text x="1035" y="378" fill="#90a4ae" font-size="12" font-family="'Noto Sans SC'" font-weight="400">微晶抛物面聚能盘</text>
<text x="1035" y="395" fill="#607d8b" font-size="10" font-family="'Noto Sans SC'" font-weight="300">焦距对准锅底中心</text>
</g>
<!-- ====== 多孔陶瓷火盖 ====== -->
<g id="burnerGroup">
<!-- 陶瓷主体 -->
<rect x="498" y="530" width="204" height="130" rx="10" fill="url(#ceramicGrad)" stroke="#5d4037" stroke-width="1.5"/>
<!-- 多孔纹理叠加 -->
<rect x="498" y="530" width="204" height="130" rx="10" fill="url(#porePattern)"/>
<!-- 远红外涂层 (顶部内表面) -->
<rect x="503" y="530" width="194" height="12" rx="4" fill="url(#coatingGrad)" opacity="0.9"/>
<rect x="503" y="530" width="194" height="12" rx="4" fill="none" stroke="#ff6f00" stroke-width="0.5" opacity="0.6"/>
<!-- 内部火焰 -->
<g id="flameGroup" style="animation: flameFlicker 0.8s ease-in-out infinite; transform-origin: 600px 600px;">
<ellipse cx="600" cy="600" rx="50" ry="40" fill="url(#flameGrad)" filter="url(#glowOrange)" opacity="0.85"/>
<ellipse cx="600" cy="590" rx="30" ry="28" fill="#ffcc02" opacity="0.5"/>
<ellipse cx="600" cy="585" rx="15" ry="18" fill="#fff9c4" opacity="0.4"/>
</g>
<!-- 陶瓷表面热辐射光晕 -->
<ellipse cx="600" cy="530" rx="90" ry="8" fill="#ff8f00" opacity="0.25" filter="url(#glowOrange)">
<animate attributeName="opacity" values="0.15;0.35;0.15" dur="2s" repeatCount="indefinite"/>
</ellipse>
<!-- 标注 -->
<line x1="498" y1="595" x2="420" y2="620" stroke="rgba(255,143,0,0.4)" stroke-width="1" stroke-dasharray="4,3"/>
<text x="280" y="618" fill="#ffab00" font-size="12" font-family="'Noto Sans SC'" font-weight="600">碳化硅基多孔陶瓷火盖</text>
<text x="280" y="636" fill="#ff8f00" font-size="10" font-family="'Noto Sans SC'" font-weight="300">850~950°C · 发射率 > 0.9</text>
<text x="280" y="654" fill="#ff6f00" font-size="10" font-family="'Noto Sans SC'" font-weight="300">过渡金属氧化物远红外涂层</text>
<!-- 温度标注 -->
<g id="tempLabel" transform="translate(720, 580)">
<rect x="0" y="-12" width="90" height="24" rx="4" fill="rgba(255,143,0,0.12)" stroke="rgba(255,143,0,0.3)" stroke-width="0.8"/>
<text x="45" y="4" text-anchor="middle" fill="#ffab00" font-size="12" font-family="'Orbitron'" font-weight="700" id="tempDisplay">900°C</text>
</g>
</g>
<!-- ====== 辐射射线 (JS 动态绘制) ====== -->
<g id="radiationGroup"></g>
<!-- ====== 辐射波纹 (从陶瓷表面扩散) ====== -->
<g id="waveGroup"></g>
<!-- ====== 锅具截面 ====== -->
<g id="potGroup">
<!-- 锅内水/食材 -->
<rect x="366" y="85" width="468" height="155" rx="3" fill="url(#waterGrad)"/>
<!-- 锅壁 -->
<path d="M 360,80 L 360,238 Q 360,248 370,248 L 830,248 Q 840,248 840,238 L 840,80"
fill="none" stroke="#546e7a" stroke-width="8" stroke-linejoin="round"/>
<!-- 锅底 -->
<rect x="360" y="234" width="480" height="20" rx="2" fill="url(#potGrad)"/>
<!-- 锅底微孔层 -->
<rect x="360" y="240" width="480" height="14" rx="1" fill="url(#microPorePattern)" opacity="0.7"/>
<!-- 选择性吸收涂层 -->
<rect x="365" y="236" width="470" height="4" rx="1" fill="#455a64" opacity="0.6"/>
<line x1="365" y1="238" x2="835" y2="238" stroke="#607d8b" stroke-width="0.5" stroke-dasharray="2,2" opacity="0.4"/>
<!-- 标注 -->
<line x1="840" y1="242" x2="920" y2="268" stroke="rgba(84,110,122,0.4)" stroke-width="1" stroke-dasharray="4,3"/>
<text x="925" y="265" fill="#78909c" font-size="11" font-family="'Noto Sans SC'" font-weight="400">亚微米级微孔结构锅底</text>
<text x="925" y="282" fill="#607d8b" font-size="10" font-family="'Noto Sans SC'" font-weight="300">选择性吸收 · 红外穿透</text>
</g>
<!-- ====== 水分子群 ====== -->
<g id="moleculeGroup"></g>
<!-- ====== 光谱匹配指示器 ====== -->
<g id="spectralDisplay" transform="translate(30, 680)">
<rect x="0" y="0" width="320" height="160" rx="8" fill="rgba(6,10,20,0.85)" stroke="rgba(0,229,255,0.15)" stroke-width="1"/>
<text x="160" y="22" text-anchor="middle" fill="#90a4ae" font-size="11" font-family="'Noto Sans SC'" font-weight="600">光谱匹配度 · 维恩位移定律</text>
<text x="160" y="38" text-anchor="middle" fill="#607d8b" font-size="9" font-family="'Orbitron'">λmax = 2898 / T(K) μm</text>
<!-- 波长轴 -->
<line x1="30" y1="120" x2="290" y2="120" stroke="#455a64" stroke-width="1"/>
<text x="30" y="135" fill="#607d8b" font-size="9" font-family="'Orbitron'">2μm</text>
<text x="140" y="135" fill="#607d8b" font-size="9" font-family="'Orbitron'">3μm</text>
<text x="260" y="135" fill="#607d8b" font-size="9" font-family="'Orbitron'">5μm</text>
<!-- 水吸收带 (2.7-3.2μm) -->
<rect id="waterAbsBand" x="108" y="55" width="42" height="60" rx="2" fill="rgba(66,165,245,0.12)" stroke="rgba(66,165,245,0.3)" stroke-width="0.8"/>
<text x="129" y="52" text-anchor="middle" fill="#42a5f5" font-size="8" font-family="'Noto Sans SC'">H₂O吸收带</text>
<!-- 发射峰 (动态) -->
<g id="emissionPeak">
<line id="emissionLine" x1="129" y1="60" x2="129" y2="118" stroke="#ff8f00" stroke-width="2" opacity="0.8"/>
<polygon id="emissionArrow" points="129,58 124,68 134,68" fill="#ff8f00" opacity="0.9"/>
</g>
<text id="wavelengthLabel" x="129" y="150" text-anchor="middle" fill="#ffab00" font-size="10" font-family="'Orbitron'" font-weight="700">2.47μm</text>
<!-- 匹配度指示 -->
<text id="matchText" x="250" y="95" text-anchor="middle" fill="#76ff03" font-size="13" font-family="'Orbitron'" font-weight="700">MATCH</text>
</g>
<!-- ====== 核心机理文字标注 ====== -->
<g id="mechanismLabels">
<!-- 步骤1 -->
<g transform="translate(40, 450)">
<circle cx="8" cy="0" r="8" fill="none" stroke="#ff8f00" stroke-width="1.5" opacity="0.7"/>
<text x="8" y="4" text-anchor="middle" fill="#ff8f00" font-size="9" font-family="'Orbitron'" font-weight="700">1</text>
<text x="22" y="4" fill="#ffab00" font-size="11" font-family="'Noto Sans SC'" font-weight="600">多孔陶瓷蓄热</text>
<text x="22" y="18" fill="#8d6e63" font-size="9" font-family="'Noto Sans SC'" font-weight="300">1200°C明火 → 900°C辐射体</text>
</g>
<!-- 步骤2 -->
<g transform="translate(40, 490)">
<circle cx="8" cy="0" r="8" fill="none" stroke="#00e5ff" stroke-width="1.5" opacity="0.7"/>
<text x="8" y="4" text-anchor="middle" fill="#00e5ff" font-size="9" font-family="'Orbitron'" font-weight="700">2</text>
<text x="22" y="4" fill="#00e5ff" font-size="11" font-family="'Noto Sans SC'" font-weight="600">远红外涂层辐射</text>
<text x="22" y="18" fill="#0097a7" font-size="9" font-family="'Noto Sans SC'" font-weight="300">发射率>0.9 · 峰值2.9μm</text>
</g>
<!-- 步骤3 -->
<g transform="translate(40, 530)">
<circle cx="8" cy="0" r="8" fill="none" stroke="#b0bec5" stroke-width="1.5" opacity="0.7"/>
<text x="8" y="4" text-anchor="middle" fill="#b0bec5" font-size="9" font-family="'Orbitron'" font-weight="700">3</text>
<text x="22" y="4" fill="#b0bec5" font-size="11" font-family="'Noto Sans SC'" font-weight="600">抛物面聚焦</text>
<text x="22" y="18" fill="#78909c" font-size="9" font-family="'Noto Sans SC'" font-weight="300">散射红外 → 锅底中心</text>
</g>
<!-- 步骤4 -->
<g transform="translate(40, 570)">
<circle cx="8" cy="0" r="8" fill="none" stroke="#42a5f5" stroke-width="1.5" opacity="0.7"/>
<text x="8" y="4" text-anchor="middle" fill="#42a5f5" font-size="9" font-family="'Orbitron'" font-weight="700">4</text>
<text x="22" y="4" fill="#42a5f5" font-size="11" font-family="'Noto Sans SC'" font-weight="600">水分子共振吸收</text>
<text x="22" y="18" fill="#1e88e5" font-size="9" font-family="'Noto Sans SC'" font-weight="300">2.9μm = O-H伸缩峰 · 直接产热</text>
</g>
</g>
<!-- ====== IFR 理想解标识 ====== -->
<g transform="translate(940, 700)">
<rect x="0" y="0" width="220" height="130" rx="8" fill="rgba(6,10,20,0.85)" stroke="rgba(118,255,3,0.2)" stroke-width="1"/>
<text x="110" y="22" text-anchor="middle" fill="#76ff03" font-size="11" font-family="'Orbitron'" font-weight="700" letter-spacing="1">IDEAL FINAL RESULT</text>
<line x1="15" y1="30" x2="205" y2="30" stroke="rgba(118,255,3,0.15)" stroke-width="0.5"/>
<text x="15" y="48" fill="#aed581" font-size="10" font-family="'Noto Sans SC'" font-weight="400">▸ 热源-辐射-吸收 频率绝对协调</text>
<text x="15" y="66" fill="#aed581" font-size="10" font-family="'Noto Sans SC'" font-weight="400">▸ 光谱匹配替代温度堆砌</text>
<text x="15" y="84" fill="#aed581" font-size="10" font-family="'Noto Sans SC'" font-weight="400">▸ 陶瓷自身 = 波长变换器</text>
<text x="15" y="102" fill="#aed581" font-size="10" font-family="'Noto Sans SC'" font-weight="400">▸ 反射盘 = 零能耗聚能器</text>
<text x="15" y="120" fill="#81c784" font-size="9" font-family="'Noto Sans SC'" font-weight="300">不增加复杂度,矛盾自行消失</text>
</g>
</svg>
</div>
<!-- 控制面板 -->
<div class="controls">
<div class="ctrl-group">
<label>陶瓷温度</label>
<input type="range" id="tempSlider" min="700" max="1200" value="900" step="10"/>
<span class="val" id="tempVal" style="color: var(--flame-warm);">900°C</span>
</div>
<div class="ctrl-group">
<label>峰值波长</label>
<span class="val" id="waveVal" style="color: var(--ir-cyan);">2.58μm</span>
</div>
<div class="ctrl-group">
<label>匹配状态</label>
<span class="match-badge optimal" id="matchBadge">光谱匹配</span>
</div>
<div class="phase-indicator">
<div class="phase-step"><div class="phase-dot active" id="pd0"></div><span class="phase-label">蓄热</span></div>
<div class="phase-step"><div class="phase-dot" id="pd1"></div><span class="phase-label">辐射</span></div>
<div class="phase-step"><div class="phase-dot" id="pd2"></div><span class="phase-label">聚焦</span></div>
<div class="phase-step"><div class="phase-dot" id="pd3"></div><span class="phase-label">共振</span></div>
</div>
</div>
</div>
<script>
(function() {
const SVG_NS = 'http://www.w3.org/2000/svg';
const svg = document.getElementById('mainSvg');
const radiationGroup = document.getElementById('radiationGroup');
const waveGroup = document.getElementById('waveGroup');
const moleculeGroup = document.getElementById('moleculeGroup');
// 状态
let ceramicTemp = 900; // °C
let animFrame = 0;
let phase = 0; // 0-3 对应四个阶段
let phaseTimer = 0;
const PHASE_DURATION = 120; // 帧数
// 光谱参数
function getPeakWavelength(tempC) {
const tempK = tempC + 273.15;
return 2898 / tempK; // μm
}
function getMatchScore(wavelength) {
// 水吸收带 2.7-3.2μm,峰值 ~2.9μm
const center = 2.9;
const sigma = 0.25;
return Math.exp(-Math.pow(wavelength - center, 2) / (2 * sigma * sigma));
}
// ====== 创建水分子 ======
const moleculeData = [];
const MOLECULE_COUNT = 14;
for (let i = 0; i < MOLECULE_COUNT; i++) {
const mx = 400 + Math.random() * 400;
const my = 100 + Math.random() * 120;
const angle = Math.random() * Math.PI * 2;
moleculeData.push({ x: mx, y: my, angle, baseAngle: angle, vibAmp: 0 });
}
function createMolecule(d) {
const g = document.createElementNS(SVG_NS, 'g');
g.setAttribute('transform', `translate(${d.x}, ${d.y}) rotate(${d.angle * 180 / Math.PI})`);
// O 原子
const o = document.createElementNS(SVG_NS, 'circle');
o.setAttribute('cx', '0'); o.setAttribute('cy', '0');
o.setAttribute('r', '5'); o.setAttribute('fill', '#1565c0');
g.appendChild(o);
// H1
const h1 = document.createElementNS(SVG_NS, 'circle');
h1.setAttribute('cx', '-6'); h1.setAttribute('cy', '-5');
h1.setAttribute('r', '3'); h1.setAttribute('fill', '#42a5f5');
g.appendChild(h1);
// H2
const h2 = document.createElementNS(SVG_NS, 'circle');
h2.setAttribute('cx', '6'); h2.setAttribute('cy', '-5');
h2.setAttribute('r', '3'); h2.setAttribute('fill', '#42a5f5');
g.appendChild(h2);
// 键
const b1 = document.createElementNS(SVG_NS, 'line');
b1.setAttribute('x1', '-3.5'); b1.setAttribute('y1', '-2.5');
b1.setAttribute('x2', '-5'); b1.setAttribute('y2', '-3.5');
b1.setAttribute('stroke', '#90caf9'); b1.setAttribute('stroke-width', '1.2');
g.appendChild(b1);
const b2 = document.createElementNS(SVG_NS, 'line');
b2.setAttribute('x1', '3.5'); b2.setAttribute('y1', '-2.5');
b2.setAttribute('x2', '5'); b2.setAttribute('y2', '-3.5');
b2.setAttribute('stroke', '#90caf9'); b2.setAttribute('stroke-width', '1.2');
g.appendChild(b2);
// 发光效果(共振时)
const glow = document.createElementNS(SVG_NS, 'circle');
glow.setAttribute('cx', '0'); glow.setAttribute('cy', '0');
glow.setAttribute('r', '10'); glow.setAttribute('fill', 'none');
glow.setAttribute('stroke', '#42a5f5'); glow.setAttribute('stroke-width', '0.8');
glow.setAttribute('opacity', '0');
g.appendChild(glow);
d.element = g;
d.glowEl = glow;
d.h1El = h1;
d.h2El = h2;
moleculeGroup.appendChild(g);
}
moleculeData.forEach(createMolecule);
// ====== 辐射粒子系统 ======
const particles = [];
const PARTICLE_COUNT = 30;
// 射线定义
const rayPaths = [
// 直射
{ type: 'direct', x1: 560, y1: 525, x2: 560, y2: 248 },
{ type: 'direct', x1: 600, y1: 525, x2: 600, y2: 248 },
{ type: 'direct', x1: 640, y1: 525, x2: 640, y2: 248 },
// 反射 - 左
{ type: 'reflect', x1: 510, y1: 540, cpx: 310, cpy: 465, x2: 460, y2: 248 },
{ type: 'reflect', x1: 500, y1: 575, cpx: 255, cpy: 530, x2: 410, y2: 248 },
// 反射 - 右
{ type: 'reflect', x1: 690, y1: 540, cpx: 890, cpy: 465, x2: 740, y2: 248 },
{ type: 'reflect', x1: 700, y1: 575, cpx: 945, cpy: 530, x2: 790, y2: 248 },
];
function bezierPoint(t, p0x, p0y, cpx, cpy, p1x, p1y) {
const mt = 1 - t;
return {
x: mt * mt * p0x + 2 * mt * t * cpx + t * t * p1x,
y: mt * mt * p0y + 2 * mt * t * cpy + t * t * p1y
};
}
function lerp(a, b, t) { return a + (b - a) * t; }
function createParticle() {
const rayIdx = Math.floor(Math.random() * rayPaths.length);
const ray = rayPaths[rayIdx];
const el = document.createElementNS(SVG_NS, 'circle');
el.setAttribute('r', '2.5');
el.setAttribute('fill', '#00e5ff');
el.setAttribute('opacity', '0');
radiationGroup.appendChild(el);
return {
el,
ray,
t: Math.random(),
speed: 0.004 + Math.random() * 0.004,
active: true
};
}
for (let i = 0; i < PARTICLE_COUNT; i++) {
particles.push(createParticle());
}
// ====== 波纹效果 ======
const waveRings = [];
const WAVE_COUNT = 5;
for (let i = 0; i < WAVE_COUNT; i++) {
const el = document.createElementNS(SVG_NS, 'ellipse');
el.setAttribute('cx', '600');
el.setAttribute('cy', '525');
el.setAttribute('rx', '0');
el.setAttribute('ry', '0');
el.setAttribute('fill', 'none');
el.setAttribute('stroke', '#00e5ff');
el.setAttribute('stroke-width', '1');
el.setAttribute('opacity', '0');
waveGroup.appendChild(el);
waveRings.push({ el, phase: i / WAVE_COUNT });
}
// ====== 绘制静态射线参考线 ======
rayPaths.forEach(ray => {
const line = document.createElementNS(SVG_NS, 'line');
if (ray.type === 'direct') {
line.setAttribute('x1', ray.x1); line.setAttribute('y1', ray.y1);
line.setAttribute('x2', ray.x2); line.setAttribute('y2', ray.y2);
}
line.setAttribute('stroke', 'rgba(0,229,255,0.06)');
line.setAttribute('stroke-width', '1');
line.setAttribute('stroke-dasharray', '4,6');
radiationGroup.insertBefore(line, radiationGroup.firstChild);
if (ray.type === 'reflect') {
const path = document.createElementNS(SVG_NS, 'path');
path.setAttribute('d', `M ${ray.x1},${ray.y1} Q ${ray.cpx},${ray.cpy} ${ray.x2},${ray.y2}`);
path.setAttribute('fill', 'none');
path.setAttribute('stroke', 'rgba(0,229,255,0.06)');
path.setAttribute('stroke-width', '1');
path.setAttribute('stroke-dasharray', '4,6');
radiationGroup.insertBefore(path, radiationGroup.firstChild);
}
});
// ====== 反射点高光 ======
const reflectPoints = [
{ x: 310, y: 465 }, { x: 255, y: 530 },
{ x: 890, y: 465 }, { x: 945, y: 530 }
];
reflectPoints.forEach(p => {
const c = document.createElementNS(SVG_NS, 'circle');
c.setAttribute('cx', p.x); c.setAttribute('cy', p.y);
c.setAttribute('r', '3');
c.setAttribute('fill', '#b0bec5');
c.setAttribute('opacity', '0.15');
c.setAttribute('filter', 'url(#softGlow)');
waveGroup.appendChild(c);
});
// ====== 交互控制 ======
const tempSlider = document.getElementById('tempSlider');
const tempVal = document.getElementById('tempVal');
const waveVal = document.getElementById('waveVal');
const matchBadge = document.getElementById('matchBadge');
const tempDisplay = document.getElementById('tempDisplay');
const emissionLine = document.getElementById('emissionLine');
const emissionArrow = document.getElementById('emissionArrow');
const wavelengthLabel = document.getElementById('wavelengthLabel');
const matchText = document.getElementById('matchText');
tempSlider.addEventListener('input', function() {
ceramicTemp = parseInt(this.value);
updateDisplays();
});
function updateDisplays() {
const wl = getPeakWavelength(ceramicTemp);
const match = getMatchScore(wl);
tempVal.textContent = ceramicTemp + '°C';
waveVal.textContent = wl.toFixed(2) + 'μm';
tempDisplay.textContent = ceramicTemp + '°C';
// 光谱指示器位置(2μm=30px, 5μm=290px,线性映射)
const specX = 30 + (wl - 2) / (5 - 2) * 260;
emissionLine.setAttribute('x1', specX);
emissionLine.setAttribute('x2', specX);
emissionArrow.setAttribute('points', `${specX},58 ${specX-5},68 ${specX+5},68`);
wavelengthLabel.setAttribute('x', specX);
wavelengthLabel.textContent = wl.toFixed(2) + 'μm';
if (match > 0.6) {
matchBadge.className = 'match-badge optimal';
matchBadge.textContent = '光谱匹配';
matchText.textContent = 'MATCH';
matchText.setAttribute('fill', '#76ff03');
emissionLine.setAttribute('stroke', '#76ff03');
emissionArrow.setAttribute('fill', '#76ff03');
wavelengthLabel.setAttribute('fill', '#76ff03');
} else {
matchBadge.className = 'match-badge mismatch';
matchBadge.textContent = '波长偏离';
matchText.textContent = 'MISMATCH';
matchText.setAttribute('fill', '#ff3d00');
emissionLine.setAttribute('stroke', '#ff3d00');
emissionArrow.setAttribute('fill', '#ff3d00');
wavelengthLabel.setAttribute('fill', '#ff3d00');
}
}
// ====== 主动画循环 ======
function animate() {
animFrame++;
phaseTimer++;
// 阶段循环
if (phaseTimer > PHASE_DURATION) {
phaseTimer = 0;
phase = (phase + 1) % 4;
}
// 更新阶段指示器
for (let i = 0; i < 4; i++) {
const dot = document.getElementById('pd' + i);
dot.className = 'phase-dot' + (i === phase ? ' active' : '');
}
const wl = getPeakWavelength(ceramicTemp);
const match = getMatchScore(wl);
// ---- 更新辐射粒子 ----
const rayOpacity = phase >= 1 ? Math.min(1, (phaseTimer / 30)) : 0.3;
particles.forEach(p => {
p.t += p.speed * (0.5 + match * 1.5);
if (p.t > 1) {
p.t = 0;
p.ray = rayPaths[Math.floor(Math.random() * rayPaths.length)];
}
let pos;
if (p.ray.type === 'direct') {
pos = { x: lerp(p.ray.x1, p.ray.x2, p.t), y: lerp(p.ray.y1, p.ray.y2, p.t) };
} else {
pos = bezierPoint(p.t, p.ray.x1, p.ray.y1, p.ray.cpx, p.ray.cpy, p.ray.x2, p.ray.y2);
}
const alpha = Math.sin(p.t * Math.PI) * rayOpacity * (0.5 + match * 0.5);
p.el.setAttribute('cx', pos.x);
p.el.setAttribute('cy', pos.y);
p.el.setAttribute('opacity', alpha.toFixed(3));
// 颜色根据匹配度变化
if (match > 0.6) {
p.el.setAttribute('fill', '#00e5ff');
p.el.setAttribute('r', (2 + match * 1.5).toFixed(1));
} else {
p.el.setAttribute('fill', '#ff8f00');
p.el.setAttribute('r', '2');
}
// 到达锅底时的爆发效果
if (p.t > 0.9 && match > 0.6) {
p.el.setAttribute('filter', 'url(#glowCyan)');
} else {
p.el.removeAttribute('filter');
}
});
// ---- 更新波纹 ----
waveRings.forEach(w => {
w.phase += 0.006 * (0.5 + match);
if (w.phase > 1) w.phase -= 1;
const r = w.phase * 80;
const ry = r * 0.3;
const alpha = (1 - w.phase) * 0.3 * (phase >= 1 ? 1 : 0.2);
w.el.setAttribute('rx', r.toFixed(1));
w.el.setAttribute('ry', ry.toFixed(1));
w.el.setAttribute('opacity', alpha.toFixed(3));
if (match > 0.6) {
w.el.setAttribute('stroke', '#00e5ff');
} else {
w.el.setAttribute('stroke', '#ff8f00');
}
});
// ---- 更新水分子振动 ----
const vibIntensity = match * (phase >= 3 ? 1 : 0.3);
moleculeData.forEach((d, i) => {
const timeOffset = i * 0.7;
const vibX = Math.sin(animFrame * 0.08 + timeOffset) * vibIntensity * 4;
const vibY = Math.cos(animFrame * 0.1 + timeOffset) * vibIntensity * 3;
const rotAngle = d.baseAngle * 180 / Math.PI + Math.sin(animFrame * 0.06 + timeOffset) * vibIntensity * 15;
// O-H 键伸缩
const stretch = 1 + Math.sin(animFrame * 0.12 + timeOffset) * vibIntensity * 0.3;
d.h1El.setAttribute('cx', (-6 * stretch).toFixed(1));
d.h2El.setAttribute('cx', (6 * stretch).toFixed(1));
d.element.setAttribute('transform',
`translate(${(d.x + vibX).toFixed(1)}, ${(d.y + vibY).toFixed(1)}) rotate(${rotAngle.toFixed(1)})`);
// 共振光晕
const glowAlpha = vibIntensity * 0.5 * (0.5 + 0.5 * Math.sin(animFrame * 0.1 + timeOffset));
d.glowEl.setAttribute('opacity', glowAlpha.toFixed(3));
if (match > 0.6) {
d.glowEl.setAttribute('stroke', '#42a5f5');
d.oParent = d.element.querySelector('circle');
} else {
d.glowEl.setAttribute('stroke', '#546e7a');
}
});
// ---- 火焰强度随温度变化 ----
const flameGroup = document.getElementById('flameGroup');
const flameScale = 0.7 + (ceramicTemp - 700) / 500 * 0.5;
flameGroup.style.transform = `scaleY(${flameScale.toFixed(2)})`;
requestAnimationFrame(animate);
}
// 初始化
updateDisplays();
animate();
// 自动阶段切换动画(连续循环展示四个阶段)
// 阶段已在 animate() 中自动循环
})();
</script>
</body>
</html>
实现说明
本动画以 "热-辐射-吸收"频率绝对协调 为核心叙事,采用暗色科技仪器美学(Technical-Noir),通过以下设计实现 IFR 思想的可视化:
视觉架构
- 纵剖面视图:从下至上依次为多孔陶瓷火盖→抛物面聚能盘→辐射传输区→微孔锅底→水分子层,清晰呈现能量转化路径
- 四阶段自动循环:蓄热→辐射→聚焦→共振,底部指示器实时标注当前阶段
- 光谱匹配面板(左下):实时显示维恩位移定律计算的峰值波长与水分子吸收带(2.7-3.2μm)的重合度
IFR 核心表达
- 陶瓷自身即为"波长变换器"——无需额外能源,仅靠材料特性将1200°C明火降频为900°C辐射体
- 抛物面聚能盘为零能耗聚能器——纯粹几何资源利用,将散射红外重定向至锅底
- 水分子共振动画直观展示"光谱匹配替代温度堆砌":当波长落入吸收带,分子剧烈振动(O-H键伸缩);偏离时振动衰减
交互控制
- 温度滑块(700-1200°C):拖动可观察波长偏移,当偏离900°C最佳工作点时,辐射粒子变橙、水分子振动减弱、匹配状态切换为"波长偏离"
- 匹配度通过粒子颜色/大小/速度、分子振幅、波纹强度三重反馈同步呈现
积分规则:第一轮对话扣减6分,后续每轮扣4分
等待动画代码生成...
