分享图
动画工坊
引擎就绪
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>TRIZ IFR: 全周径向膨胀锁紧机构原理</title>
    <style>
        :root {
            /* High-tech engineering blueprint palette */
            --bg-color: #050914;
            --grid-color: rgba(32, 48, 86, 0.4);
            --shaft-color: #1a2235;
            --shaft-stroke: #3b507d;
            --housing-color: #0d1424;
            --housing-stroke: #2a3d66;
            --ring-inner: #293855;
            --ring-outer: #384b70;
            --bolt-color: #6a7d9e;
            
            /* Accent & Force Colors */
            --force-radial: #00f0ff;
            --force-axial-none: #ff3366;
            --text-hud: #7da0d6;
            --text-highlight: #e0f2fe;
            
            --anim-timing: cubic-bezier(0.4, 0.0, 0.2, 1);
        }

        body, html {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            background-color: var(--bg-color);
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'JetBrains Mono', 'Courier New', Courier, monospace, sans-serif;
            overflow: hidden;
            color: var(--text-hud);
        }

        #animation-container {
            position: relative;
            width: 100%;
            max-width: 1200px;
            aspect-ratio: 16 / 9;
            box-shadow: 0 0 50px rgba(0, 0, 0, 0.8) inset;
        }

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

        /* --- HUD Layout (Strictly edge-aligned to avoid obscuring) --- */
        .hud-panel {
            position: absolute;
            font-size: 13px;
            line-height: 1.5;
            pointer-events: none;
            background: rgba(5, 9, 20, 0.7);
            border: 1px solid rgba(125, 160, 214, 0.2);
            padding: 12px 16px;
            border-radius: 4px;
            backdrop-filter: blur(4px);
        }

        .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; }

        .hud-title {
            color: var(--text-highlight);
            font-weight: bold;
            font-size: 15px;
            margin-bottom: 6px;
            letter-spacing: 1px;
            border-bottom: 1px solid var(--force-radial);
            padding-bottom: 4px;
            display: inline-block;
        }

        .data-row {
            display: flex;
            justify-content: space-between;
            gap: 16px;
            margin-top: 4px;
        }
        .data-value {
            color: var(--force-radial);
            font-family: monospace;
            font-weight: bold;
        }

        /* --- SVG Element Styling & Transitions --- */
        .blueprint-grid { fill: url(#gridPattern); }
        .centerline { stroke: var(--text-hud); stroke-width: 1; stroke-dasharray: 15, 5, 3, 5; opacity: 0.5; }
        
        .part { transition: transform 1.5s var(--anim-timing), fill 1s; stroke-linejoin: round; }
        .shaft { fill: var(--shaft-color); stroke: var(--shaft-stroke); stroke-width: 2; }
        .housing { fill: url(#housingHatch); stroke: var(--housing-stroke); stroke-width: 2; }
        
        .ring-inner { fill: var(--ring-inner); stroke: #455a8a; stroke-width: 1.5; }
        .ring-outer { fill: var(--ring-outer); stroke: #5a73a3; stroke-width: 1.5; }
        .bolt { fill: var(--bolt-color); stroke: #111; stroke-width: 1; }

        /* Force Vectors & Glows */
        .force-arrow {
            stroke: var(--force-radial);
            stroke-width: 2;
            fill: none;
            opacity: 0;
            transition: opacity 0.5s ease;
            marker-end: url(#arrowhead-radial);
        }
        
        .glow-line {
            stroke: var(--force-radial);
            stroke-width: 3;
            opacity: 0;
            filter: drop-shadow(0 0 5px var(--force-radial));
            transition: opacity 1s ease;
        }

        .no-axial-symbol {
            stroke: var(--force-axial-none);
            stroke-width: 2;
            fill: none;
            opacity: 0;
            transition: opacity 0.5s ease;
        }

        /* End View Elements */
        .end-view-group { opacity: 0.2; transition: opacity 1s ease; }
        .ev-shaft { fill: var(--shaft-color); stroke: var(--shaft-stroke); }
        .ev-ring-inner { fill: none; stroke: var(--ring-inner); stroke-width: 8; }
        .ev-ring-outer { fill: none; stroke: var(--ring-outer); stroke-width: 8; }
        .ev-housing { fill: none; stroke: var(--housing-stroke); stroke-width: 15; stroke-dasharray: 10, 5; }
        .ev-radial-line { stroke: var(--force-radial); stroke-width: 1.5; opacity: 0; transition: all 1s ease; }

        /* --- Animation States (Controlled by JS classes on SVG) --- */
        
        /* State: Tightening (Axial movement of wedges) */
        svg.state-tightening .ring-inner.top { transform: translateX(-18px); }
        svg.state-tightening .ring-inner.bottom { transform: translateX(-18px); }
        svg.state-tightening .ring-outer.top { transform: translateX(12px); }
        svg.state-tightening .ring-outer.bottom { transform: translateX(12px); }
        svg.state-tightening .bolt { transform: translateX(-8px); }
        
        /* State: Locked (Radial expansion, forces active) */
        svg.state-locked .ring-inner.top { transform: translateX(-18px) translateY(2px); fill: #31466e; }
        svg.state-locked .ring-inner.bottom { transform: translateX(-18px) translateY(-2px); fill: #31466e; }
        svg.state-locked .ring-outer.top { transform: translateX(12px) translateY(-2px); fill: #48628f; }
        svg.state-locked .ring-outer.bottom { transform: translateX(12px) translateY(2px); fill: #48628f; }
        svg.state-locked .bolt { transform: translateX(-8px); }
        
        /* Force visuals activate */
        svg.state-locked .force-arrow { opacity: 1; animation: pulse-arrow 1.5s infinite alternate; }
        svg.state-locked .glow-line { opacity: 0.8; }
        svg.state-locked .no-axial-symbol { opacity: 0.9; }
        
        /* End view activates */
        svg.state-locked .end-view-group { opacity: 0.9; }
        svg.state-locked .ev-radial-line { opacity: 1; stroke-dashoffset: 0; }

        @keyframes pulse-arrow {
            0% { filter: drop-shadow(0 0 2px var(--force-radial)); }
            100% { filter: drop-shadow(0 0 8px var(--force-radial)); transform: scaleY(1.1); }
        }

        /* Subtle idle animation for mechanical feel */
        .gear-idle {
            transform-origin: 900px 300px;
            animation: rotate-slow 20s linear infinite;
        }
        @keyframes rotate-slow {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

    </style>
</head>
<body>

<div id="animation-container">
    <!-- SVG Canvas: Using a large viewBox for precise blueprint layout -->
    <svg id="mainSvg" viewBox="0 0 1200 675" preserveAspectRatio="xMidYMid meet">
        <defs>
            <!-- Background Grid Pattern -->
            <pattern id="gridPattern" width="40" height="40" patternUnits="userSpaceOnUse">
                <path d="M 40 0 L 0 0 0 40" fill="none" stroke="var(--grid-color)" stroke-width="0.5"/>
                <path d="M 200 0 L 0 0 0 200" fill="none" stroke="var(--grid-color)" stroke-width="1"/>
            </pattern>

            <!-- Hatching for cross-section parts -->
            <pattern id="housingHatch" width="10" height="10" patternTransform="rotate(45 0 0)" patternUnits="userSpaceOnUse">
                <rect width="10" height="10" fill="var(--housing-color)"/>
                <line x1="0" y1="0" x2="0" y2="10" stroke="var(--housing-stroke)" stroke-width="1.5" opacity="0.3"/>
            </pattern>

            <!-- Markers for Force Vectors -->
            <marker id="arrowhead-radial" markerWidth="6" markerHeight="6" refX="3" refY="3" orient="auto">
                <polygon points="0 0, 6 3, 0 6" fill="var(--force-radial)" />
            </marker>
            
            <marker id="arrowhead-axial" markerWidth="6" markerHeight="6" refX="3" refY="3" orient="auto">
                <polygon points="0 0, 6 3, 0 6" fill="var(--force-axial-none)" />
            </marker>

            <!-- Glow Filters -->
            <filter id="neon-glow" x="-20%" y="-20%" width="140%" height="140%">
                <feGaussianBlur stdDeviation="4" result="blur" />
                <feMerge>
                    <feMergeNode in="blur" />
                    <feMergeNode in="SourceGraphic" />
                </feMerge>
            </filter>
        </defs>

        <!-- Base Background & Grid -->
        <rect width="100%" height="100%" fill="var(--bg-color)"/>
        <rect width="100%" height="100%" class="blueprint-grid"/>

        <!-- Centerline of Rotation -->
        <line x1="50" y1="337.5" x2="750" y2="337.5" class="centerline" />

        <!-- ========================================== -->
        <!-- MAIN CROSS-SECTION ASSEMBLY (Left/Center)  -->
        <!-- ========================================== -->
        <g id="cross-section" transform="translate(0, 37.5)"> <!-- Shifted to align centerline visually -->
            
            <!-- 1. SHAFT (Center core) -->
            <!-- Top Half -->
            <rect class="part shaft" x="80" y="220" width="600" height="80" />
            <!-- Bottom Half -->
            <rect class="part shaft" x="80" y="300" width="600" height="80" />

            <!-- 2. HOUSING (Outer structure with hole) -->
            <!-- Top Half Cutout -->
            <path class="part housing" d="M 80,60 L 680,60 L 680,180 L 80,180 Z M 150,180 L 600,180 L 600,60 L 150,60 Z" fill-rule="evenodd"/>
            <!-- Solid Top Housing above the gap -->
            <rect class="part housing" x="80" y="60" width="600" height="120" />
            <!-- Solid Bottom Housing below the gap -->
            <rect class="part housing" x="80" y="420" width="600" height="120" />

            <!-- ========================================== -->
            <!-- 3. LOCKING DEVICE (The innovative part)      -->
            <!-- ========================================== -->
            
            <!-- TOP ASSEMBLY -->
            <g id="top-lock">
                <!-- Interface interface line: slopes from (320, 185) to (520, 215) -->
                
                <!-- Inner Ring (Wedge getting thicker towards left) -->
                <polygon class="part ring-inner top" points="320,218 520,218 520,212 320,188" />
                
                <!-- Outer Ring (Wedge getting thicker towards right) -->
                <polygon class="part ring-outer top" points="310,184 510,208 510,182 310,182" />

                <!-- Bolt (Top) -->
                <g class="part bolt top-bolt">
                    <!-- Bolt Head -->
                    <rect x="295" y="193" width="15" height="14" rx="2" />
                    <!-- Bolt Shaft -->
                    <rect x="310" y="196" width="70" height="8" />
                    <!-- Thread lines -->
                    <path d="M 350,196 L 350,204 M 355,196 L 355,204 M 360,196 L 360,204 M 365,196 L 365,204 M 370,196 L 370,204" stroke="#111" stroke-width="1"/>
                </g>
            </g>

            <!-- BOTTOM ASSEMBLY (Mirrored vertically around Y=300) -->
            <g id="bottom-lock">
                <!-- Inner Ring (Wedge thicker left) -->
                <polygon class="part ring-inner bottom" points="320,382 520,382 520,388 320,412" />
                
                <!-- Outer Ring (Wedge thicker right) -->
                <polygon class="part ring-outer bottom" points="310,416 510,392 510,418 310,418" />

                <!-- Bolt (Bottom) -->
                <g class="part bolt bottom-bolt">
                    <rect x="295" y="393" width="15" height="14" rx="2" />
                    <rect x="310" y="396" width="70" height="8" />
                    <path d="M 350,396 L 350,404 M 355,396 L 355,404 M 360,396 L 360,404 M 365,396 L 365,404 M 370,396 L 370,404" stroke="#111" stroke-width="1"/>
                </g>
            </g>

            <!-- ========================================== -->
            <!-- 4. VISUAL GUIDANCE & FORCES (IFR Focus)    -->
            <!-- ========================================== -->
            
            <!-- Highlighting Interface Lines when locked -->
            <path class="glow-line" d="M 302,185 L 522,211" />
            <path class="glow-line" d="M 302,415 L 522,389" />

            <!-- Radial Expansion Forces (Top Assembly) -->
            <g class="force-vectors top">
                <!-- Outer pushing UP into housing -->
                <path class="force-arrow" d="M 360,180 L 360,165" />
                <path class="force-arrow" d="M 410,180 L 410,165" />
                <path class="force-arrow" d="M 460,180 L 460,165" />
                <!-- Inner pushing DOWN into shaft -->
                <path class="force-arrow" d="M 360,220 L 360,235" />
                <path class="force-arrow" d="M 410,220 L 410,235" />
                <path class="force-arrow" d="M 460,220 L 460,235" />
            </g>

            <!-- Radial Expansion Forces (Bottom Assembly) -->
            <g class="force-vectors bottom">
                <!-- Outer pushing DOWN into housing -->
                <path class="force-arrow" d="M 360,420 L 360,435" />
                <path class="force-arrow" d="M 410,420 L 410,435" />
                <path class="force-arrow" d="M 460,420 L 460,435" />
                <!-- Inner pushing UP into shaft -->
                <path class="force-arrow" d="M 360,380 L 360,365" />
                <path class="force-arrow" d="M 410,380 L 410,365" />
                <path class="force-arrow" d="M 460,380 L 460,365" />
            </g>

            <!-- Emphasizing NO AXIAL MOVEMENT (IFR Core) -->
            <g class="no-axial-symbol" transform="translate(620, 200)">
                <!-- Red cross over horizontal arrows -->
                <path d="M 0,0 L 40,0" stroke-width="2" marker-end="url(#arrowhead-axial)" />
                <path d="M 40,0 L 0,0" stroke-width="2" marker-end="url(#arrowhead-axial)" />
                <path d="M 10,-10 L 30,10" stroke="var(--force-axial-none)" stroke-width="3" />
                <path d="M 30,-10 L 10,10" stroke="var(--force-axial-none)" stroke-width="3" />
                <text x="50" y="4" fill="var(--force-axial-none)" font-size="12" font-family="sans-serif" stroke="none">零轴向位移</text>
            </g>
        </g>

        <!-- ========================================== -->
        <!-- 5. 360° END VIEW (Right Side, Radial concept) -->
        <!-- ========================================== -->
        <g id="end-view" class="end-view-group" transform="translate(950, 337.5)">
            <!-- Concentric representation -->
            <circle class="ev-housing" r="140" />
            <circle class="ev-ring-outer gear-idle" r="110" stroke-dasharray="20 5" />
            <circle class="ev-ring-inner gear-idle" r="95" stroke-dasharray="15 10" />
            <circle class="ev-shaft" r="80" />
            <circle r="4" fill="var(--text-hud)" /> <!-- Center point -->
            
            <!-- 360 degree Force Arrows generation -->
            <g class="radial-forces">
                <!-- Javascript will duplicate these lines to form a starburst -->
                <line class="ev-radial-line" x1="0" y1="-85" x2="0" y2="-125" marker-end="url(#arrowhead-radial)" />
                <line class="ev-radial-line" x1="0" y1="85" x2="0" y2="125" marker-end="url(#arrowhead-radial)" />
                <line class="ev-radial-line" x1="-85" y1="0" x2="-125" y2="0" marker-end="url(#arrowhead-radial)" />
                <line class="ev-radial-line" x1="85" y1="0" x2="125" y2="0" marker-end="url(#arrowhead-radial)" />
                
                <line class="ev-radial-line" x1="60" y1="-60" x2="88" y2="-88" marker-end="url(#arrowhead-radial)" />
                <line class="ev-radial-line" x1="-60" y1="-60" x2="-88" y2="-88" marker-end="url(#arrowhead-radial)" />
                <line class="ev-radial-line" x1="60" y1="60" x2="88" y2="88" marker-end="url(#arrowhead-radial)" />
                <line class="ev-radial-line" x1="-60" y1="60" x2="-88" y2="88" marker-end="url(#arrowhead-radial)" />
            </g>
            <text x="0" y="165" text-anchor="middle" fill="var(--force-radial)" font-size="14" font-weight="bold" filter="url(#neon-glow)">360° 均匀径向分布</text>
        </g>
    </svg>

    <!-- ========================================== -->
    <!-- HUD OVERLAYS (Strict corner placement)     -->
    <!-- ========================================== -->
    
    <div class="hud-panel hud-top-left">
        <div class="hud-title">TRIZ 最终理想解 (IFR)</div>
        <div>矛盾:紧固端面导致轴向偏载/应力集中</div>
        <div>理想解:摒弃端面,利用间隙径向消除间隙</div>
        <div style="color: var(--force-radial); margin-top: 4px; font-weight: bold;">
            ➔ 零绝对轴向拉伸 · 完美同轴度
        </div>
    </div>

    <div class="hud-panel hud-top-right">
        <div class="hud-title">系统实时状态</div>
        <div class="data-row">
            <span>工作模式</span>
            <span id="mode-text" class="data-value" style="color: var(--text-hud);">等待接入</span>
        </div>
        <div class="data-row">
            <span>径向压强</span>
            <span class="data-value"><span id="pressure-val">0</span> MPa</span>
        </div>
        <div class="data-row">
            <span>传递扭矩</span>
            <span class="data-value"><span id="torque-val">0</span> N·m</span>
        </div>
    </div>

    <div class="hud-panel hud-bottom-left">
        <div class="hud-title">机理说明</div>
        <div>1. 螺栓拧紧驱动内外锥环轴向相对滑动</div>
        <div>2. 锥面力矩转化为纯粹的径向膨胀力</div>
        <div>3. 内环抱死电机轴,外环撑死结构孔</div>
    </div>

    <div class="hud-panel hud-bottom-right">
        <div class="hud-title">图例标识</div>
        <div style="display: flex; align-items: center; gap: 8px;">
            <div style="width: 12px; height: 12px; background: var(--shaft-color); border: 1px solid var(--shaft-stroke);"></div> 电机轴
        </div>
        <div style="display: flex; align-items: center; gap: 8px;">
            <div style="width: 12px; height: 12px; background: var(--ring-outer); border: 1px solid #5a73a3;"></div> 胀紧套组件
        </div>
        <div style="display: flex; align-items: center; gap: 8px;">
            <div style="width: 12px; height: 12px; border-bottom: 2px dashed var(--force-radial);"></div> 膨胀撑力轨迹
        </div>
    </div>
</div>

<script>
    /**
     * Animation Controller for TRIZ IFR Principle
     * Manages state transitions and HUD data counting to create a realistic
     * engineering analysis visualization. Automatically loops.
     */
    document.addEventListener('DOMContentLoaded', () => {
        const svgElement = document.getElementById('mainSvg');
        const modeText = document.getElementById('mode-text');
        const pressureVal = document.getElementById('pressure-val');
        const torqueVal = document.getElementById('torque-val');
        
        // Target parameters from context
        const MAX_PRESSURE = 120;
        const MAX_TORQUE = 200;

        // Easing function for numbers (easeOutExpo)
        const easeOut = (t) => t === 1 ? 1 : 1 - Math.pow(2, -10 * t);

        // Counter animation utility
        function animateValue(obj, start, end, duration) {
            let startTimestamp = null;
            const step = (timestamp) => {
                if (!startTimestamp) startTimestamp = timestamp;
                const progress = Math.min((timestamp - startTimestamp) / duration, 1);
                const current = Math.floor(start + (end - start) * easeOut(progress));
                obj.innerHTML = current;
                if (progress < 1) {
                    window.requestAnimationFrame(step);
                }
            };
            window.requestAnimationFrame(step);
        }

        // Delay utility for async sequence
        const delay = ms => new Promise(res => setTimeout(res, ms));

        async function runAnimationSequence() {
            while (true) { // Infinite auto-loop
                
                // --- STATE 1: LOOSE / RESET ---
                svgElement.className.baseVal = ''; // Clear classes
                modeText.innerText = "装配间隙阶段";
                modeText.style.color = "var(--text-hud)";
                pressureVal.innerText = "0";
                torqueVal.innerText = "0";
                await delay(2000);

                // --- STATE 2: TIGHTENING (Axial motion) ---
                svgElement.className.baseVal = 'state-tightening';
                modeText.innerText = "螺栓拧紧滑动";
                modeText.style.color = "#ffb86c"; // Warning/action color
                await delay(1500); // Wait for CSS transition to near end

                // --- STATE 3: LOCKED (Radial Expansion & IFR Realization) ---
                svgElement.className.baseVal = 'state-tightening state-locked';
                modeText.innerText = "刚性固接完成";
                modeText.style.color = "var(--force-radial)";
                
                // Trigger numerical count ups
                animateValue(pressureVal, 0, MAX_PRESSURE, 1500);
                animateValue(torqueVal, 0, MAX_TORQUE, 1500);
                
                // Hold the ideal final result state for observation
                await delay(5000);

                // Reset cycle starts over implicitly at loop top
            }
        }

        // Start auto-playback immediately upon load
        runAnimationSequence();
    });
</script>

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