分享图
动画工坊
引擎就绪
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>独立夹持与剪切解耦系统原理演示</title>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700;800&display=swap');

        :root {
            --bg-color: #03070e;
            --grid-color: rgba(0, 240, 255, 0.07);
            --cyan-main: #00f0ff;
            --cyan-dim: rgba(0, 240, 255, 0.3);
            --red-alert: #ff2a4a;
            --green-safe: #00ff66;
            --mech-dark: #0b1120;
            --mech-border: #1e293b;
            --material-color: #f8fafc;
        }

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

        body {
            background-color: var(--bg-color);
            color: var(--cyan-main);
            font-family: 'JetBrains Mono', monospace;
            height: 100vh;
            overflow: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
            /* 工业蓝图网格背景 */
            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 {
            position: absolute;
            font-size: 11px;
            line-height: 1.6;
            pointer-events: none;
            z-index: 100;
            text-transform: uppercase;
            letter-spacing: 1px;
        }

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

        .hud-title {
            font-weight: 800;
            font-size: 14px;
            margin-bottom: 8px;
            color: #fff;
            text-shadow: 0 0 10px var(--cyan-dim);
        }

        .hud-value { color: #fff; font-weight: 700; }
        .hud-highlight { color: var(--green-safe); }
        .hud-warning { color: var(--red-alert); }

        /* 中心动画容器 - 占据最大空间 */
        .stage {
            position: relative;
            width: 800px;
            height: 400px;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        /* 参考线 */
        .axis-line {
            position: absolute;
            background: rgba(0, 240, 255, 0.15);
        }
        .axis-x { width: 100%; height: 1px; top: 50%; left: 0; }
        .axis-y-1 { height: 100%; width: 1px; left: 30%; top: 0; border-left: 1px dashed var(--cyan-dim); background: transparent; }
        .axis-y-2 { height: 100%; width: 1px; left: 70%; top: 0; border-left: 1px dashed rgba(255, 42, 74, 0.3); background: transparent; }

        /* 被处理物料 */
        .material-container {
            position: absolute;
            width: 600px;
            height: 16px;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            display: flex;
            z-index: 10;
        }

        .material-core {
            height: 100%;
            background: linear-gradient(90deg, #94a3b8, #f8fafc, #94a3b8);
            box-shadow: 0 0 15px rgba(255,255,255,0.2);
            border-radius: 2px;
        }

        .material-left { width: 70%; transform-origin: left center; }
        .material-right { 
            width: 30%; 
            transform-origin: left center; 
            /* 切断时的物理掉落过渡 */
            transition: transform 0.6s cubic-bezier(0.5, 0, 1, 1), opacity 0.5s ease; 
        }

        /* 独立系统 1: 夹持模块 (左侧) */
        .module-clamp {
            position: absolute;
            left: calc(50% - 160px);
            top: 50%;
            width: 120px;
            height: 200px;
            transform: translateY(-50%);
            z-index: 20;
        }

        .jaw {
            position: absolute;
            width: 100%;
            height: 60px;
            background: var(--mech-dark);
            border: 2px solid var(--cyan-main);
            box-shadow: inset 0 0 20px rgba(0, 240, 255, 0.1);
            display: flex;
            align-items: center;
            justify-content: center;
            /* 夹持动作转换干脆利落 */
            transition: transform 0.15s cubic-bezier(0.1, 1, 0, 1);
        }
        
        .jaw::after {
            content: '';
            position: absolute;
            width: 80%;
            height: 6px;
            background: repeating-linear-gradient(45deg, transparent, transparent 5px, var(--cyan-dim) 5px, var(--cyan-dim) 10px);
        }

        .jaw-top { top: -20px; transform: translateY(-80px); border-bottom: 4px solid var(--cyan-main); }
        .jaw-bottom { bottom: -20px; transform: translateY(80px); border-top: 4px solid var(--cyan-main); }
        .jaw-top::after { bottom: 0; }
        .jaw-bottom::after { top: 0; }

        /* 传感器扫描场 (夹持与剪切之间) */
        .sensor-field {
            position: absolute;
            left: calc(50% - 20px);
            top: 50%;
            width: 140px;
            height: 120px;
            transform: translateY(-50%);
            border: 1px solid transparent;
            z-index: 15;
            overflow: hidden;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        .laser-beam {
            position: absolute;
            top: 0;
            left: 0;
            width: 2px;
            height: 100%;
            background: var(--green-safe);
            box-shadow: 0 0 15px var(--green-safe), 0 0 30px var(--green-safe);
            transform: translateX(0);
        }

        .scan-grid {
            position: absolute;
            width: 100%;
            height: 100%;
            background-image: linear-gradient(var(--green-safe) 1px, transparent 1px);
            background-size: 100% 10px;
            opacity: 0.1;
        }

        /* 独立系统 2: 剪切模块 (右侧) */
        .module-shear {
            position: absolute;
            left: calc(50% + 140px);
            top: 50%;
            width: 40px;
            height: 300px;
            transform: translateY(-50%);
            z-index: 25;
        }

        .blade-housing {
            position: absolute;
            width: 100%;
            height: 100%;
            border-left: 2px solid var(--mech-border);
            border-right: 2px solid var(--mech-border);
            background: rgba(11, 17, 32, 0.5);
        }

        .blade {
            position: absolute;
            top: 0;
            width: 60px;
            left: -10px;
            height: 80px;
            background: var(--mech-dark);
            border: 2px solid var(--red-alert);
            border-bottom: 6px solid var(--red-alert);
            box-shadow: 0 5px 20px rgba(255, 42, 74, 0.4);
            /* 剪切动作极其干脆、暴力 */
            transform: translateY(-100px);
            transition: transform 0s; 
        }

        .blade::before {
            content: '';
            position: absolute;
            bottom: -15px;
            left: -2px;
            width: 0;
            height: 0;
            border-left: 30px solid transparent;
            border-right: 30px solid transparent;
            border-top: 15px solid var(--red-alert);
        }

        /* 状态控制类 */
        .state-clamping .jaw-top { transform: translateY(12px); }
        .state-clamping .jaw-bottom { transform: translateY(-12px); }
        
        .state-sensing .sensor-field { opacity: 1; border-color: rgba(0, 255, 102, 0.2); }
        
        /* 切割瞬间使用类来触发 CSS transition */
        .state-shearing .blade {
            transform: translateY(145px); /* 切断位置 */
            transition: transform 0.05s cubic-bezier(1, 0, 1, 1); /* 极快落下 */
        }
        
        .state-retracting .blade {
            transform: translateY(-100px);
            transition: transform 0.4s cubic-bezier(0.1, 1, 0, 1); /* 快速回弹 */
        }

        .state-cut .material-right {
            transform: translate(20px, 150px) rotate(15deg);
            opacity: 0;
        }

        .state-feed .material-container {
            transform: translate(-150%, -50%);
            transition: none;
        }
        .state-feeding .material-container {
            transform: translate(-50%, -50%);
            transition: transform 0.8s cubic-bezier(0.1, 1, 0, 1);
        }
        
        /* 扫描动画通过 JS 控制或 CSS 动画 */
        @keyframes scanMotion {
            0% { transform: translateX(0); }
            50% { transform: translateX(138px); }
            100% { transform: translateX(0); }
        }
        .is-scanning .laser-beam {
            animation: scanMotion 1.5s infinite ease-in-out;
        }

    </style>
</head>
<body>

    <!-- 左上角 HUD -->
    <div class="hud hud-top-left">
        <div class="hud-title">DECOUPLED KINETICS SYS</div>
        <div>Engine: <span class="hud-highlight">ONLINE</span></div>
        <div>Mode: <span class="hud-value">Asynchronous</span></div>
        <div style="margin-top: 10px; color: var(--cyan-dim);">
            SYS.1: CLAMP_AND_HOLD<br>
            SYS.2: INDEPENDENT_SHEAR
        </div>
    </div>

    <!-- 右上角 HUD -->
    <div class="hud hud-top-right">
        <div>System Clock: <span id="clock" class="hud-value">00:00:00:000</span></div>
        <div>Cycle Count: <span id="cycle-count" class="hud-value">0000</span></div>
        <div style="margin-top: 10px;">
            Action Transtion: <span class="hud-highlight">CRISP</span>
        </div>
    </div>

    <!-- 左下角 HUD -->
    <div class="hud hud-bottom-left">
        <div>[ SENSOR TELEMETRY ]</div>
        <div>Status: <span id="sensor-status">STANDBY</span></div>
        <div>Detection Time: <span id="detect-time" class="hud-highlight">0.00s</span></div>
        <div style="color: var(--cyan-dim); margin-top: 5px;">* Time infinitely extendable due to decoupling</div>
    </div>

    <!-- 右下角 HUD -->
    <div class="hud hud-bottom-right">
        <div>[ SEQUENCE LOG ]</div>
        <div id="seq-log-3" style="color: var(--cyan-dim);">SYS INIT</div>
        <div id="seq-log-2" style="color: rgba(0,240,255,0.6);">WAITING FOR MAT</div>
        <div id="seq-log-1" class="hud-value">> ENGAGING LOOP</div>
    </div>

    <!-- 核心动画舞台 -->
    <div class="stage" id="stage">
        <!-- 装饰轴线 -->
        <div class="axis-line axis-x"></div>
        <div class="axis-line axis-y-1"></div>
        <div class="axis-line axis-y-2"></div>

        <!-- 物料 -->
        <div class="material-container" id="material">
            <div class="material-core material-left"></div>
            <div class="material-core material-right" id="material-right"></div>
        </div>

        <!-- 系统1: 夹持模块 -->
        <div class="module-clamp" id="module-clamp">
            <div class="jaw jaw-top"></div>
            <div class="jaw jaw-bottom"></div>
        </div>

        <!-- 传感器阵列 (位于夹持后部) -->
        <div class="sensor-field" id="sensor-field">
            <div class="scan-grid"></div>
            <div class="laser-beam" id="laser"></div>
        </div>

        <!-- 系统2: 剪切模块 -->
        <div class="module-shear" id="module-shear">
            <div class="blade-housing"></div>
            <div class="blade" id="blade"></div>
        </div>
    </div>

    <script>
        // DOM Elements
        const stage = document.getElementById('stage');
        const materialContainer = document.getElementById('material');
        const materialRight = document.getElementById('material-right');
        const sensorField = document.getElementById('sensor-field');
        const clockEl = document.getElementById('clock');
        const cycleEl = document.getElementById('cycle-count');
        const sensorStatusEl = document.getElementById('sensor-status');
        const detectTimeEl = document.getElementById('detect-time');
        const logs = [
            document.getElementById('seq-log-3'),
            document.getElementById('seq-log-2'),
            document.getElementById('seq-log-1')
        ];

        let cycleCount = 0;
        let detectionStartTime = 0;
        let detectionTimer = null;
        let globalTime = 0;

        // HUD 运行时钟
        setInterval(() => {
            globalTime += 16;
            const ms = globalTime % 1000;
            const s = Math.floor(globalTime / 1000) % 60;
            const m = Math.floor(globalTime / 60000);
            clockEl.innerText = `${m.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}:${ms.toString().padStart(3,'0')}`;
        }, 16);

        // HUD 日志更新
        function log(msg, type = 'normal') {
            logs[0].innerText = logs[1].innerText;
            logs[0].style.color = logs[1].style.color;
            logs[1].innerText = logs[2].innerText;
            logs[1].style.color = logs[2].style.color;
            logs[2].innerText = `> ${msg}`;
            
            if(type === 'alert') logs[2].style.color = 'var(--red-alert)';
            else if(type === 'safe') logs[2].style.color = 'var(--green-safe)';
            else logs[2].style.color = '#fff';
        }

        // 等待函数
        const delay = ms => new Promise(res => setTimeout(res, ms));

        // 核心解耦控制逻辑状态机
        async function runEngineCycle() {
            cycleCount++;
            cycleEl.innerText = cycleCount.toString().padStart(4, '0');

            // 1. 送料阶段
            log("PHASE 1: MATERIAL FEEDING");
            stage.className = 'stage state-feed'; 
            materialRight.style.transition = 'none';
            materialRight.style.opacity = '1';
            materialRight.style.transform = 'translate(0, 0) rotate(0deg)';
            await delay(50);
            stage.className = 'stage state-feeding';
            await delay(800);

            // 2. 独立夹持阶段 (干脆锁定)
            log("PHASE 2: CLAMP LOCK", "safe");
            stage.classList.add('state-clamping');
            await delay(300); // 物理锁定时间极其短促

            // 3. 无限延长的检测阶段 (夹持与剪切解耦的核心体现)
            // 此时物料被稳固夹持,剪切刀完全未介入
            log("PHASE 3: SENSING (DECOUPLED)");
            stage.classList.add('state-sensing');
            sensorField.classList.add('is-scanning');
            sensorStatusEl.innerText = "ANALYZING...";
            sensorStatusEl.className = "hud-value";
            
            // 模拟一个较长且随机的检测时间,证明时间的完全解耦
            const sensingDuration = 2500 + Math.random() * 1500; 
            detectionStartTime = Date.now();
            
            // 更新检测时间 UI
            detectionTimer = setInterval(() => {
                const elapsed = (Date.now() - detectionStartTime) / 1000;
                detectTimeEl.innerText = elapsed.toFixed(2) + "s";
            }, 50);

            await delay(sensingDuration);
            
            clearInterval(detectionTimer);
            sensorStatusEl.innerText = "TARGET VERIFIED";
            sensorStatusEl.className = "hud-highlight";
            sensorField.classList.remove('is-scanning');
            await delay(200);
            stage.classList.remove('state-sensing');

            // 4. 独立剪切阶段 (极度干脆的打击)
            log("PHASE 4: SHEAR STRIKE", "alert");
            stage.classList.add('state-shearing');
            await delay(50); // 极短的剪切下落时间
            
            // 剪切瞬间物料分离
            stage.classList.add('state-cut');
            await delay(100); // 刀片在底部停留极短时间

            // 5. 刀片快速回弹与夹具释放
            log("PHASE 5: RETRACT & RELEASE");
            stage.classList.remove('state-shearing');
            stage.classList.add('state-retracting');
            
            await delay(200); // 刀片先回缩
            
            // 夹具再松开
            stage.classList.remove('state-clamping');
            sensorStatusEl.innerText = "STANDBY";
            sensorStatusEl.className = "";
            detectTimeEl.innerText = "0.00s";
            
            await delay(600); // 等待物料掉落和机构复位

            // 移除回弹状态准备下一循环
            stage.classList.remove('state-retracting');
            stage.classList.remove('state-cut');
            
            // 循环
            runEngineCycle();
        }

        // 系统启动
        setTimeout(() => {
            log("ALL SYSTEMS GO", "safe");
            runEngineCycle();
        }, 1000);

    </script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>高精度解耦机械系统 - 动力学可视化</title>
    <style>
        @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@300;500;800&display=swap');

        :root {
            --bg-base: #060913;
            --grid-line: rgba(56, 189, 248, 0.06);
            --cyan-glow: #0ea5e9;
            --neon-blue: #38bdf8;
            --alert-red: #ef4444;
            --safe-green: #10b981;
            --metal-dark: #1e293b;
            --metal-mid: #475569;
            --metal-light: #94a3b8;
            --copper: #b45309;
        }

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

        body {
            background-color: var(--bg-base);
            font-family: 'JetBrains Mono', monospace;
            height: 100vh;
            overflow: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
            /* 复杂工程蓝图背景 */
            background-image: 
                linear-gradient(var(--grid-line) 1px, transparent 1px),
                linear-gradient(90deg, var(--grid-line) 1px, transparent 1px),
                linear-gradient(rgba(56, 189, 248, 0.02) 2px, transparent 2px),
                linear-gradient(90deg, rgba(56, 189, 248, 0.02) 2px, transparent 2px);
            background-size: 20px 20px, 20px 20px, 100px 100px, 100px 100px;
            background-position: center center;
        }

        /* 极简角落HUD系统 - 严格小字号、边缘定位 */
        .hud {
            position: absolute;
            font-size: 10px;
            line-height: 1.5;
            color: rgba(255,255,255,0.6);
            pointer-events: none;
            z-index: 100;
            text-transform: uppercase;
            letter-spacing: 1px;
        }
        .hud-tl { top: 20px; left: 20px; }
        .hud-tr { top: 20px; right: 20px; text-align: right; }
        .hud-bl { bottom: 20px; left: 20px; }
        .hud-br { bottom: 20px; right: 20px; text-align: right; }

        .hud-title {
            font-weight: 800;
            font-size: 12px;
            color: var(--neon-blue);
            margin-bottom: 6px;
            letter-spacing: 2px;
        }
        .hud-val { color: #fff; font-weight: 500; font-size: 11px; }
        .hud-hl { color: var(--safe-green); font-weight: 800; }
        .hud-warn { color: var(--alert-red); font-weight: 800; }
        
        /* 核心动画区 - 最大化空间且无遮挡 */
        .stage-container {
            position: relative;
            width: 1100px;
            height: 600px;
            display: flex;
            justify-content: center;
            align-items: center;
            filter: drop-shadow(0 0 30px rgba(14, 165, 233, 0.05));
        }

        svg {
            width: 100%;
            height: 100%;
            overflow: visible;
        }

        /* 机械部件的微光与质感 */
        .glow-cyan { filter: drop-shadow(0 0 8px rgba(56,189,248,0.6)); }
        .glow-red { filter: drop-shadow(0 0 12px rgba(239,68,68,0.8)); }
        .glow-green { filter: drop-shadow(0 0 10px rgba(16,185,129,0.8)); }
        
        .part-metal { fill: url(#grad-metal); stroke: #0f172a; stroke-width: 1.5; }
        .part-metal-dark { fill: url(#grad-metal-dark); stroke: #020617; stroke-width: 2; }
        .part-copper { fill: url(#grad-copper); stroke: #78350f; stroke-width: 1; }
        .part-blade { fill: url(#grad-blade); stroke: var(--metal-light); stroke-width: 1; }
        
        /* 装饰性UI线 */
        .ui-line { stroke: var(--neon-blue); stroke-width: 1; opacity: 0.3; stroke-dasharray: 4 4; }
        
        /* 激光扫描特效 */
        #laser-beam {
            transition: opacity 0.2s;
        }
        .scanning {
            animation: scanAnim 1.2s ease-in-out infinite alternate;
        }
        @keyframes scanAnim {
            0% { transform: translateX(-40px); }
            100% { transform: translateX(40px); }
        }

        /* 动态粒子层 */
        #particles {
            position: absolute;
            top: 0; left: 0;
            width: 100%; height: 100%;
            pointer-events: none;
        }
        .spark {
            position: absolute;
            width: 2px;
            height: 8px;
            background: #fff;
            box-shadow: 0 0 6px #facc15, 0 0 12px #ef4444;
            border-radius: 2px;
            opacity: 0;
        }
    </style>
</head>
<body>

    <!-- 极简边缘 HUD -->
    <div class="hud hud-tl">
        <div class="hud-title">KINEMATIC SYSTEM .V2</div>
        <div>ARCH: <span class="hud-val">MOTOR-CAM-LINKAGE & RACK-PINION</span></div>
        <div>OP_MODE: <span class="hud-val">FULLY DECOUPLED</span></div>
        <div style="margin-top: 8px; opacity: 0.6; font-size: 9px;">
            > SYS.01 : RACK-DRIVEN CLAMP<br>
            > SYS.02 : SENSOR ARRAY (VARIABLE TIME)<br>
            > SYS.03 : CAM-DRIVEN GUILLOTINE SHEAR
        </div>
    </div>

    <div class="hud hud-tr">
        <div>SYS CLOCK // <span id="clock" class="hud-val">00:00:00:000</span></div>
        <div>CAM ANGLE // <span id="hud-angle" class="hud-val">270.0°</span></div>
        <div>LINK STRESS // <span id="hud-stress" class="hud-val">0.0 MPa</span></div>
        <div style="margin-top: 8px;">
            BLADE VELOCITY: <span id="hud-vel" class="hud-val">0.0 m/s</span>
        </div>
    </div>

    <div class="hud hud-bl">
        <div class="hud-title">DECOUPLING TELEMETRY</div>
        <div>CLAMP STATE: <span id="hud-clamp">OPEN</span></div>
        <div>SENSOR LOCK: <span id="hud-sensor">WAITING</span></div>
        <div>SCAN DUR: <span id="hud-time" class="hud-hl">0.00s</span></div>
        <div style="margin-top: 8px; max-width: 220px; font-size: 9px; opacity: 0.5;">
            * ACTION ISOLATED: CLAMP HOLDS SECURELY WHILE SENSOR EXECUTES UNLIMITED DURATION SCAN. MOTOR/CAM ACTUATES INDEPENDENTLY.
        </div>
    </div>

    <div class="hud hud-br">
        <div>[ SEQUENCE LOG ]</div>
        <div id="log-3" style="opacity: 0.3;">SYS BOOT</div>
        <div id="log-2" style="opacity: 0.6;">CALIBRATING KINEMATICS</div>
        <div id="log-1" class="hud-val">> STANDBY FOR MATERIAL</div>
    </div>

    <!-- 中心纯动画区域 -->
    <div class="stage-container">
        <svg id="stage" viewBox="0 0 1100 600">
            <defs>
                <!-- 材质渐变定义 -->
                <linearGradient id="grad-metal" x1="0%" y1="0%" x2="0%" y2="100%">
                    <stop offset="0%" stop-color="#64748b" />
                    <stop offset="50%" stop-color="#334155" />
                    <stop offset="100%" stop-color="#1e293b" />
                </linearGradient>
                <linearGradient id="grad-metal-dark" x1="0%" y1="0%" x2="100%" y2="100%">
                    <stop offset="0%" stop-color="#1e293b" />
                    <stop offset="100%" stop-color="#020617" />
                </linearGradient>
                <linearGradient id="grad-copper" x1="0%" y1="0%" x2="100%" y2="100%">
                    <stop offset="0%" stop-color="#d97706" />
                    <stop offset="50%" stop-color="#f59e0b" />
                    <stop offset="100%" stop-color="#92400e" />
                </linearGradient>
                <linearGradient id="grad-blade" x1="0%" y1="0%" x2="100%" y2="0%">
                    <stop offset="0%" stop-color="#e2e8f0" />
                    <stop offset="80%" stop-color="#94a3b8" />
                    <stop offset="100%" stop-color="#f8fafc" />
                </linearGradient>
                <linearGradient id="grad-mat" x1="0%" y1="0%" x2="0%" y2="100%">
                    <stop offset="0%" stop-color="#fcd34d" />
                    <stop offset="20%" stop-color="#fef3c7" />
                    <stop offset="80%" stop-color="#d97706" />
                    <stop offset="100%" stop-color="#78350f" />
                </linearGradient>
                
                <!-- 发光滤镜 -->
                <filter id="neon-glow" x="-50%" y="-50%" width="200%" height="200%">
                    <feGaussianBlur stdDeviation="4" result="blur" />
                    <feMerge>
                        <feMergeNode in="blur" />
                        <feMergeNode in="SourceGraphic" />
                    </feMerge>
                </filter>
                
                <!-- 条纹图样 (用于危险区域或抓手) -->
                <pattern id="stripes" width="10" height="10" patternUnits="userSpaceOnUse" patternTransform="rotate(45)">
                    <rect width="5" height="10" fill="#0f172a" opacity="0.5"/>
                </pattern>
            </defs>

            <!-- 背景导轨与机架 -->
            <g id="bg-frame" opacity="0.6">
                <!-- 送料轴线 -->
                <line x1="0" y1="350" x2="1100" y2="350" class="ui-line" />
                <!-- 剪切垂直轴线 -->
                <line x1="850" y1="0" x2="850" y2="600" class="ui-line" stroke-dasharray="2 6" />
                
                <!-- 夹持器导轨 -->
                <rect x="250" y="150" width="40" height="300" class="part-metal-dark" rx="5" />
                <line x1="270" y1="160" x2="270" y2="440" stroke="#0ea5e9" stroke-width="2" opacity="0.3" />
                
                <!-- 剪刀机架背板 -->
                <path d="M 780,80 h 140 v 420 h -140 z" fill="#0f172a" stroke="#1e293b" stroke-width="4" rx="10" />
                <rect x="800" y="240" width="20" height="240" class="part-metal-dark" />
                <rect x="880" y="240" width="20" height="240" class="part-metal-dark" />
            </g>

            <!-- 动态物料层 -->
            <g id="material-layer">
                <!-- 左侧被夹持部分 -->
                <rect id="mat-left" x="-500" y="340" width="1350" height="20" fill="url(#grad-mat)" rx="2" filter="drop-shadow(0 5px 10px rgba(0,0,0,0.5))" />
                <!-- 右侧被切断掉落部分 -->
                <g id="mat-right-group">
                    <rect id="mat-right" x="850" y="340" width="250" height="20" fill="url(#grad-mat)" rx="2" display="none" />
                </g>
            </g>

            <!-- 系统1: 夹持器组件 (齿轮齿条式抓手) -->
            <g id="clamp-system">
                <!-- 上抓手 -->
                <g id="jaw-top" transform="translate(0, -60)">
                    <path d="M 230,220 h 80 v 100 h -80 z" class="part-metal" rx="4" />
                    <!-- 齿条 -->
                    <rect x="295" y="220" width="10" height="100" fill="url(#stripes)" />
                    <!-- 夹爪 -->
                    <path d="M 240,320 h 60 l -10,18 h -40 z" class="part-metal-dark" />
                    <rect x="245" y="338" width="50" height="4" fill="#ef4444" />
                </g>
                
                <!-- 下抓手 -->
                <g id="jaw-bottom" transform="translate(0, 60)">
                    <path d="M 230,380 h 80 v 100 h -80 z" class="part-metal" rx="4" />
                    <!-- 齿条 -->
                    <rect x="295" y="380" width="10" height="100" fill="url(#stripes)" />
                    <!-- 夹爪 -->
                    <path d="M 240,380 h 60 l -10,-18 h -40 z" class="part-metal-dark" />
                    <rect x="245" y="358" width="50" height="4" fill="#ef4444" />
                </g>

                <!-- 驱动齿轮 (Pinion) -->
                <g id="clamp-pinion" transform="translate(270, 350)">
                    <circle cx="0" cy="0" r="22" class="part-metal" />
                    <circle cx="0" cy="0" r="16" class="part-copper" />
                    <circle cx="0" cy="0" r="6" fill="#020617" />
                    <!-- 齿轮纹理示意 -->
                    <path d="M -16,0 L 16,0 M 0,-16 L 0,16 M -11,-11 L 11,11 M -11,11 L 11,-11" stroke="#1e293b" stroke-width="3" />
                </g>
            </g>

            <!-- 系统2: 传感器阵列 (解耦等待区) -->
            <g id="sensor-system" transform="translate(550, 350)">
                <!-- 扫描仪外壳 -->
                <path d="M -40,-60 h 80 v 20 h -80 z M -40,40 h 80 v 20 h -80 z" class="part-metal-dark" rx="3" />
                <path d="M -30,-40 v 80 M 30,-40 v 80" stroke="#334155" stroke-width="4" stroke-dasharray="4 4" />
                
                <!-- 激光发射器与光束 -->
                <g id="laser-assembly" opacity="0">
                    <rect x="-40" y="-45" width="80" height="90" fill="rgba(16, 185, 129, 0.05)" />
                    <line id="laser-beam" x1="0" y1="-40" x2="0" y2="40" stroke="#10b981" stroke-width="3" filter="url(#neon-glow)" class="" />
                    <circle id="laser-dot" cx="0" cy="-40" r="4" fill="#10b981" filter="url(#neon-glow)" />
                </g>
            </g>

            <!-- 系统3: 凸轮连杆剪切机 (核心动力学可视化) -->
            <g id="shear-system">
                <!-- 1. 驱动电机定子 (Motor Stator) -->
                <g transform="translate(850, 150)">
                    <circle cx="0" cy="0" r="70" class="part-metal-dark" />
                    <!-- 铜线圈示意 -->
                    <circle cx="0" cy="0" r="55" class="part-copper" stroke-dasharray="10 4" stroke-width="12" fill="none" />
                    <circle cx="0" cy="0" r="45" class="part-metal" />
                </g>

                <!-- 2. 旋转凸轮/转子 (Cam/Rotor) - 动态旋转 -->
                <g id="shear-cam" transform="translate(850, 150) rotate(-90)">
                    <circle cx="0" cy="0" r="40" class="part-metal" />
                    <!-- 偏心销轴心 (Crank Pin) -->
                    <circle cx="28" cy="0" r="8" fill="#e2e8f0" stroke="#0f172a" stroke-width="2" />
                    <line x1="0" y1="0" x2="28" y2="0" stroke="#0f172a" stroke-width="4" />
                    <circle cx="0" cy="0" r="6" fill="#0f172a" />
                </g>

                <!-- 3. 传动连杆 (Linkage) - 动态计算坐标 -->
                <!-- x1,y1接偏心销, x2,y2接刀具块 -->
                <line id="shear-linkage" x1="850" y1="122" x2="850" y2="242" stroke="url(#grad-metal)" stroke-width="16" stroke-linecap="round" />
                <circle id="link-pin-top" cx="850" cy="122" r="5" fill="#0f172a" />
                <circle id="link-pin-bot" cx="850" cy="242" r="5" fill="#0f172a" />

                <!-- 4. 剪切刀具滑块组 (Blade Assembly) - 动态Y轴平移 -->
                <g id="blade-assembly" transform="translate(0, 242)">
                    <!-- 承重滑块 -->
                    <path d="M 810,-10 h 80 v 60 h -80 z" class="part-metal-dark" rx="5" />
                    <circle cx="850" cy="0" r="10" class="part-metal" /> <!-- 下连接销底座 -->
                    <!-- 剪刀刃 (Scissor/Guillotine Blade) - 带有倾斜剪切角,保证干脆利落 -->
                    <path d="M 815,50 h 70 v 40 l -70, 20 z" class="part-blade" />
                    <!-- 刀锋高光 -->
                    <line x1="815" y1="110" x2="885" y2="90" stroke="#fff" stroke-width="2" opacity="0.8" />
                    <!-- 危险警示条纹 -->
                    <rect x="815" y="45" width="70" height="10" fill="url(#stripes)" />
                </g>
            </g>

            <!-- 前景遮挡/导轨压板 -->
            <rect x="800" y="240" width="10" height="240" fill="#0f172a" opacity="0.8" />
            <rect x="890" y="240" width="10" height="240" fill="#0f172a" opacity="0.8" />
        </svg>

        <!-- 粒子容器用于火花特效 -->
        <div id="particles"></div>
    </div>

    <script>
        /**
         * 核心运动学常量与状态
         */
        const KINEMATICS = {
            motorX: 850,
            motorY: 150,
            camRadius: 28,      // 偏心距 R
            linkLength: 140,    // 连杆长度 L
            bladeBaseY: 0,      // 刀具相对滑块销的偏移
            matCutX: 850,       // 剪切位置
            matSurfaceY: 340    // 物料上表面Y
        };

        const STATE = {
            phase: 'INIT', // FEED, CLAMP, SENSE, SHEAR, RELEASE
            feedX: -500,   // -500 to 0 (0 means tip is at 850)
            clampY: 60,    // 60 (open) to 0 (closed)
            motorAngle: -Math.PI / 2, // Starts at top (-90 deg)
            isCut: false,
            cutMatY: 340,
            cutMatVy: 0,
            cutMatRot: 0,
            cutMatVx: 0,
            globalTime: 0
        };

        // DOM 元素绑定
        const els = {
            jawTop: document.getElementById('jaw-top'),
            jawBot: document.getElementById('jaw-bottom'),
            pinion: document.getElementById('clamp-pinion'),
            matLeft: document.getElementById('mat-left'),
            matRightGrp: document.getElementById('mat-right-group'),
            matRight: document.getElementById('mat-right'),
            cam: document.getElementById('shear-cam'),
            linkage: document.getElementById('shear-linkage'),
            linkPinTop: document.getElementById('link-pin-top'),
            linkPinBot: document.getElementById('link-pin-bot'),
            bladeAssy: document.getElementById('blade-assembly'),
            laserAssy: document.getElementById('laser-assembly'),
            laserBeam: document.getElementById('laser-beam'),
            particles: document.getElementById('particles'),
            
            // HUD
            clock: document.getElementById('clock'),
            hudAngle: document.getElementById('hud-angle'),
            hudStress: document.getElementById('hud-stress'),
            hudVel: document.getElementById('hud-vel'),
            hudClamp: document.getElementById('hud-clamp'),
            hudSensor: document.getElementById('hud-sensor'),
            hudTime: document.getElementById('hud-time'),
            logs: [document.getElementById('log-3'), document.getElementById('log-2'), document.getElementById('log-1')]
        };

        // 工具函数
        const delay = ms => new Promise(res => setTimeout(res, ms));
        
        function log(msg, type = 'normal') {
            els.logs[0].innerText = els.logs[1].innerText;
            els.logs[0].style.color = els.logs[1].style.color;
            els.logs[1].innerText = els.logs[2].innerText;
            els.logs[1].style.color = els.logs[2].style.color;
            els.logs[2].innerText = `> ${msg}`;
            if(type === 'alert') els.logs[2].style.color = 'var(--alert-red)';
            else if(type === 'safe') els.logs[2].style.color = 'var(--safe-green)';
            else els.logs[2].style.color = '#fff';
        }

        function createSparks() {
            for(let i=0; i<8; i++) {
                let spark = document.createElement('div');
                spark.className = 'spark';
                spark.style.left = (KINEMATICS.matCutX - 10 + Math.random()*20) + 'px';
                spark.style.top = KINEMATICS.matSurfaceY + 'px';
                els.particles.appendChild(spark);
                
                let angle = Math.random() * Math.PI - Math.PI; // -180 to 0
                let speed = 5 + Math.random() * 10;
                let vx = Math.cos(angle) * speed;
                let vy = Math.sin(angle) * speed;
                let x = 0, y = 0;
                
                let life = 0;
                function animSpark() {
                    life++;
                    x += vx;
                    y += vy;
                    vy += 0.5; // gravity
                    spark.style.transform = `translate(${x}px, ${y}px) rotate(${Math.atan2(vy, vx)}rad)`;
                    spark.style.opacity = 1 - (life/30);
                    if(life < 30) requestAnimationFrame(animSpark);
                    else spark.remove();
                }
                requestAnimationFrame(animSpark);
            }
        }

        /**
         * 核心运动学渲染循环
         * 实时计算连杆与滑块的精确几何位置
         */
        let lastBladeY = 0;
        function renderKinematics() {
            STATE.globalTime += 16;
            
            // HUD 时钟
            const ms = STATE.globalTime % 1000;
            const s = Math.floor(STATE.globalTime / 1000) % 60;
            const m = Math.floor(STATE.globalTime / 60000);
            els.clock.innerText = `${m.toString().padStart(2,'0')}:${s.toString().padStart(2,'0')}:${ms.toString().padStart(3,'0')}`;

            // --- 1. 送料与夹持系统渲染 ---
            els.matLeft.setAttribute('x', STATE.feedX);
            els.jawTop.setAttribute('transform', `translate(0, ${-STATE.clampY})`);
            els.jawBot.setAttribute('transform', `translate(0, ${STATE.clampY})`);
            // 齿轮联动旋转 (位移 / 半径 = 弧度)
            let pinionAngle = ((60 - STATE.clampY) / 22) * (180/Math.PI);
            els.pinion.setAttribute('transform', `translate(270, 350) rotate(${pinionAngle})`);

            // --- 2. 剪切系统运动学解算 ---
            // 偏心销坐标 (Pin Top)
            let px = KINEMATICS.motorX + KINEMATICS.camRadius * Math.cos(STATE.motorAngle);
            let py = KINEMATICS.motorY + KINEMATICS.camRadius * Math.sin(STATE.motorAngle);
            
            // 连杆与垂直导轨的交点 (Pin Bottom = Blade Assembly Y)
            // L^2 = (px - bx)^2 + (py - by)^2. Here bx is fixed at motorX.
            let dx = KINEMATICS.motorX - px;
            let dy = Math.sqrt(KINEMATICS.linkLength**2 - dx**2);
            let by = py + dy; // 滑块销钉 Y 坐标

            // 应用到 SVG
            let deg = STATE.motorAngle * (180/Math.PI);
            els.cam.setAttribute('transform', `translate(${KINEMATICS.motorX}, ${KINEMATICS.motorY}) rotate(${deg})`);
            
            els.linkage.setAttribute('x1', px);
            els.linkage.setAttribute('y1', py);
            els.linkage.setAttribute('x2', KINEMATICS.motorX);
            els.linkage.setAttribute('y2', by);
            
            els.linkPinTop.setAttribute('cx', px);
            els.linkPinTop.setAttribute('cy', py);
            
            els.linkPinBot.setAttribute('cy', by);
            els.bladeAssy.setAttribute('transform', `translate(0, ${by})`);

            // 计算物理量 HUD
            let degDisplay = ((deg + 360 + 90) % 360).toFixed(1);
            els.hudAngle.innerText = `${degDisplay}°`;
            
            let vel = (by - lastBladeY) / 16 * 1000; // px/s
            els.hudVel.innerText = (vel/100).toFixed(2) + " m/s";
            lastBladeY = by;
            
            // 模拟连杆应力 (当切削瞬间应力激增)
            let stress = Math.abs(Math.cos(STATE.motorAngle)) * 15;
            if(STATE.phase === 'SHEAR' && by > KINEMATICS.matSurfaceY - 80 && by < KINEMATICS.matSurfaceY - 40) {
                stress += 250; // 切割瞬间应力极大
                els.hudStress.style.color = "var(--alert-red)";
            } else {
                els.hudStress.style.color = "#fff";
            }
            els.hudStress.innerText = stress.toFixed(1) + " MPa";

            // --- 3. 切断物料物理模拟 ---
            if (STATE.isCut) {
                STATE.cutMatVy += 0.8; // 重力
                STATE.cutMatY += STATE.cutMatVy;
                STATE.cutMatX += STATE.cutMatVx;
                STATE.cutMatRot += 3;
                els.matRightGrp.setAttribute('transform', `translate(${STATE.cutMatX - 850}, ${STATE.cutMatY - 340}) rotate(${STATE.cutMatRot}, 850, 340)`);
                if(STATE.cutMatY > 800) els.matRight.style.display = 'none'; // 掉出屏幕外
            }

            requestAnimationFrame(renderKinematics);
        }
        
        // 启动渲染引擎
        requestAnimationFrame(renderKinematics);

        /**
         * 状态机控制序列
         */
        async function runCycle() {
            // --- 阶段 1: 送料 ---
            STATE.phase = 'FEED';
            log("PHASE 1: MATERIAL FEED", "normal");
            STATE.isCut = false;
            els.matRight.style.display = 'none';
            els.matLeft.setAttribute('width', 1350);
            
            // 缓动送料
            await new Promise(res => {
                let start = performance.now();
                function step(t) {
                    let p = (t - start) / 600;
                    if(p > 1) p = 1;
                    let ease = 1 - Math.pow(1 - p, 3);
                    STATE.feedX = -500 + ease * 500;
                    if(p < 1) requestAnimationFrame(step);
                    else res();
                }
                requestAnimationFrame(step);
            });
            await delay(100);

            // --- 阶段 2: 夹持 (Rack & Pinion 动作) ---
            STATE.phase = 'CLAMP';
            log("PHASE 2: RACK CLAMP LOCK", "safe");
            els.hudClamp.innerText = "LOCKED";
            els.hudClamp.className = "hud-hl";
            
            await new Promise(res => {
                let start = performance.now();
                function step(t) {
                    let p = (t - start) / 150; // 150ms 快速夹紧
                    if(p > 1) p = 1;
                    STATE.clampY = 60 - (p * 60); // 降到0
                    if(p < 1) requestAnimationFrame(step);
                    else res();
                }
                requestAnimationFrame(step);
            });
            await delay(100);

            // --- 阶段 3: 无限延长检测 (体现解耦核心) ---
            // 夹持器锁死,剪切刀未动,时间完全由传感器决定
            STATE.phase = 'SENSE';
            log("PHASE 3: SENSOR ARRAY ACTIVE", "normal");
            els.hudSensor.innerText = "SCANNING...";
            els.hudSensor.className = "hud-hl";
            els.laserAssy.style.opacity = 1;
            els.laserBeam.classList.add('scanning');

            let scanStartTime = Date.now();
            let scanDuration = 2000 + Math.random() * 2000; // 随机 2-4 秒的检测时间
            
            let timeInterval = setInterval(() => {
                els.hudTime.innerText = ((Date.now() - scanStartTime)/1000).toFixed(2) + "s";
            }, 50);

            await delay(scanDuration);
            
            clearInterval(timeInterval);
            els.laserBeam.classList.remove('scanning');
            els.laserAssy.style.opacity = 0;
            els.hudSensor.innerText = "VERIFIED";
            await delay(100);

            // --- 阶段 4: 独立剪切 (凸轮连杆暴力打击) ---
            STATE.phase = 'SHEAR';
            log("PHASE 4: KINEMATIC SHEAR STRIKE", "alert");
            
            await new Promise(res => {
                let start = performance.now();
                let dur = 350; // 极快的一击
                let startAngle = -Math.PI / 2;
                
                function step(t) {
                    let p = (t - start) / dur;
                    if(p > 1) p = 1;
                    
                    // 自定义动力学缓动:加速下落,减速回抽
                    let ease;
                    if (p < 0.4) {
                        ease = 2.5 * p * p; // 加速下落
                    } else {
                        let pp = (p - 0.4) / 0.6;
                        ease = 0.4 + 0.6 * (1 - Math.pow(1 - pp, 3)); // 减速回升
                    }
                    
                    STATE.motorAngle = startAngle + ease * (Math.PI * 2);
                    
                    // 触发物理切断点 (当刀刃经过物料表面)
                    if(p > 0.15 && !STATE.isCut) {
                        STATE.isCut = true;
                        createSparks();
                        els.matLeft.setAttribute('width', 1350 - 250); // 左侧缩短
                        els.matRight.style.display = 'block'; // 右侧显示并掉落
                        STATE.cutMatY = 340;
                        STATE.cutMatX = 850;
                        STATE.cutMatVy = 2; // 初速度
                        STATE.cutMatVx = 1 + Math.random();
                        STATE.cutMatRot = 0;
                    }
                    
                    if(p < 1) requestAnimationFrame(step);
                    else {
                        STATE.motorAngle = startAngle; // 精确复位
                        res();
                    }
                }
                requestAnimationFrame(step);
            });

            // --- 阶段 5: 复位释放 ---
            STATE.phase = 'RELEASE';
            log("PHASE 5: SYSTEM RESET", "normal");
            
            await new Promise(res => {
                let start = performance.now();
                function step(t) {
                    let p = (t - start) / 200;
                    if(p > 1) p = 1;
                    STATE.clampY = p * 60; // 回到60
                    if(p < 1) requestAnimationFrame(step);
                    else res();
                }
                requestAnimationFrame(step);
            });
            
            els.hudClamp.innerText = "OPEN";
            els.hudClamp.className = "";
            els.hudSensor.innerText = "WAITING";
            els.hudSensor.className = "";
            els.hudTime.innerText = "0.00s";

            await delay(400); // 等待下一次循环
            runCycle();
        }

        // 系统启动延迟
        setTimeout(() => {
            log("INIT KINEMATICS ENGINE...", "safe");
            setTimeout(runCycle, 800);
        }, 500);

    </script>
</body>
</html>
积分规则:第一轮对话扣减8分,后续每轮扣6分