分享图
动画工坊
引擎就绪
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>IFR: 柔性阻拦网络回收系统</title>
    <style>
        :root {
            --bg-color: #060913;
            --grid-color: rgba(30, 58, 138, 0.3);
            --text-main: #94a3b8;
            --text-highlight: #38bdf8;
            --text-warning: #fbbf24;
            --text-danger: #ef4444;
            --text-success: #10b981;
            --net-idle: #2563eb;
            --net-active: #f59e0b;
            --rocket-body: #e2e8f0;
        }

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

        body {
            background-color: var(--bg-color);
            color: var(--text-main);
            font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
            overflow: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            width: 100vw;
            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;
        }

        /* 扫描线特效 */
        .scanlines {
            position: absolute;
            top: 0; left: 0; width: 100vw; height: 100vh;
            background: linear-gradient(to bottom, rgba(255,255,255,0), rgba(255,255,255,0) 50%, rgba(0,0,0,0.2) 50%, rgba(0,0,0,0.2));
            background-size: 100% 4px;
            pointer-events: none;
            z-index: 10;
            opacity: 0.4;
        }

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

        /* 文本排版严格限制:极其小巧,靠边缘放置 */
        .hud-text {
            font-family: 'JetBrains Mono', 'Courier New', Courier, monospace;
            font-size: 11px;
            fill: var(--text-main);
            letter-spacing: 1px;
        }

        .hud-value {
            font-weight: 700;
            fill: var(--text-highlight);
        }

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

        .hud-subtitle {
            font-size: 10px;
            fill: var(--text-success);
        }

        /* SVG 滤镜与动画类 */
        .glow {
            filter: url(#glow);
        }
        
        .glow-red {
            filter: url(#glow-red);
        }

        .parafoil-line {
            stroke: var(--text-success);
            stroke-width: 1.5;
            stroke-dasharray: 4 2;
        }

        .net-cable {
            fill: none;
            stroke-linecap: round;
            stroke-linejoin: round;
            transition: stroke 0.1s ease;
        }

        .truss {
            stroke: #1e293b;
            stroke-width: 2;
            fill: none;
        }

        #rocket-group {
            will-change: transform;
        }
    </style>
</head>
<body>
    <div class="scanlines"></div>
    
    <svg id="animation-canvas" viewBox="0 0 1200 900" preserveAspectRatio="xMidYMid meet">
        <defs>
            <!-- 蓝青色发光滤镜 -->
            <filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
                <feGaussianBlur stdDeviation="5" result="blur" />
                <feMerge>
                    <feMergeNode in="blur" />
                    <feMergeNode in="SourceGraphic" />
                </feMerge>
            </filter>
            <!-- 警告红色发光滤镜 -->
            <filter id="glow-red" x="-20%" y="-20%" width="140%" height="140%">
                <feGaussianBlur stdDeviation="8" result="blur" />
                <feComponentTransfer in="blur" result="glow">
                    <feFuncA type="linear" slope="1.5"/>
                </feComponentTransfer>
                <feMerge>
                    <feMergeNode in="glow" />
                    <feMergeNode in="SourceGraphic" />
                </feMerge>
            </filter>

            <!-- 塔架桁架图案 -->
            <pattern id="truss-pattern" width="40" height="40" patternUnits="userSpaceOnUse">
                <path d="M0,0 L40,40 M40,0 L0,40 M0,0 L0,40 M40,0 L40,40 M0,20 L40,20" stroke="#1e293b" stroke-width="2" fill="none"/>
            </pattern>

            <!-- 火箭渐变 -->
            <linearGradient id="rocket-grad" x1="0%" y1="0%" x2="100%" y2="0%">
                <stop offset="0%" stop-color="#94a3b8" />
                <stop offset="50%" stop-color="#f8fafc" />
                <stop offset="100%" stop-color="#64748b" />
            </linearGradient>

            <linearGradient id="flame-grad" x1="0%" y1="0%" x2="0%" y2="100%">
                <stop offset="0%" stop-color="#38bdf8" stop-opacity="0.8"/>
                <stop offset="100%" stop-color="#0284c7" stop-opacity="0"/>
            </linearGradient>
        </defs>

        <!-- 背景刻度与装饰 -->
        <g opacity="0.3">
            <line x1="600" y1="100" x2="600" y2="800" stroke="#334155" stroke-width="1" stroke-dasharray="10 10"/>
            <path d="M 580 480 L 620 480" stroke="#38bdf8" stroke-width="1"/>
            <text x="630" y="484" class="hud-text" fill="#38bdf8">TARGET ALT: 0M</text>
        </g>

        <!-- ================= 左侧边缘文字面板 (严禁遮挡中央) ================= -->
        <g transform="translate(40, 60)">
            <text x="0" y="0" class="hud-title">IFR: 零冲压着陆系统</text>
            <text x="0" y="20" class="hud-subtitle">TRIZ 最终理想解分析</text>
            
            <rect x="0" y="35" width="220" height="1" fill="#1e293b" />
            
            <text x="0" y="55" class="hud-text">核心矛盾:</text>
            <text x="0" y="75" class="hud-text" fill="#64748b">- 传统反推耗费海量燃料 (重)</text>
            <text x="0" y="95" class="hud-text" fill="#64748b">- 发动机单点故障率高 (险)</text>

            <text x="0" y="135" class="hud-text">理想状态 (IFR):</text>
            <text x="0" y="155" class="hud-text" fill="#10b981">▶ 系统自身消除动能</text>
            <text x="0" y="175" class="hud-text" fill="#10b981">▶ 不增加箭体复杂性</text>

            <text x="0" y="215" class="hud-text">资源利用 (Resource):</text>
            <text x="0" y="235" class="hud-text" fill="#38bdf8">1. 空气动力学 (冲压翼伞减速)</text>
            <text x="0" y="255" class="hud-text" fill="#38bdf8">2. 地面柔性基建 (3D阻拦网)</text>
            <text x="0" y="275" class="hud-text" fill="#38bdf8">3. 形变耗散 (液压阻尼器储能)</text>
        </g>

        <!-- ================= 右侧边缘遥测数据面板 (严禁遮挡中央) ================= -->
        <g transform="translate(960, 60)">
            <text x="0" y="0" class="hud-title">TELEMETRY DATA</text>
            <text x="0" y="20" class="hud-subtitle">LIVE FEED // SYSTEM NORMAL</text>
            
            <rect x="0" y="35" width="200" height="1" fill="#1e293b" />
            
            <text x="0" y="60" class="hud-text">PHASE:</text>
            <text x="100" y="60" class="hud-text hud-value" id="tel-phase">GLIDING</text>
            
            <text x="0" y="90" class="hud-text">ALTITUDE:</text>
            <text x="100" y="90" class="hud-text hud-value" id="tel-alt">1450.5 M</text>
            
            <text x="0" y="120" class="hud-text">VELOCITY:</text>
            <text x="100" y="120" class="hud-text hud-value" id="tel-vel">-18.2 M/S</text>
            
            <text x="0" y="150" class="hud-text">NET DEFORM:</text>
            <text x="100" y="150" class="hud-text hud-value" id="tel-def">0.0 M</text>
            
            <text x="0" y="180" class="hud-text">DAMPER LOAD:</text>
            <text x="100" y="180" class="hud-text hud-value" id="tel-load">0 %</text>
            
            <!-- 阻尼器负载条 -->
            <rect x="0" y="200" width="180" height="6" fill="#1e293b" />
            <rect id="load-bar" x="0" y="200" width="0" height="6" fill="#10b981" class="glow" />
        </g>

        <!-- ================= 中央核心动画区域 ================= -->
        
        <!-- 地面塔架系统 -->
        <g id="ground-system">
            <!-- 左后塔架 -->
            <rect x="300" y="480" width="20" height="320" fill="url(#truss-pattern)" opacity="0.4"/>
            <!-- 右后塔架 -->
            <rect x="880" y="480" width="20" height="320" fill="url(#truss-pattern)" opacity="0.4"/>
            
            <!-- 左前塔架 -->
            <rect x="240" y="400" width="40" height="400" fill="url(#truss-pattern)"/>
            <path d="M 230 800 L 290 800 L 280 400 L 240 400 Z" fill="none" stroke="#334155" stroke-width="3"/>
            <!-- 左前液压阻尼器 -->
            <rect x="250" y="440" width="20" height="60" fill="#1e293b" stroke="#38bdf8" stroke-width="2"/>
            <rect id="damper-left" x="255" y="440" width="10" height="20" fill="#38bdf8" class="glow"/>

            <!-- 右前塔架 -->
            <rect x="920" y="400" width="40" height="400" fill="url(#truss-pattern)"/>
            <path d="M 910 800 L 970 800 L 960 400 L 920 400 Z" fill="none" stroke="#334155" stroke-width="3"/>
            <!-- 右前液压阻尼器 -->
            <rect x="930" y="440" width="20" height="60" fill="#1e293b" stroke="#38bdf8" stroke-width="2"/>
            <rect id="damper-right" x="935" y="440" width="10" height="20" fill="#38bdf8" class="glow"/>
        </g>

        <!-- 柔性阻拦网系统 (前后多层,展现3D感) -->
        <g id="net-system">
            <!-- 后层网 -->
            <path id="net-back-1" class="net-cable" d="M 310 480 Q 600 480 890 480" stroke="#1d4ed8" stroke-width="2" opacity="0.5"/>
            <path id="net-back-2" class="net-cable" d="M 310 480 Q 600 480 890 480" stroke="#1d4ed8" stroke-width="2" opacity="0.3"/>
            
            <!-- 前层主网 (受力形变核心) -->
            <path id="net-main-1" class="net-cable glow" d="M 260 480 Q 600 480 940 480" stroke="#38bdf8" stroke-width="4"/>
            <path id="net-main-2" class="net-cable" d="M 260 480 Q 600 480 940 480" stroke="#60a5fa" stroke-width="2" transform="translate(0, -10)"/>
            <path id="net-main-3" class="net-cable" d="M 260 480 Q 600 480 940 480" stroke="#60a5fa" stroke-width="2" transform="translate(0, 10)"/>
            
            <!-- 垂直连接线 (交织网眼) -->
            <g id="net-verticals" stroke="#38bdf8" stroke-width="1" opacity="0.6">
                <!-- 由 JS 动态更新 -->
            </g>
        </g>

        <!-- 飞行器系统 -->
        <g id="vehicle">
            <!-- 滑翔翼伞 (冲压伞) -->
            <g id="parafoil-group">
                <!-- 伞盖 -->
                <path d="M 450 -150 Q 600 -220 750 -150 Q 600 -180 450 -150 Z" fill="#10b981" fill-opacity="0.2" stroke="#10b981" stroke-width="2" class="glow"/>
                <path d="M 500 -160 Q 600 -200 700 -160" stroke="#34d399" stroke-width="1" fill="none"/>
                <!-- 伞绳 -->
                <line x1="450" y1="-150" x2="585" y2="-10" class="parafoil-line"/>
                <line x1="500" y1="-165" x2="590" y2="-10" class="parafoil-line"/>
                <line x1="600" y1="-180" x2="600" y2="-10" class="parafoil-line"/>
                <line x1="700" y1="-165" x2="610" y2="-10" class="parafoil-line"/>
                <line x1="750" y1="-150" x2="615" y2="-10" class="parafoil-line"/>
            </g>

            <!-- 火箭主体 -->
            <g id="rocket-body" transform="translate(600, 0)">
                <!-- 气动舵 (格栅舵) -->
                <line x1="-25" y1="-30" x2="-15" y2="-30" stroke="#94a3b8" stroke-width="4"/>
                <line x1="15" y1="-30" x2="25" y2="-30" stroke="#94a3b8" stroke-width="4"/>
                
                <!-- 箭体外壳 -->
                <rect x="-15" y="-50" width="30" height="140" rx="15" fill="url(#rocket-grad)" stroke="#334155" stroke-width="2"/>
                
                <!-- 姿态控制喷口 (冷气) - 装饰 -->
                <circle cx="0" cy="-20" r="3" fill="#0f172a"/>
                <circle cx="0" cy="70" r="3" fill="#0f172a"/>
                
                <!-- 底部发动机喷管 (关闭状态,呼应无需反推) -->
                <path d="M -10 90 L -15 105 L 15 105 L 10 90 Z" fill="#334155"/>
                <path d="M -6 105 L -8 115 L 8 115 L 6 105 Z" fill="#1e293b"/>
                
                <!-- 脱落标识 -->
                <text x="0" y="20" font-family="sans-serif" font-size="10" fill="#1e293b" text-anchor="middle" font-weight="bold" transform="rotate(90, 0, 20)">STAGE-1</text>
            </g>
        </g>
    </svg>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            // DOM Elements
            const vehicle = document.getElementById('vehicle');
            const parafoilGrp = document.getElementById('parafoil-group');
            const rocketBody = document.getElementById('rocket-body');
            
            // Net paths
            const netMain1 = document.getElementById('net-main-1');
            const netMain2 = document.getElementById('net-main-2');
            const netMain3 = document.getElementById('net-main-3');
            const netBack1 = document.getElementById('net-back-1');
            const netBack2 = document.getElementById('net-back-2');
            const netVerticals = document.getElementById('net-verticals');
            
            // Dampers
            const damperLeft = document.getElementById('damper-left');
            const damperRight = document.getElementById('damper-right');
            
            // Telemetry Text
            const telPhase = document.getElementById('tel-phase');
            const telAlt = document.getElementById('tel-alt');
            const telVel = document.getElementById('tel-vel');
            const telDef = document.getElementById('tel-def');
            const telLoad = document.getElementById('tel-load');
            const loadBar = document.getElementById('load-bar');

            // Constants & Physics config
            const DURATION = 9000; // 整个循环周期时长(ms)
            const NET_BASE_Y = 480;
            const NET_MAX_Y = 750; // 最大形变到底部的视觉坐标
            
            // Animation Loop
            let startTime = null;

            function updateNet(rocketY) {
                // 计算形变
                let deformY = NET_BASE_Y;
                if (rocketY > NET_BASE_Y - 90) { // 火箭底部(约+90偏移)触网
                    deformY = rocketY + 90;
                }
                
                // 二次贝塞尔曲线 控制点CY计算:要使曲线过 (600, deformY),起点(260, 480) 终点(940, 480)
                // B(0.5) = 0.25*P0 + 0.5*P1 + 0.25*P2
                // deformY = 0.25*480 + 0.5*CY + 0.25*480 = 240 + 0.5*CY
                // CY = (deformY - 240) * 2
                
                // 如果没有形变,CY 就是 480
                let cyMain = (deformY > NET_BASE_Y) ? (deformY - 240) * 2 : 480;
                let cyBack = (deformY > NET_BASE_Y) ? (deformY - 240) * 1.8 : 480; // 后网形变稍小

                // 更新主网形变
                netMain1.setAttribute('d', `M 260 ${NET_BASE_Y} Q 600 ${cyMain} 940 ${NET_BASE_Y}`);
                netMain2.setAttribute('d', `M 260 ${NET_BASE_Y-10} Q 600 ${cyMain-10} 940 ${NET_BASE_Y-10}`);
                netMain3.setAttribute('d', `M 260 ${NET_BASE_Y+10} Q 600 ${cyMain+10} 940 ${NET_BASE_Y+10}`);
                
                // 更新后网
                netBack1.setAttribute('d', `M 310 ${NET_BASE_Y} Q 600 ${cyBack} 890 ${NET_BASE_Y}`);
                netBack2.setAttribute('d', `M 310 ${NET_BASE_Y-10} Q 600 ${cyBack-10} 890 ${NET_BASE_Y-10}`);

                // 更新交织网眼(动态生成垂直线段示意)
                let verticalsHTML = '';
                const segments = 15;
                for (let i = 1; i < segments; i++) {
                    let t = i / segments;
                    // 二次贝塞尔曲线上点的计算 (主网和主网2之间,简单垂直线)
                    let x = 260 * Math.pow(1-t, 2) + 2 * 600 * (1-t) * t + 940 * Math.pow(t, 2);
                    let y1 = NET_BASE_Y * Math.pow(1-t, 2) + 2 * (cyMain-10) * (1-t) * t + NET_BASE_Y * Math.pow(t, 2);
                    let y2 = NET_BASE_Y * Math.pow(1-t, 2) + 2 * (cyMain+10) * (1-t) * t + NET_BASE_Y * Math.pow(t, 2);
                    verticalsHTML += `<line x1="${x}" y1="${y1}" x2="${x}" y2="${y2}" />`;
                }
                netVerticals.innerHTML = verticalsHTML;

                // 阻尼器与颜色反馈
                const loadPercent = Math.max(0, Math.min(100, ((deformY - NET_BASE_Y) / (NET_MAX_Y - NET_BASE_Y)) * 100));
                
                let damperColor = '#38bdf8'; // 默认蓝青
                let netStroke = '#38bdf8';
                let loadClass = 'glow';

                if (loadPercent > 70) {
                    damperColor = '#ef4444'; // 危险红
                    netStroke = '#ef4444';
                    loadClass = 'glow-red';
                } else if (loadPercent > 30) {
                    damperColor = '#f59e0b'; // 警告黄
                    netStroke = '#f59e0b';
                }

                // 应用颜色
                damperLeft.style.fill = damperColor;
                damperRight.style.fill = damperColor;
                damperLeft.setAttribute('class', loadClass);
                damperRight.setAttribute('class', loadClass);
                
                netMain1.style.stroke = netStroke;
                netMain1.setAttribute('class', `net-cable ${loadClass}`);

                // 阻尼器行程动画 (20 -> 60)
                const damperHeight = 20 + (loadPercent / 100) * 40;
                damperLeft.setAttribute('height', damperHeight);
                damperRight.setAttribute('height', damperHeight);

                return { loadPercent, deformY };
            }

            // 缓动函数
            function easeOutCubic(x) {
                return 1 - Math.pow(1 - x, 3);
            }
            function easeInOutSine(x) {
                return -(Math.cos(Math.PI * x) - 1) / 2;
            }

            function render(timestamp) {
                if (!startTime) startTime = timestamp;
                let elapsed = (timestamp - startTime) % DURATION;
                let t = elapsed / DURATION; // 0.0 to 1.0

                let rocketY = 0;
                let rocketVelocity = 0; // m/s 视觉近似
                let parafoilYOffset = 0;
                let parafoilOpacity = 1;
                let phaseStr = "";
                let textColor = "var(--text-main)";

                // 阶段分割设计
                // 0.0 - 0.35 : 盘旋滑翔 (缓降)
                // 0.35 - 0.45: 切伞与自由落体 (加速)
                // 0.45 - 0.60: 触网形变吸收 (极速减速)
                // 0.60 - 0.80: 回弹与姿态稳定 (阻尼震荡)
                // 0.80 - 1.00: 重置过渡

                if (t < 0.35) {
                    // 滑翔
                    let pt = t / 0.35;
                    rocketY = -150 + pt * 350; // -150 到 200
                    rocketVelocity = 15; // 稳态速度
                    phaseStr = "PARAFOIL GLIDE";
                    textColor = "var(--text-highlight)";
                } else if (t < 0.45) {
                    // 自由落体
                    let pt = (t - 0.35) / 0.10;
                    rocketY = 200 + Math.pow(pt, 2) * 190; // 200 到 390 (触网点)
                    rocketVelocity = 15 + pt * 15; // 加速至 30m/s (终端速度)
                    parafoilYOffset = -pt * 150; // 伞向上飘走
                    parafoilOpacity = 1 - pt;
                    phaseStr = "FREE FALL";
                    textColor = "var(--text-warning)";
                } else if (t < 0.60) {
                    // 触网耗能
                    let pt = (t - 0.45) / 0.15;
                    // 使用缓出模拟减速
                    rocketY = 390 + easeOutCubic(pt) * 250; // 390 到 640 (最大形变)
                    rocketVelocity = 30 * (1 - easeOutCubic(pt)); // 减速至0
                    parafoilOpacity = 0;
                    phaseStr = "ENERGY DISSIPATION";
                    textColor = "var(--text-danger)";
                } else if (t < 0.80) {
                    // 回弹稳定
                    let pt = (t - 0.60) / 0.20;
                    // 阻尼震荡:640 -> 540 -> 560
                    let damp = Math.exp(-pt * 5);
                    let osc = Math.cos(pt * Math.PI * 3);
                    rocketY = 560 + (80 * damp * osc); // 稳定在 560
                    rocketVelocity = 0;
                    parafoilOpacity = 0;
                    phaseStr = "SECURED";
                    textColor = "var(--text-success)";
                } else {
                    // 重置阶段
                    let pt = (t - 0.80) / 0.20;
                    rocketY = 560; // 保持
                    rocketVelocity = 0;
                    parafoilOpacity = 0;
                    // 淡出特效处理可在此处添加,为保持纯粹结构,仅改变透明度
                    vehicle.style.opacity = 1 - pt;
                    phaseStr = "SYSTEM RESET";
                    textColor = "var(--text-main)";
                    
                    if (pt > 0.95) {
                        vehicle.style.opacity = (pt - 0.95) * 20; // 极速淡入回来
                        rocketY = -150;
                        parafoilOpacity = 1;
                        parafoilYOffset = 0;
                    }
                }

                // 应用火箭位置
                if (t <= 0.80) {
                    vehicle.style.opacity = 1;
                }
                vehicle.setAttribute('transform', `translate(0, ${rocketY})`);
                
                // 应用滑翔伞状态
                parafoilGrp.setAttribute('transform', `translate(0, ${parafoilYOffset})`);
                parafoilGrp.style.opacity = parafoilOpacity;

                // 更新网的状态
                let { loadPercent, deformY } = updateNet(rocketY);

                // 更新遥测 UI
                let altitude = Math.max(0, 1000 - rocketY * 1.5).toFixed(1); // 伪造高度换算
                
                telPhase.textContent = phaseStr;
                telPhase.style.fill = textColor;
                
                telAlt.textContent = `${altitude} M`;
                telVel.textContent = `-${rocketVelocity.toFixed(1)} M/S`;
                
                let deformMeters = Math.max(0, (deformY - NET_BASE_Y) * 0.1).toFixed(1); // 伪造形变米数
                telDef.textContent = `${deformMeters} M`;
                
                telLoad.textContent = `${loadPercent.toFixed(0)} %`;
                telLoad.style.fill = loadPercent > 70 ? 'var(--text-danger)' : (loadPercent > 30 ? 'var(--text-warning)' : 'var(--text-success)');
                
                loadBar.setAttribute('width', (loadPercent / 100) * 180);
                loadBar.style.fill = telLoad.style.fill;

                requestAnimationFrame(render);
            }

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