分享图
动画工坊
引擎就绪
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>端面齿电磁脱扣机构 - IFR 原理演示</title>
    <style>
        :root {
            --bg-color: #06090e;
            --grid-color: #121a2f;
            --text-main: #6887a8;
            --text-hl: #00f0ff;
            --text-alert: #ff3c00;
            --accent-green: #00ff88;
            --metal-dark: #1a2233;
            --metal-light: #8b9bb4;
            --coil-off: #2a3441;
            --coil-on: #00d2ff;
        }

        * {
            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: 40px 40px;
            background-position: center center;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            font-family: 'SF Mono', Consolas, 'Liberation Mono', Menlo, monospace;
            overflow: hidden;
            color: var(--text-main);
        }

        #animation-container {
            width: 100vw;
            height: 100vh;
            max-width: 1600px;
            max-height: 900px;
            position: relative;
            box-shadow: inset 0 0 150px rgba(0,0,0,0.8);
        }

        svg {
            width: 100%;
            height: 100%;
            display: block;
        }

        /* 文本与UI样式 */
        .ui-text {
            font-size: 12px;
            fill: var(--text-main);
            letter-spacing: 1px;
        }
        
        .ui-value {
            font-size: 13px;
            fill: var(--text-hl);
            font-weight: bold;
        }
        
        .ui-alert {
            fill: var(--text-alert);
            font-weight: bold;
        }

        .ui-title {
            font-size: 14px;
            fill: #ffffff;
            font-weight: bold;
            letter-spacing: 2px;
        }

        /* 动态类 */
        .glow {
            filter: drop-shadow(0 0 8px var(--coil-on));
        }

        .glow-alert {
            filter: drop-shadow(0 0 10px var(--text-alert));
        }

        .hidden {
            opacity: 0;
        }

        .dash-line {
            stroke-dasharray: 4 4;
            animation: dash-scroll 20s linear infinite;
        }

        @keyframes dash-scroll {
            to { stroke-dashoffset: -400; }
        }
    </style>
</head>
<body>

<div id="animation-container">
    <svg viewBox="0 0 1200 700" preserveAspectRatio="xMidYMid meet">
        <defs>
            <!-- 材质渐变 -->
            <linearGradient id="metal-grad" x1="0%" y1="0%" x2="0%" y2="100%">
                <stop offset="0%" stop-color="#3b4a6b" />
                <stop offset="50%" stop-color="#8b9bb4" />
                <stop offset="100%" stop-color="#1a2233" />
            </linearGradient>
            
            <linearGradient id="metal-dark-grad" x1="0%" y1="0%" x2="0%" y2="100%">
                <stop offset="0%" stop-color="#121826" />
                <stop offset="50%" stop-color="#2a3854" />
                <stop offset="100%" stop-color="#0a0e17" />
            </linearGradient>

            <linearGradient id="coil-grad-on" x1="0%" y1="0%" x2="0%" y2="100%">
                <stop offset="0%" stop-color="#005577" />
                <stop offset="50%" stop-color="#00f0ff" />
                <stop offset="100%" stop-color="#003344" />
            </linearGradient>

            <linearGradient id="coil-grad-off" x1="0%" y1="0%" x2="0%" y2="100%">
                <stop offset="0%" stop-color="#1a1a1a" />
                <stop offset="50%" stop-color="#333333" />
                <stop offset="100%" stop-color="#0d0d0d" />
            </linearGradient>

            <!-- 滤镜发光效果 -->
            <filter id="neon-glow" x="-50%" y="-50%" width="200%" height="200%">
                <feGaussianBlur stdDeviation="5" result="blur" />
                <feMerge>
                    <feMergeNode in="blur" />
                    <feMergeNode in="SourceGraphic" />
                </feMerge>
            </filter>

            <filter id="impact-glow" x="-50%" y="-50%" width="200%" height="200%">
                <feGaussianBlur stdDeviation="8" result="blur" />
                <feComponentTransfer in="blur" result="glow">
                    <feFuncA type="linear" slope="2" />
                </feComponentTransfer>
                <feMerge>
                    <feMergeNode in="glow" />
                    <feMergeNode in="SourceGraphic" />
                </feMerge>
            </filter>

            <!-- 花键纹理 -->
            <pattern id="spline-pattern" width="10" height="20" patternUnits="userSpaceOnUse">
                <line x1="0" y1="5" x2="10" y2="5" stroke="#111" stroke-width="1" opacity="0.5"/>
                <line x1="0" y1="15" x2="10" y2="15" stroke="#fff" stroke-width="1" opacity="0.2"/>
            </pattern>
        </defs>

        <!-- ==================== 左侧:离合机构剖面图 ==================== -->
        <g id="clutch-mechanism" transform="translate(100, 300)">
            <!-- 背景网格与轴线 -->
            <line x1="-50" y1="0" x2="550" y2="0" stroke="var(--text-main)" stroke-width="0.5" stroke-dasharray="10 5" opacity="0.4" />
            
            <!-- 电机座 -->
            <rect x="0" y="-70" width="80" height="140" fill="url(#metal-dark-grad)" stroke="#4a5f80" stroke-width="1.5" />
            <text x="10" y="-80" class="ui-text">DRIVE MOTOR</text>

            <!-- 花键滑移轴 (连接电机) -->
            <rect x="80" y="-20" width="160" height="40" fill="url(#metal-grad)" />
            <rect x="80" y="-20" width="160" height="40" fill="url(#spline-pattern)" />

            <!-- 脱扣分离弹簧 (推力35N) -->
            <path id="sep-spring" d="M 80,-30 L 90,30 L 100,-30 L 110,30 L 120,-30 L 130,30 L 140,-30 L 150,30 L 160,-30 L 170,30 L 180,0" 
                  fill="none" stroke="#6887a8" stroke-width="3" vector-effect="non-scaling-stroke" />

            <!-- 大推力电磁线圈 -->
            <g id="coil-assembly">
                <!-- 上半部 -->
                <rect x="140" y="-90" width="100" height="50" fill="url(#coil-grad-off)" id="coil-top" stroke="#111" stroke-width="2"/>
                <!-- 下半部 -->
                <rect x="140" y="40" width="100" height="50" fill="url(#coil-grad-off)" id="coil-bottom" stroke="#111" stroke-width="2"/>
                <!-- 磁场指示线 (仅通电时显示) -->
                <g id="magnetic-field" opacity="0">
                    <path d="M 190,-40 C 130,-20 130,20 190,40" fill="none" stroke="var(--text-hl)" stroke-width="1.5" stroke-dasharray="4 4" filter="url(#neon-glow)" />
                    <path d="M 190,-40 C 250,-20 250,20 190,40" fill="none" stroke="var(--text-hl)" stroke-width="1.5" stroke-dasharray="4 4" filter="url(#neon-glow)" />
                </g>
            </g>

            <!-- 动端面齿盘 (Dog Clutch - Moving) -->
            <g id="moving-plate">
                <rect x="160" y="-60" width="40" height="120" fill="url(#metal-grad)" stroke="#222" stroke-width="1" />
                <!-- 梯形拔模角端面齿 (右向) -->
                <polygon points="200,-60 215,-55 215,-40 200,-35 200,-20 215,-15 215,0 200,5 200,20 215,25 215,40 200,45" fill="url(#metal-grad)" stroke="#222" stroke-width="1"/>
            </g>

            <!-- 静端面齿盘 (Dog Clutch - Static) -->
            <g id="static-plate" transform="translate(230, 0)">
                <rect x="15" y="-60" width="40" height="120" fill="url(#metal-grad)" stroke="#222" stroke-width="1" />
                <!-- 梯形拔模角端面齿 (左向 - 负形) -->
                <polygon points="15,-60 0,-55 0,-40 15,-35 15,-20 0,-15 0,0 15,5 15,20 0,25 0,40 15,45" fill="url(#metal-grad)" stroke="#222" stroke-width="1"/>
            </g>

            <!-- 主轴 (连接抬杆) -->
            <rect x="285" y="-20" width="120" height="40" fill="url(#metal-grad)" />
            
            <!-- 脱扣冲击波特效 -->
            <circle id="impact-wave" cx="215" cy="0" r="10" fill="none" stroke="var(--text-alert)" stroke-width="4" opacity="0" filter="url(#impact-glow)"/>
        </g>

        <!-- ==================== 关联线 ==================== -->
        <g stroke="var(--text-main)" stroke-width="1" opacity="0.4">
            <line x1="505" y1="300" x2="700" y2="300" class="dash-line" />
            <line x1="700" y1="300" x2="700" y2="400" class="dash-line" />
            <circle cx="700" cy="400" r="3" fill="var(--text-main)" />
        </g>

        <!-- ==================== 右侧:抬杆系统正视图 ==================== -->
        <g id="barrier-system" transform="translate(850, 450)">
            <!-- 支撑柱 -->
            <rect x="-30" y="0" width="60" height="200" fill="url(#metal-dark-grad)" />
            
            <!-- 蜗卷弹簧 (蓄能) -->
            <g id="spiral-spring" stroke="var(--metal-light)" fill="none" stroke-width="4" stroke-linecap="round">
                <!-- 螺旋路径表示 -->
                <path d="M 0,0 m 20,0 a 20,20 0 1,1 -40,0 a 20,20 0 1,1 40,0 m 10,0 a 30,30 0 1,1 -60,0 a 30,30 0 1,1 60,0 m 10,0 a 40,40 0 1,1 -80,0 a 40,40 0 1,1 80,0" />
            </g>

            <!-- 旋转中心 / 主轴端面 -->
            <circle cx="0" cy="0" r="15" fill="#111" stroke="#4a5f80" stroke-width="3" />

            <!-- 重型长栏杆 -->
            <g id="barrier-arm">
                <rect x="-20" y="-15" width="280" height="30" fill="url(#metal-grad)" rx="5" />
                <!-- 警示条纹 -->
                <path d="M 20,-15 L 40,15 M 60,-15 L 80,15 M 100,-15 L 120,15 M 140,-15 L 160,15 M 180,-15 L 200,15 M 220,-15 L 240,15" stroke="#111" stroke-width="10" opacity="0.3"/>
            </g>
        </g>

        <!-- ==================== 极简数据面板 HUD ==================== -->
        <!-- 左上角:状态参数 -->
        <g transform="translate(30, 40)">
            <text x="0" y="0" class="ui-title">SYSTEM_TELEMETRY // DOG_CLUTCH</text>
            <rect x="0" y="10" width="280" height="1" fill="var(--text-main)" opacity="0.5"/>
            
            <text x="0" y="35" class="ui-text">PHASE:</text>
            <text x="120" y="35" class="ui-value" id="hud-phase">IDLE</text>

            <text x="0" y="55" class="ui-text">COIL_POWER:</text>
            <text x="120" y="55" class="ui-value" id="hud-power">OFF</text>

            <text x="0" y="75" class="ui-text">CLUTCH_GAP:</text>
            <text x="120" y="75" class="ui-value" id="hud-gap">15.0 mm</text>

            <text x="0" y="95" class="ui-text">SPRING_FORCE:</text>
            <text x="120" y="95" class="ui-value" id="hud-force">35.0 N (NOMINAL)</text>
            
            <text x="0" y="115" class="ui-text">ARM_ANGLE:</text>
            <text x="120" y="115" class="ui-value" id="hud-angle">0.0 DEG</text>
        </g>

        <!-- 右下角:IFR 核心解析 -->
        <g transform="translate(850, 620)">
            <rect x="0" y="-60" width="300" height="80" fill="rgba(18,26,47,0.8)" stroke="#4a5f80" stroke-width="1" rx="4"/>
            <text x="15" y="-35" class="ui-text" fill="#fff" font-weight="bold">TRIZ 最终理想解 (IFR) :</text>
            <text x="15" y="-15" class="ui-text">无需外部解锁机构,断电瞬间利用</text>
            <text x="15" y="5" class="ui-text">分离弹簧势能实现 <tspan class="ui-alert" filter="url(#neon-glow)">绝对可靠脱扣</tspan></text>
        </g>
        
        <!-- 脱扣时间提示 (绝对边缘不遮挡) -->
        <g id="disconnect-alert" transform="translate(450, 200)" opacity="0">
            <rect x="-10" y="-15" width="220" height="24" fill="var(--text-alert)" opacity="0.2" />
            <text x="0" y="0" class="ui-text ui-alert" style="font-size: 14px;" filter="url(#neon-glow)">! 极速脱离响应 &lt; 0.1s</text>
        </g>

    </svg>
</div>

<script>
    // 动画状态管理
    const STATE = {
        IDLE: 0,
        ENGAGING: 1,
        LIFTING: 2,
        HOLDING: 3,
        DISCONNECTING: 4,
        DROPPING: 5
    };

    let currentState = STATE.IDLE;
    let timeInState = 0;
    let lastTime = 0;

    // 动画变量插值
    let vars = {
        clutchGap: 15.0,     // mm (15.0 to 0.0)
        armAngle: 0.0,       // deg (0 to -90)
        coilPower: 0,        // 0 or 1
        springColor: 0       // 0 to 1 (0: gray, 1: orange)
    };

    // DOM 引用
    const elMovingPlate = document.getElementById('moving-plate');
    const elSepSpring = document.getElementById('sep-spring');
    const elCoilTop = document.getElementById('coil-top');
    const elCoilBottom = document.getElementById('coil-bottom');
    const elMagField = document.getElementById('magnetic-field');
    const elBarrierArm = document.getElementById('barrier-arm');
    const elSpiralSpring = document.getElementById('spiral-spring');
    const elImpactWave = document.getElementById('impact-wave');
    const elAlert = document.getElementById('disconnect-alert');
    
    // HUD 引用
    const hudPhase = document.getElementById('hud-phase');
    const hudPower = document.getElementById('hud-power');
    const hudGap = document.getElementById('hud-gap');
    const hudForce = document.getElementById('hud-force');
    const hudAngle = document.getElementById('hud-angle');

    // 缓动函数
    const easeOutCubic = x => 1 - Math.pow(1 - x, 3);
    const easeInOutQuad = x => x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2;
    const easeOutBounce = x => {
        const n1 = 7.5625, d1 = 2.75;
        if (x < 1 / d1) return n1 * x * x;
        if (x < 2 / d1) return n1 * (x -= 1.5 / d1) * x + 0.75;
        if (x < 2.5 / d1) return n1 * (x -= 2.25 / d1) * x + 0.9375;
        return n1 * (x -= 2.625 / d1) * x + 0.984375;
    };

    // 渲染更新
    function render() {
        // 1. 离合器位移与弹簧压缩 (将gap转换为位移: gap 15 -> dx 0, gap 0 -> dx 15)
        const clutchDx = 15 - vars.clutchGap; 
        elMovingPlate.setAttribute('transform', `translate(${clutchDx}, 0)`);
        
        // 弹簧形变: X方向缩放,起点在x=80,固定,动点在x=160+clutchDx。原始长度80
        const springScaleX = (80 + clutchDx) / 80;
        elSepSpring.setAttribute('transform', `translate(80, 0) scale(${springScaleX}, 1) translate(-80, 0)`);

        // 2. 线圈状态更新
        if (vars.coilPower > 0.5) {
            elCoilTop.setAttribute('fill', 'url(#coil-grad-on)');
            elCoilBottom.setAttribute('fill', 'url(#coil-grad-on)');
            elMagField.setAttribute('opacity', '1');
            hudPower.textContent = 'ON / ELECTROMAGNETIC ENGAGED';
            hudPower.style.fill = 'var(--coil-on)';
        } else {
            elCoilTop.setAttribute('fill', 'url(#coil-grad-off)');
            elCoilBottom.setAttribute('fill', 'url(#coil-grad-off)');
            elMagField.setAttribute('opacity', '0');
            hudPower.textContent = 'OFF / POWER LOSS';
            hudPower.style.fill = 'var(--text-main)';
        }

        // 3. 抬杆与蜗卷弹簧更新
        elBarrierArm.setAttribute('transform', `rotate(${vars.armAngle})`);
        
        // 蜗卷弹簧旋转与颜色变化
        elSpiralSpring.setAttribute('transform', `rotate(${vars.armAngle * 0.5})`);
        const springR = Math.floor(139 + vars.springColor * 116); // 139 -> 255
        const springG = Math.floor(155 - vars.springColor * 95);  // 155 -> 60
        const springB = Math.floor(180 - vars.springColor * 180); // 180 -> 0
        elSpiralSpring.setAttribute('stroke', `rgb(${springR}, ${springG}, ${springB})`);

        // 4. 更新 HUD
        hudGap.textContent = vars.clutchGap.toFixed(1) + ' mm';
        hudAngle.textContent = Math.abs(vars.armAngle).toFixed(1) + ' DEG';
        
        if (vars.clutchGap < 0.1) {
            hudGap.style.fill = 'var(--accent-green)';
            hudGap.textContent += ' (LOCKED)';
        } else {
            hudGap.style.fill = 'var(--text-hl)';
        }

        if (vars.springColor > 0.9) {
            hudForce.textContent = '35.0 N (MAX POTENTIAL LOAD)';
            hudForce.style.fill = 'var(--text-alert)';
        } else {
            hudForce.textContent = '35.0 N (NOMINAL)';
            hudForce.style.fill = 'var(--text-hl)';
        }
    }

    // 主循环
    function tick(timestamp) {
        if (!lastTime) lastTime = timestamp;
        const delta = timestamp - lastTime;
        lastTime = timestamp;
        timeInState += delta;

        // 状态机逻辑
        switch (currentState) {
            case STATE.IDLE:
                hudPhase.textContent = '01 - IDLE / SAFE STATE';
                vars.clutchGap = 15;
                vars.armAngle = 0;
                vars.coilPower = 0;
                vars.springColor = 0;
                elImpactWave.setAttribute('opacity', '0');
                elImpactWave.setAttribute('r', '10');
                elAlert.setAttribute('opacity', '0');
                
                if (timeInState > 1500) {
                    currentState = STATE.ENGAGING;
                    timeInState = 0;
                }
                break;

            case STATE.ENGAGING:
                hudPhase.textContent = '02 - COIL ENERGIZED / ENGAGING';
                vars.coilPower = 1;
                // 离合器在0.3秒内吸合
                let pEngage = Math.min(timeInState / 300, 1);
                vars.clutchGap = 15 - 15 * easeOutCubic(pEngage);
                
                if (timeInState > 800) {
                    currentState = STATE.LIFTING;
                    timeInState = 0;
                }
                break;

            case STATE.LIFTING:
                hudPhase.textContent = '03 - MOTOR DRIVE / ACCUMULATING ENERGY';
                // 抬杆1.5秒
                let pLift = Math.min(timeInState / 1500, 1);
                vars.armAngle = -90 * easeInOutQuad(pLift);
                vars.springColor = pLift; // 弹簧蓄能颜色变红
                
                if (timeInState > 2000) {
                    currentState = STATE.HOLDING;
                    timeInState = 0;
                }
                break;

            case STATE.HOLDING:
                hudPhase.textContent = '04 - LOCKED / HOLDING STATE';
                if (timeInState > 2500) {
                    currentState = STATE.DISCONNECTING;
                    timeInState = 0;
                }
                break;

            case STATE.DISCONNECTING:
                hudPhase.textContent = '05 - POWER CUT / INSTANT DISCONNECT';
                hudPhase.style.fill = 'var(--text-alert)';
                vars.coilPower = 0;
                
                // <0.1s 极速脱扣 (100ms)
                let pDisc = Math.min(timeInState / 100, 1);
                vars.clutchGap = 15 * pDisc; 
                
                // 冲击波特效
                elImpactWave.setAttribute('opacity', 1 - pDisc);
                elImpactWave.setAttribute('r', 10 + 40 * pDisc);
                
                // 提示文字闪烁
                elAlert.setAttribute('opacity', timeInState % 200 < 100 ? '1' : '0');

                if (timeInState > 300) {
                    currentState = STATE.DROPPING;
                    timeInState = 0;
                    hudPhase.style.fill = 'var(--text-hl)';
                }
                break;

            case STATE.DROPPING:
                hudPhase.textContent = '06 - FREE FALL / SPRING RELEASE';
                
                // 弹簧释放,重力下落 0.8s
                let pDrop = Math.min(timeInState / 800, 1);
                vars.armAngle = -90 + 90 * easeOutBounce(pDrop);
                vars.springColor = 1 - pDrop;
                
                elAlert.setAttribute('opacity', '0');

                if (timeInState > 1500) {
                    currentState = STATE.IDLE;
                    timeInState = 0;
                }
                break;
        }

        render();
        requestAnimationFrame(tick);
    }

    // 初始化启动
    window.addEventListener('DOMContentLoaded', () => {
        requestAnimationFrame(tick);
    });
</script>

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