分享图
动画工坊
引擎就绪

这里是为您设计的“国标直流快充 PCM 相变热管理系统”原理动画。

为了打破常规的技术演示风格,我采用了**“深空科技诊断界面 (Sci-Fi Diagnostics Panel)”**的美学方向。这种风格通过硬核的等宽字体、深邃的炭黑背景、发光的能量流迹以及高对比度的热成像色彩映射,生动地呈现了 IFR(最终理想解)—— 即系统巧妙利用 PCM 潜热“吞噬”快充热量的核心物理过程。

请将以下代码保存为 .html 文件并在现代浏览器中全屏打开,动画将在加载完毕后自动循环播放。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CTP相变热管理系统原理</title>
    <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Share+Tech+Mono&display=swap" rel="stylesheet">
    <style>
        :root {
            /* 主题调色板 */
            --bg-color: #07090e;
            --grid-color: rgba(0, 255, 255, 0.04);
            --panel-bg: rgba(9, 14, 23, 0.7);
            --panel-border: #1a2a40;
            --text-main: #e2e8f0;
            --text-accent: #00f0ff;
            --text-warn: #ff3c00;
            
            /* 动态变量 (由JS控制) */
            --cell-color: #1e293b;
            --cell-glow: rgba(30, 41, 59, 0);
            --pcm-color: #0f3a40;
            --pcm-glow: rgba(0, 255, 255, 0);
            --current-dash-speed: 0s;
            --current-opacity: 0;
            --data-blur: 8px;
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            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: 30px 30px;
            color: var(--text-main);
            font-family: 'Share Tech Mono', monospace;
            height: 100vh;
            width: 100vw;
            display: flex;
            justify-content: center;
            align-items: center;
            overflow: hidden;
            position: relative;
        }

        /* 顶部标题栏 */
        .header {
            position: absolute;
            top: 20px;
            left: 30px;
            right: 30px;
            display: flex;
            justify-content: space-between;
            align-items: flex-end;
            border-bottom: 1px solid var(--panel-border);
            padding-bottom: 10px;
            z-index: 10;
        }

        .title-box h1 {
            font-family: 'Orbitron', sans-serif;
            font-size: 24px;
            font-weight: 700;
            letter-spacing: 2px;
            color: var(--text-accent);
            text-transform: uppercase;
        }

        .title-box p {
            font-size: 12px;
            color: #64748b;
            margin-top: 4px;
        }

        /* 数据诊断面板 */
        .hud-panel {
            position: absolute;
            bottom: 30px;
            right: 30px;
            background: var(--panel-bg);
            backdrop-filter: blur(var(--data-blur));
            border: 1px solid var(--panel-border);
            padding: 20px;
            border-radius: 4px;
            width: 320px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.5);
            z-index: 10;
        }

        .data-row {
            display: flex;
            justify-content: space-between;
            margin-bottom: 12px;
            border-bottom: 1px dashed rgba(255,255,255,0.1);
            padding-bottom: 4px;
        }

        .data-label {
            color: #94a3b8;
            font-size: 14px;
        }

        .data-value {
            font-size: 18px;
            font-weight: bold;
            color: var(--text-accent);
            transition: color 0.3s;
            font-family: 'Orbitron', sans-serif;
        }

        .value-warn { color: var(--text-warn); }
        .value-safe { color: #39ff14; }

        /* 状态指示器 */
        .status-box {
            margin-top: 20px;
            padding: 10px;
            background: rgba(0, 0, 0, 0.4);
            border-left: 3px solid var(--text-accent);
            font-size: 13px;
            line-height: 1.5;
        }

        .status-type { color: var(--text-accent); font-weight: bold; }

        /* 动画主容器 */
        .anim-container {
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            padding: 80px 40px;
        }

        svg {
            width: 100%;
            height: 100%;
            max-width: 1200px;
            max-height: 700px;
            filter: drop-shadow(0 0 20px rgba(0,0,0,0.5));
        }

        /* SVG 内元素动效 */
        .cell-body {
            fill: var(--cell-color);
            transition: fill 0.3s ease;
            stroke: #334155;
            stroke-width: 2;
        }
        
        .pcm-material {
            fill: var(--pcm-color);
            transition: fill 0.5s ease;
            stroke: #0d9488;
            stroke-width: 1;
        }

        /* 流动的高压电流 */
        .power-line {
            fill: none;
            stroke: var(--text-accent);
            stroke-width: 4;
            stroke-dasharray: 10 20;
            opacity: var(--current-opacity);
            animation: flow var(--current-dash-speed) linear infinite;
        }

        @keyframes flow {
            to { stroke-dashoffset: -30; }
        }

        /* 扫描线效果 */
        .scanline {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 10px;
            background: linear-gradient(to bottom, transparent, rgba(0, 240, 255, 0.1), transparent);
            opacity: 0.5;
            animation: scan 8s linear infinite;
            pointer-events: none;
            z-index: 99;
        }

        @keyframes scan {
            0% { top: -10%; }
            100% { top: 110%; }
        }
        
        /* 十字准星装饰 */
        .crosshair {
            position: absolute;
            width: 20px;
            height: 20px;
            border-color: rgba(0, 240, 255, 0.3);
            border-style: solid;
            z-index: 1;
        }
        .ch-tl { top: 20%; left: 10%; border-width: 2px 0 0 2px; }
        .ch-tr { top: 20%; right: 10%; border-width: 2px 2px 0 0; }
        .ch-bl { bottom: 20%; left: 10%; border-width: 0 0 2px 2px; }
        .ch-br { bottom: 20%; right: 10%; border-width: 0 2px 2px 0; }
    </style>
</head>
<body>

    <div class="scanline"></div>
    
    <div class="crosshair ch-tl"></div>
    <div class="crosshair ch-tr"></div>
    <div class="crosshair ch-bl"></div>
    <div class="crosshair ch-br"></div>

    <header class="header">
        <div class="title-box">
            <h1>CTP Thermal Management IFR</h1>
            <p>PHASE-CHANGE MATERIAL HEAT ABSORPTION OVERRIDE (24S1P LFP)</p>
        </div>
        <div class="title-box" style="text-align: right;">
            <p style="color: var(--text-accent);">SYS_ACTIVE // AUTOLOOP_ENGAGED</p>
        </div>
    </header>

    <div class="anim-container">
        <!-- SVG 渲染核心模块 -->
        <svg viewBox="0 0 1000 500" preserveAspectRatio="xMidYMid meet">
            <defs>
                <!-- 发光滤镜 -->
                <filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
                    <feGaussianBlur stdDeviation="8" result="blur" />
                    <feComposite in="SourceGraphic" in2="blur" operator="over" />
                </filter>
                
                <!-- PCM 液化噪点纹理 -->
                <pattern id="pcm-pattern" width="20" height="20" patternUnits="userSpaceOnUse">
                    <rect width="20" height="20" fill="var(--pcm-color)" />
                    <circle cx="10" cy="10" r="1.5" fill="rgba(255,255,255,0.15)" />
                    <path d="M0,10 Q5,5 10,10 T20,10" fill="none" stroke="rgba(0,255,255,0.1)" stroke-width="1"/>
                </pattern>
                
                <!-- 发热粒子扩散效果(预留给相变吸热) -->
                <filter id="thermal-blur">
                    <feGaussianBlur stdDeviation="4" />
                </filter>
            </defs>

            <!-- 外层壳体 -->
            <rect x="50" y="50" width="900" height="400" rx="10" fill="none" stroke="#1e293b" stroke-width="4" />
            <text x="60" y="80" fill="#475569" font-size="14">BATTERY ENCLOSURE (CTP)</text>
            <path d="M 50 100 L 950 100" stroke="#1e293b" stroke-width="2" stroke-dasharray="5 5" />

            <!-- 生成电芯组和PCM材料 (局部展示 6块电芯 代表 24S1P) -->
            <!-- 整体组居中 -->
            <g transform="translate(100, 150)">
                <!-- 底部导电排连接线 -->
                <path class="power-line" d="M -50 200 L 800 200" />
                <path class="power-line" d="M -50 0 L 800 0" />

                <!-- 循环构建 6 个 Cell 和中间的 PCM -->
                <!-- Cell 1 -->
                <rect class="cell-body" x="0" y="20" width="100" height="160" rx="4" filter="drop-shadow(0 0 15px var(--cell-glow))"/>
                <text x="50" y="105" fill="#94a3b8" font-size="16" text-anchor="middle" font-family="Orbitron">CELL</text>
                <!-- PCM 1 -->
                <rect class="pcm-material" x="105" y="30" width="25" height="140" fill="url(#pcm-pattern)" filter="drop-shadow(0 0 20px var(--pcm-glow))" />
                
                <!-- Cell 2 -->
                <rect class="cell-body" x="135" y="20" width="100" height="160" rx="4" filter="drop-shadow(0 0 15px var(--cell-glow))"/>
                <text x="185" y="105" fill="#94a3b8" font-size="16" text-anchor="middle" font-family="Orbitron">CELL</text>
                <!-- PCM 2 -->
                <rect class="pcm-material" x="240" y="30" width="25" height="140" fill="url(#pcm-pattern)" filter="drop-shadow(0 0 20px var(--pcm-glow))" />

                <!-- Cell 3 -->
                <rect class="cell-body" x="270" y="20" width="100" height="160" rx="4" filter="drop-shadow(0 0 15px var(--cell-glow))"/>
                <text x="320" y="105" fill="#94a3b8" font-size="16" text-anchor="middle" font-family="Orbitron">CELL</text>
                <!-- PCM 3 -->
                <rect class="pcm-material" x="375" y="30" width="25" height="140" fill="url(#pcm-pattern)" filter="drop-shadow(0 0 20px var(--pcm-glow))" />

                <!-- Cell 4 -->
                <rect class="cell-body" x="405" y="20" width="100" height="160" rx="4" filter="drop-shadow(0 0 15px var(--cell-glow))"/>
                <text x="455" y="105" fill="#94a3b8" font-size="16" text-anchor="middle" font-family="Orbitron">CELL</text>
                <!-- PCM 4 -->
                <rect class="pcm-material" x="510" y="30" width="25" height="140" fill="url(#pcm-pattern)" filter="drop-shadow(0 0 20px var(--pcm-glow))" />

                <!-- Cell 5 -->
                <rect class="cell-body" x="540" y="20" width="100" height="160" rx="4" filter="drop-shadow(0 0 15px var(--cell-glow))"/>
                <text x="590" y="105" fill="#94a3b8" font-size="16" text-anchor="middle" font-family="Orbitron">CELL</text>
                <!-- PCM 5 -->
                <rect class="pcm-material" x="645" y="30" width="25" height="140" fill="url(#pcm-pattern)" filter="drop-shadow(0 0 20px var(--pcm-glow))" />

                <!-- Cell 6 -->
                <rect class="cell-body" x="675" y="20" width="100" height="160" rx="4" filter="drop-shadow(0 0 15px var(--cell-glow))"/>
                <text x="725" y="105" fill="#94a3b8" font-size="16" text-anchor="middle" font-family="Orbitron">CELL</text>

                <!-- 注释线条 -->
                <path d="M 117 10 L 117 -30 L 250 -30" stroke="#00f0ff" stroke-width="1" fill="none" opacity="0.6"/>
                <circle cx="117" cy="10" r="3" fill="#00f0ff" />
                <text x="260" y="-25" fill="#00f0ff" font-size="14" font-family="Share Tech Mono">GRAPHENE COMPOSITE PCM</text>
                <text x="260" y="-10" fill="#64748b" font-size="12">LATENT HEAT CAPACITY > 220 kJ/kg</text>
            </g>
        </svg>
    </div>

    <!-- 数据浮层 -->
    <div class="hud-panel">
        <div class="data-row">
            <span class="data-label">MODE</span>
            <span class="data-value" id="ui-mode">IDLE</span>
        </div>
        <div class="data-row">
            <span class="data-label">INPUT CURRENT</span>
            <span class="data-value" id="ui-current">0.0 A</span>
        </div>
        <div class="data-row">
            <span class="data-label">CELL TEMPERATURE</span>
            <span class="data-value" id="ui-temp">25.0 °C</span>
        </div>
        <div class="data-row">
            <span class="data-label">PCM STATE</span>
            <span class="data-value" id="ui-pcm">SOLID</span>
        </div>
        
        <div class="status-box">
            <div id="ui-desc" class="status-type">SYSTEM ONLINE</div>
            <div id="ui-detail" style="color: #64748b; font-size: 11px; margin-top: 5px;">Waiting for charge cycle...</div>
        </div>
    </div>

    <script>
        /**
         * 状态机与动画核心引擎
         * 完全实现前端隔离与自治的自动循环动画
         */
        document.addEventListener('DOMContentLoaded', () => {
            const root = document.documentElement;
            
            // UI 元素绑定
            const uiMode = document.getElementById('ui-mode');
            const uiCurrent = document.getElementById('ui-current');
            const uiTemp = document.getElementById('ui-temp');
            const uiPcm = document.getElementById('ui-pcm');
            const uiDesc = document.getElementById('ui-desc');
            const uiDetail = document.getElementById('ui-detail');

            // 物理常量模拟
            let currentTemp = 25.0;
            let currentAmp = 0.0;
            
            // 颜色插值函数 (Lerp color)
            function interpolateColor(color1, color2, factor) {
                const hex2rgb = hex => [
                    parseInt(hex.slice(1, 3), 16),
                    parseInt(hex.slice(3, 5), 16),
                    parseInt(hex.slice(5, 7), 16)
                ];
                const c1 = hex2rgb(color1);
                const c2 = hex2rgb(color2);
                const r = Math.round(c1[0] + factor * (c2[0] - c1[0]));
                const g = Math.round(c1[1] + factor * (c2[1] - c1[1]));
                const b = Math.round(c1[2] + factor * (c2[2] - c1[2]));
                return `rgb(${r}, ${g}, ${b})`;
            }

            // 更新 UI 和 CSS 变量
            function updateVisuals(temp, amp, stateStr, pcmStateStr, descStr, detailStr, pcmColorHex, pcmGlowColor) {
                // 更新数值文本
                uiTemp.textContent = temp.toFixed(1) + ' °C';
                uiCurrent.textContent = amp.toFixed(1) + ' A';
                uiMode.textContent = stateStr;
                uiPcm.textContent = pcmStateStr;
                uiDesc.textContent = descStr;
                uiDetail.textContent = detailStr;

                // 颜色和特效计算
                // 温度 25 到 45,冷色(#1e293b) 到 警告色(#ff3c00)
                let tempFactor = Math.max(0, Math.min(1, (temp - 25) / 20)); 
                let cellColor = interpolateColor('#1e293b', '#6b1000', tempFactor);
                let cellGlow = `rgba(255, 60, 0, ${tempFactor * 0.8})`;

                root.style.setProperty('--cell-color', cellColor);
                root.style.setProperty('--cell-glow', cellGlow);

                // PCM状态更新
                root.style.setProperty('--pcm-color', pcmColorHex);
                root.style.setProperty('--pcm-glow', pcmGlowColor);

                // 电流特效更新
                if (amp > 10) {
                    root.style.setProperty('--current-opacity', '1');
                    root.style.setProperty('--current-dash-speed', '0.5s'); // 极速流动
                } else {
                    root.style.setProperty('--current-opacity', '0.2');
                    root.style.setProperty('--current-dash-speed', '4s'); // 缓慢流动
                }

                // 阈值UI颜色警告
                if (temp >= 44.5) {
                    uiTemp.classList.add('value-warn');
                    uiPcm.classList.add('value-safe'); // PCM 救场高亮
                } else {
                    uiTemp.classList.remove('value-warn');
                    uiPcm.classList.remove('value-safe');
                }
            }

            // 关键帧Timeline引擎
            const timeline = [
                {
                    time: 0, 
                    duration: 2, 
                    update: (t) => {
                        currentTemp = 25;
                        currentAmp = 0;
                        updateVisuals(currentTemp, currentAmp, "STANDBY", "SOLID", "NATURAL COOLING", "System idle. Normal heat dissipation.", "#0f3a40", "rgba(0,0,0,0)");
                    }
                },
                {
                    time: 2, 
                    duration: 3, 
                    update: (t) => {
                        // 接入快充,电流瞬间飙升,温度快速线性上升
                        currentAmp = 230;
                        currentTemp = 25 + (20 * t); // 25 -> 45
                        updateVisuals(currentTemp, currentAmp, "DC FAST CHARGE", "SOLID", "JOULE HEATING RAPID", "1C/230A injected. Cell temp surging.", "#0f3a40", "rgba(0,0,0,0)");
                    }
                },
                {
                    time: 5, 
                    duration: 6, 
                    update: (t) => {
                        // PCM 触发,吸收潜热。温度锁定在 45-45.5 微小波动
                        currentAmp = 230;
                        currentTemp = 45 + Math.sin(t * 10) * 0.3; // 波动效果
                        
                        // PCM 从固态暗色变为高亮凝胶态,发荧光青色
                        let pcmGlowAlpha = 0.5 + Math.sin(t * 8) * 0.3; // 脉冲呼吸
                        updateVisuals(
                            currentTemp, currentAmp, 
                            "THERMAL OVERRIDE", "MICRO-GEL (ABSORBING)", 
                            "PCM PHASE CHANGE TRIGGERED", 
                            "Absorbing latent heat (>220 kJ/kg). Temp locked at 45°C limit.",
                            "#00f0ff", `rgba(0, 240, 255, ${pcmGlowAlpha})`
                        );
                    }
                },
                {
                    time: 11, 
                    duration: 4, 
                    update: (t) => {
                        // 快充结束,缓慢散热,PCM凝固放热
                        currentAmp = 0;
                        currentTemp = 45 - (15 * t); // 45 -> 30
                        
                        // PCM 回归暗色
                        let backFactor = 1 - t;
                        updateVisuals(
                            currentTemp, currentAmp, 
                            "COOLDOWN", "SOLIDIFYING", 
                            "HEAT DISSIPATION", 
                            "Charge complete. PCM slowly releasing stored thermal energy.",
                            interpolateColor('#0f3a40', '#00f0ff', backFactor),
                            `rgba(0, 240, 255, ${backFactor * 0.5})`
                        );
                    }
                }
            ];

            const totalDuration = timeline.reduce((acc, curr) => acc + curr.duration, 0);
            let startTime = null;

            function animate(timestamp) {
                if (!startTime) startTime = timestamp;
                let elapsedSec = (timestamp - startTime) / 1000;

                // 循环播放
                if (elapsedSec > totalDuration) {
                    startTime = timestamp;
                    elapsedSec = 0;
                }

                // 找到当前执行的关键阶段
                let accumulatedTime = 0;
                for (let i = 0; i < timeline.length; i++) {
                    let stage = timeline[i];
                    if (elapsedSec >= accumulatedTime && elapsedSec <= accumulatedTime + stage.duration) {
                        // 计算当前阶段的归一化时间 t (0.0 -> 1.0)
                        let localTime = elapsedSec - accumulatedTime;
                        let t = localTime / stage.duration;
                        stage.update(t);
                        break;
                    }
                    accumulatedTime += stage.duration;
                }

                requestAnimationFrame(animate);
            }

            // 启动引擎
            requestAnimationFrame(animate);
        });
    </script>
</body>
</html>
积分规则:第一轮对话扣减8分,后续每轮扣6分