分享图
动画工坊
引擎就绪
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>重载振动筛电液同步举升系统</title>
    <style>
        :root {
            --bg-color: #0b0e14;
            --grid-color: #1a2332;
            --text-main: #e2e8f0;
            --text-dim: #64748b;
            --accent-cyan: #00f0ff;
            --accent-amber: #ffaa00;
            --accent-red: #ff3366;
            --metal-light: #94a3b8;
            --metal-dark: #334155;
            --panel-bg: rgba(15, 23, 42, 0.7);
        }

        body, html {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            background-color: var(--bg-color);
            font-family: 'SF Pro Display', -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
            color: var(--text-main);
            overflow: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        #app-container {
            width: 100vw;
            height: 100vh;
            position: relative;
            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;
        }

        /* 绝对定位的 HUD 文字信息容器 - 严格遵守边缘放置规则 */
        .hud-container {
            position: absolute;
            padding: 24px 32px;
            pointer-events: none;
            z-index: 10;
        }

        .hud-top-left { top: 0; left: 0; }
        .hud-top-right { top: 0; right: 0; text-align: right; }
        .hud-bottom-left { bottom: 0; left: 0; }
        .hud-bottom-right { bottom: 0; right: 0; text-align: right; }

        .hud-title {
            font-size: 16px;
            font-weight: 700;
            letter-spacing: 2px;
            color: var(--text-main);
            margin: 0 0 8px 0;
            text-transform: uppercase;
        }

        .hud-subtitle {
            font-size: 12px;
            color: var(--accent-cyan);
            letter-spacing: 1px;
            margin: 0;
        }

        .hud-data-group {
            background: var(--panel-bg);
            border: 1px solid var(--metal-dark);
            border-radius: 6px;
            padding: 12px 16px;
            margin-top: 16px;
            backdrop-filter: blur(4px);
        }

        .data-row {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 6px;
            gap: 24px;
        }

        .data-row:last-child { margin-bottom: 0; }

        .data-label {
            font-size: 11px;
            color: var(--text-dim);
            text-transform: uppercase;
        }

        .data-value {
            font-family: 'SF Mono', Consolas, 'Liberation Mono', monospace;
            font-size: 14px;
            font-weight: 600;
            color: var(--accent-cyan);
        }

        .data-value.amber { color: var(--accent-amber); }
        
        .triz-callout {
            font-size: 12px;
            color: var(--text-dim);
            max-width: 280px;
            line-height: 1.6;
            margin-top: 12px;
            border-left: 2px solid var(--accent-amber);
            padding-left: 12px;
        }

        .triz-highlight { color: var(--accent-amber); font-weight: bold; }

        /* SVG 核心动画区域 */
        #svg-canvas {
            width: 100%;
            height: 100%;
            display: block;
        }

        /* 动画元素样式 */
        .fluid-path {
            stroke: var(--metal-dark);
            stroke-width: 6;
            fill: none;
            stroke-linecap: round;
        }

        .fluid-flow {
            stroke: var(--accent-cyan);
            stroke-width: 4;
            fill: none;
            stroke-linecap: round;
            stroke-dasharray: 8 12;
            opacity: 0.1;
            transition: opacity 0.3s;
        }

        .fluid-flow.active-up {
            opacity: 1;
            animation: flowAnimUp 0.8s linear infinite;
        }
        
        .fluid-flow.active-down {
            opacity: 1;
            animation: flowAnimDown 0.8s linear infinite;
        }

        @keyframes flowAnimUp { to { stroke-dashoffset: -20; } }
        @keyframes flowAnimDown { to { stroke-dashoffset: 20; } }

        .data-path {
            stroke: #332b1a;
            stroke-width: 2;
            fill: none;
        }

        .data-pulse {
            stroke: var(--accent-amber);
            stroke-width: 2;
            fill: none;
            stroke-dasharray: 4 8;
            opacity: 0.2;
        }

        .data-pulse.active {
            opacity: 1;
            animation: pulseAnim 0.5s linear infinite;
        }

        @keyframes pulseAnim { to { stroke-dashoffset: -12; } }

        .plc-indicator {
            fill: var(--metal-dark);
            transition: fill 0.2s;
        }
        .plc-indicator.active { fill: var(--accent-amber); }

    </style>
</head>
<body>

<div id="app-container">
    <!-- 边缘 HUD 界面 (文字精简,放置角落) -->
    <div class="hud-container hud-top-left">
        <h1 class="hud-title">重载振动筛系统</h1>
        <p class="hud-subtitle">电液比例闭环同步举升方案</p>
        <div class="triz-callout">
            <span class="triz-highlight">理想最终解 (IFR):</span><br>
            直接利用系统内位移传感器数据,通过 PLC 闭环微调比例阀,在极简机械结构下实现消除偏载的理想绝对同步。
        </div>
    </div>

    <div class="hud-container hud-top-right">
        <div class="hud-data-group">
            <div class="data-row">
                <span class="data-label">系统状态</span>
                <span class="data-value" id="sys-status">INITIALIZING</span>
            </div>
            <div class="data-row">
                <span class="data-label">主泵输出</span>
                <span class="data-value" id="pump-power">0.0 kW</span>
            </div>
        </div>
    </div>

    <div class="hud-container hud-bottom-left">
        <div class="hud-data-group">
            <div class="data-row">
                <span class="data-label">PLC 控制周期</span>
                <span class="data-value">2ms (闭环)</span>
            </div>
            <div class="data-row">
                <span class="data-label">动态同步误差</span>
                <span class="data-value amber" id="sync-error">0.00 mm</span>
            </div>
            <div class="data-row">
                <span class="data-label">误差阈值限制</span>
                <span class="data-value">≤ 0.50 mm</span>
            </div>
        </div>
    </div>

    <div class="hud-container hud-bottom-right">
        <div class="hud-data-group">
            <div class="data-row">
                <span class="data-label">当前举升行程</span>
                <span class="data-value" id="stroke-val">0.0 mm</span>
            </div>
            <div class="data-row">
                <span class="data-label">目标行程</span>
                <span class="data-value">150.0 mm</span>
            </div>
            <div class="data-row">
                <span class="data-label">实时举升推力</span>
                <span class="data-value">2 × <span id="force-val">0.0</span> kN</span>
            </div>
        </div>
    </div>

    <!-- 中央核心 SVG 动画区域 -->
    <svg id="svg-canvas" viewBox="0 0 1600 900" preserveAspectRatio="xMidYMid meet">
        <defs>
            <!-- 材质渐变 -->
            <linearGradient id="metal-grad" x1="0%" y1="0%" x2="0%" y2="100%">
                <stop offset="0%" stop-color="#475569" />
                <stop offset="50%" stop-color="#94a3b8" />
                <stop offset="100%" stop-color="#334155" />
            </linearGradient>
            <linearGradient id="cylinder-grad" x1="0%" y1="0%" x2="100%" y2="0%">
                <stop offset="0%" stop-color="#1e293b" />
                <stop offset="20%" stop-color="#475569" />
                <stop offset="80%" stop-color="#334155" />
                <stop offset="100%" stop-color="#0f172a" />
            </linearGradient>
            <linearGradient id="piston-grad" x1="0%" y1="0%" x2="100%" y2="0%">
                <stop offset="0%" stop-color="#cbd5e1" />
                <stop offset="50%" stop-color="#f8fafc" />
                <stop offset="100%" stop-color="#94a3b8" />
            </linearGradient>
            <linearGradient id="gold-grad" x1="0%" y1="0%" x2="100%" y2="100%">
                <stop offset="0%" stop-color="#fbbf24" />
                <stop offset="100%" stop-color="#d97706" />
            </linearGradient>
            
            <!-- 发光滤镜 -->
            <filter id="glow-cyan" x="-20%" y="-20%" width="140%" height="140%">
                <feGaussianBlur stdDeviation="6" result="blur" />
                <feComposite in="SourceGraphic" in2="blur" operator="over" />
            </filter>
            <filter id="glow-amber" x="-20%" y="-20%" width="140%" height="140%">
                <feGaussianBlur stdDeviation="4" result="blur" />
                <feComposite in="SourceGraphic" in2="blur" operator="over" />
            </filter>
            
            <!-- 振动筛内部桁架模式 -->
            <pattern id="truss-pattern" width="40" height="40" patternUnits="userSpaceOnUse">
                <path d="M0,0 L40,40 M40,0 L0,40" stroke="#334155" stroke-width="2" opacity="0.5"/>
            </pattern>
        </defs>

        <!-- 背景网格修饰 (仅在中央区域提供空间感) -->
        <g opacity="0.3">
            <line x1="800" y1="100" x2="800" y2="800" stroke="var(--metal-dark)" stroke-width="1" stroke-dasharray="10 10"/>
            <line x1="400" y1="450" x2="1200" y2="450" stroke="var(--metal-dark)" stroke-width="1" stroke-dasharray="10 10"/>
        </g>

        <!-- ================= 液压管路系统 ================= -->
        <g id="plumbing">
            <!-- 静态管道 -->
            <path class="fluid-path" d="M 800,750 L 800,660" /> <!-- 泵到阀 -->
            <path class="fluid-path" d="M 770,630 L 500,630 L 500,670" /> <!-- 阀到左缸 -->
            <path class="fluid-path" d="M 830,630 L 1100,630 L 1100,670" /> <!-- 阀到右缸 -->
            
            <!-- 动态流体液 (应用滤镜产生发光效果) -->
            <g filter="url(#glow-cyan)">
                <path class="fluid-flow fluid-pump" d="M 800,750 L 800,660" />
                <path class="fluid-flow fluid-left" d="M 770,630 L 500,630 L 500,670" />
                <path class="fluid-flow fluid-right" d="M 830,630 L 1100,630 L 1100,670" />
            </g>
        </g>

        <!-- ================= 数据反馈网络 (核心创新点展示) ================= -->
        <g id="data-network">
            <!-- 静态线缆 -->
            <path class="data-path" d="M 440,550 L 300,550 L 300,720 L 400,720" /> <!-- 左位移传感器到PLC -->
            <path class="data-path" d="M 1160,550 L 1300,550 L 1300,850 L 300,850 L 300,740 L 400,740" /> <!-- 右位移传感器到PLC -->
            <path class="data-path" d="M 460,690 L 460,630 L 760,630" /> <!-- PLC到比例阀控制线 -->

            <!-- 动态数据脉冲 -->
            <g filter="url(#glow-amber)">
                <path class="data-pulse sensor-l" d="M 440,550 L 300,550 L 300,720 L 400,720" />
                <path class="data-pulse sensor-r" d="M 1160,550 L 1300,550 L 1300,850 L 300,850 L 300,740 L 400,740" />
                <path class="data-pulse control-v" d="M 460,690 L 460,630 L 760,630" />
            </g>
        </g>

        <!-- ================= 固定基座与组件 ================= -->
        
        <!-- PLC 闭环控制器 -->
        <g transform="translate(400, 680)">
            <rect x="0" y="0" width="80" height="100" rx="4" fill="#1e293b" stroke="var(--metal-dark)" stroke-width="2"/>
            <text x="40" y="25" fill="var(--text-main)" font-size="14" font-weight="bold" text-anchor="middle">PLC</text>
            <text x="40" y="40" fill="var(--text-dim)" font-size="10" text-anchor="middle">SYNC CTRL</text>
            <!-- 状态指示灯 -->
            <circle cx="20" cy="65" r="4" class="plc-indicator plc-l" />
            <circle cx="40" cy="65" r="4" class="plc-indicator plc-r" />
            <circle cx="60" cy="65" r="4" class="plc-indicator plc-out" />
            <text x="40" y="85" fill="var(--accent-amber)" font-size="10" font-family="monospace" text-anchor="middle" filter="url(#glow-amber)">CLOSED LOOP</text>
        </g>

        <!-- 液压动力单元 (泵站) -->
        <g transform="translate(750, 750)">
            <rect x="0" y="0" width="100" height="70" rx="6" fill="#1e293b" stroke="var(--metal-dark)" stroke-width="2"/>
            <rect x="25" y="-15" width="50" height="15" fill="url(#metal-grad)"/>
            <circle cx="50" cy="35" r="20" fill="#0f172a" stroke="var(--metal-dark)" stroke-width="2"/>
            <path d="M40,35 L60,25 L60,45 Z" fill="var(--metal-light)"/>
            <text x="110" y="30" fill="var(--text-main)" font-size="12">3kW</text>
            <text x="110" y="45" fill="var(--text-dim)" font-size="10">防爆电机泵站</text>
        </g>

        <!-- 比例换向阀 -->
        <g transform="translate(760, 610)">
            <rect x="0" y="0" width="80" height="50" fill="url(#metal-grad)" stroke="#0f172a" stroke-width="2"/>
            <!-- 阀芯示意 (会随信号稍微左右移动以体现微调) -->
            <rect id="valve-spool" x="25" y="10" width="30" height="30" fill="#cbd5e1" stroke="#334155"/>
            <path id="valve-arrow-left" d="M30,25 L40,15 M30,25 L40,35" stroke="#334155" stroke-width="2" fill="none"/>
            <path id="valve-arrow-right" d="M50,25 L40,15 M50,25 L40,35" stroke="#334155" stroke-width="2" fill="none"/>
            <text x="-10" y="30" fill="var(--accent-cyan)" font-size="10" text-anchor="end">比例阀</text>
        </g>

        <!-- 左右液压缸缸体 -->
        <g id="cylinders">
            <!-- 左缸基座 -->
            <rect x="470" y="670" width="60" height="10" fill="url(#metal-grad)"/>
            <rect x="475" y="450" width="50" height="220" fill="url(#cylinder-grad)" stroke="#0f172a" stroke-width="2"/>
            <!-- 左位移传感器 (固定在外壳) -->
            <rect x="430" y="450" width="20" height="200" fill="#1e293b" stroke="#334155"/>
            <text x="400" y="480" fill="var(--accent-amber)" font-size="10" text-anchor="end">位移传感器</text>
            <path d="M 450,550 L 440,550" stroke="var(--accent-amber)" stroke-width="2"/>

            <!-- 右缸基座 -->
            <rect x="1070" y="670" width="60" height="10" fill="url(#metal-grad)"/>
            <rect x="1075" y="450" width="50" height="220" fill="url(#cylinder-grad)" stroke="#0f172a" stroke-width="2"/>
            <!-- 右位移传感器 -->
            <rect x="1150" y="450" width="20" height="200" fill="#1e293b" stroke="#334155"/>
            <text x="1200" y="480" fill="var(--accent-amber)" font-size="10" text-anchor="start">位移传感器</text>
            <path d="M 1150,550 L 1160,550" stroke="var(--accent-amber)" stroke-width="2"/>
        </g>

        <!-- ================= 动态移动部分 ================= -->
        <g id="moving-assembly">
            <!-- 左右活塞杆 (高度受 JS 控制) -->
            <!-- 基础 Y = 450, 行程 150 -> 最高处 Y = 300, Height = 150 -->
            <rect id="piston-l" x="487.5" y="400" width="25" height="50" fill="url(#piston-grad)" stroke="#64748b" stroke-width="1"/>
            <rect id="piston-r" x="1087.5" y="400" width="25" height="50" fill="url(#piston-grad)" stroke="#64748b" stroke-width="1"/>
            
            <!-- 传感器游标 (跟随活塞移动) -->
            <rect id="sensor-slider-l" x="435" y="400" width="10" height="20" fill="url(#gold-grad)"/>
            <rect id="sensor-slider-r" x="1155" y="400" width="10" height="20" fill="url(#gold-grad)"/>

            <!-- 重载振动筛架 (随活塞整体平移) -->
            <!-- 使用组并 translate 控制整个大体积部件 -->
            <g id="screen-frame" transform="translate(0, 0)">
                <!-- 筛架主体, 绘制大型桁架结构以体现"重载" -->
                <path d="M 380,400 L 1220,400 L 1180,300 L 420,300 Z" fill="url(#metal-grad)" stroke="#0f172a" stroke-width="3"/>
                <!-- 内部花纹/桁架线 -->
                <path d="M 380,400 L 1220,400 L 1180,300 L 420,300 Z" fill="url(#truss-pattern)"/>
                
                <line x1="420" y1="300" x2="1180" y2="400" stroke="#334155" stroke-width="4"/>
                <line x1="1180" y1="300" x2="420" y2="400" stroke="#334155" stroke-width="4"/>
                <line x1="800" y1="300" x2="800" y2="400" stroke="#334155" stroke-width="6"/>
                
                <!-- 顶部平台 -->
                <rect x="350" y="280" width="900" height="20" rx="4" fill="url(#metal-grad)" stroke="#1e293b" stroke-width="2"/>
                <!-- 重物/筛料示意 -->
                <path d="M 400,280 Q 800,200 1200,280 Z" fill="#475569" opacity="0.4"/>
                
                <text x="800" y="360" fill="#fff" font-size="24" font-weight="900" letter-spacing="4" text-anchor="middle" style="text-shadow: 0 2px 4px rgba(0,0,0,0.8);">重载振动筛架</text>
                
                <!-- 活塞连接点 -->
                <rect x="470" y="400" width="60" height="15" fill="#1e293b"/>
                <rect x="1070" y="400" width="60" height="15" fill="#1e293b"/>
                <!-- 举升力标注 -->
                <g transform="translate(430, 320)">
                    <path d="M 0,30 L 0,-20 M -10,-10 L 0,-20 L 10,-10" stroke="var(--accent-red)" stroke-width="3" fill="none"/>
                    <text x="-15" y="-5" fill="var(--accent-red)" font-size="14" font-weight="bold">F</text>
                </g>
                <g transform="translate(1170, 320)">
                    <path d="M 0,30 L 0,-20 M -10,-10 L 0,-20 L 10,-10" stroke="var(--accent-red)" stroke-width="3" fill="none"/>
                    <text x="5" y="-5" fill="var(--accent-red)" font-size="14" font-weight="bold">F</text>
                </g>
            </g>
        </g>
    </svg>
</div>

<script>
    // 确保页面加载完成后,动画自动无感启动并循环
    window.addEventListener('DOMContentLoaded', () => {
        
        // 动画参数配置
        const DURATION_UP = 4000;    // 上升耗时 (ms)
        const DURATION_HOLD_UP = 2000; // 顶部保持耗时 (ms)
        const DURATION_DOWN = 3500;  // 下降耗时 (ms)
        const DURATION_IDLE = 1000;  // 底部空闲耗时 (ms)
        
        const MAX_STROKE_MM = 150;     // 物理行程要求
        const PIXEL_STROKE = 150;      // SVG中活塞伸出的像素高度
        const MAX_FORCE = 40.0;        // 最大推力 kN
        
        const TOTAL_CYCLE = DURATION_UP + DURATION_HOLD_UP + DURATION_DOWN + DURATION_IDLE;

        // DOM 元素引用
        const dom = {
            frame: document.getElementById('screen-frame'),
            pistonL: document.getElementById('piston-l'),
            pistonR: document.getElementById('piston-r'),
            sensorL: document.getElementById('sensor-slider-l'),
            sensorR: document.getElementById('sensor-slider-r'),
            valveSpool: document.getElementById('valve-spool'),
            
            // 文本状态
            sysStatus: document.getElementById('sys-status'),
            pumpPower: document.getElementById('pump-power'),
            syncError: document.getElementById('sync-error'),
            strokeVal: document.getElementById('stroke-val'),
            forceVal: document.getElementById('force-val'),
            
            // 动效线缆
            fluidFlows: document.querySelectorAll('.fluid-flow'),
            dataPulses: document.querySelectorAll('.data-pulse'),
            plcInds: document.querySelectorAll('.plc-indicator')
        };

        const basePistonY = 400; // 活塞初始Y坐标 (活塞顶部)
        const basePistonH = 50;  // 活塞初始伸出高度

        let startTime = Date.now();

        // 平滑缓动函数 (Ease In Out Quad)
        function easeInOutQuad(t) {
            return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
        }

        // 格式化数字
        function fmt(num, decimals) {
            return num.toFixed(decimals);
        }

        // 核心动画循环
        function animateFrame() {
            let elapsed = (Date.now() - startTime) % TOTAL_CYCLE;
            
            let progress = 0;   // 0.0 到 1.0 的举升进度
            let state = '';
            let flowDir = 0;    // 1: 上, -1: 下, 0: 停
            let currentForce = 0;
            let dynamicError = 0; // 模拟同步误差 (重点展示 IFR 闭环控制)

            // 1. 状态机判断与参数计算
            if (elapsed < DURATION_IDLE) {
                // 待机状态
                progress = 0;
                state = 'READY / IDLE';
                flowDir = 0;
                currentForce = 0;
                dynamicError = 0;
            } 
            else if (elapsed < DURATION_IDLE + DURATION_UP) {
                // 举升状态
                let p = (elapsed - DURATION_IDLE) / DURATION_UP;
                progress = easeInOutQuad(p);
                state = 'ACTIVE LIFTING';
                flowDir = 1;
                currentForce = MAX_FORCE;
                // 模拟闭环调控中的微小跳动 (展示由于闭环作用,误差被严格限制在 0.5mm 内)
                dynamicError = (Math.random() * 0.35 + 0.05).toFixed(2);
            }
            else if (elapsed < DURATION_IDLE + DURATION_UP + DURATION_HOLD_UP) {
                // 顶部保压状态
                progress = 1;
                state = 'HOLD POSITION';
                flowDir = 0;
                currentForce = MAX_FORCE * 0.7; // 保压所需力较小
                dynamicError = "0.00"; // 绝对稳定
            }
            else {
                // 回程下降状态
                let p = (elapsed - (DURATION_IDLE + DURATION_UP + DURATION_HOLD_UP)) / DURATION_DOWN;
                progress = 1 - easeInOutQuad(p);
                state = 'RETRACTING';
                flowDir = -1;
                currentForce = MAX_FORCE * 0.1;
                dynamicError = (Math.random() * 0.2).toFixed(2);
            }

            // 2. 更新 SVG 图形变换
            
            // 筛架整体平移 (往上为负Y)
            let currentOffset = progress * PIXEL_STROKE;
            dom.frame.setAttribute('transform', `translate(0, -${currentOffset})`);
            
            // 活塞杆伸长 (Y变小,Height变大,确保底部固定)
            dom.pistonL.setAttribute('y', basePistonY - currentOffset);
            dom.pistonL.setAttribute('height', basePistonH + currentOffset);
            dom.pistonR.setAttribute('y', basePistonY - currentOffset);
            dom.pistonR.setAttribute('height', basePistonH + currentOffset);
            
            // 传感器游标移动
            dom.sensorL.setAttribute('y', basePistonY - currentOffset);
            dom.sensorR.setAttribute('y', basePistonY - currentOffset);

            // 比例阀阀芯微调演示 (当有动态误差时,阀芯轻微抖动代表 PLC 在干预)
            if (flowDir !== 0 && dynamicError > 0.1) {
                let jitter = (Math.random() - 0.5) * 4;
                dom.valveSpool.setAttribute('transform', `translate(${jitter}, 0)`);
            } else {
                dom.valveSpool.setAttribute('transform', `translate(0, 0)`);
            }

            // 3. 更新流体及数据线缆的 CSS 类 (控制流动特效)
            if (flowDir === 1) {
                dom.fluidFlows.forEach(el => {
                    el.classList.add('active-up');
                    el.classList.remove('active-down');
                });
            } else if (flowDir === -1) {
                dom.fluidFlows.forEach(el => {
                    el.classList.add('active-down');
                    el.classList.remove('active-up');
                });
            } else {
                dom.fluidFlows.forEach(el => {
                    el.classList.remove('active-up', 'active-down');
                });
            }

            // 只要系统不在 IDLE,闭环反馈就一直在工作 (脉冲和指示灯点亮)
            if (state !== 'READY / IDLE') {
                dom.dataPulses.forEach(el => el.classList.add('active'));
                dom.plcInds.forEach(el => el.classList.add('active'));
            } else {
                dom.dataPulses.forEach(el => el.classList.remove('active'));
                dom.plcInds.forEach(el => el.classList.remove('active'));
            }

            // 4. 更新 HUD 文本数据
            dom.sysStatus.textContent = state;
            dom.strokeVal.textContent = fmt(progress * MAX_STROKE_MM, 1) + ' mm';
            dom.forceVal.textContent = fmt(currentForce, 1);
            dom.pumpPower.textContent = flowDir === 1 ? '3.0 kW' : (flowDir === 0 && state === 'HOLD POSITION' ? '1.2 kW' : '0.0 kW');
            
            // 误差告警色控制
            dom.syncError.textContent = (flowDir === 0 && progress === 0) ? '0.00 mm' : dynamicError + ' mm';
            if (parseFloat(dynamicError) > 0.4) {
                dom.syncError.style.color = 'var(--accent-red)';
            } else {
                dom.syncError.style.color = 'var(--accent-amber)';
            }

            // 递归调用下一帧
            requestAnimationFrame(animateFrame);
        }

        // 启动动画循环
        requestAnimationFrame(animateFrame);
    });
</script>

</body>
</html>
积分规则:每轮对话扣10分