分享图
动画工坊
引擎就绪

以下是为您设计的“赛博朋克/科幻风”无人机第一人称视角(FPV)实战演示动画。

该方案严格遵循 TRIZ 最终理想解(IFR)原则,通过光流视觉和动态界面直接展现“锁定、包覆、瞬间修复”的核心创新过程。视觉布局上,说明性文字和遥测数据均作为 HUD(平视显示器)微型字符紧贴屏幕边缘,将 80% 以上的核心视野留给十字准星与目标电网,确保沉浸感与视觉张力。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>双稳态智能绝缘抱箍 - FPV 无人机作业系统</title>
<style>
    @import url('https://fonts.googleapis.com/css2?family=Share+Tech+Mono&display=swap');

    :root {
        --color-bg: #03080a;
        --color-primary: #00ff66; /* 科技绿 */
        --color-secondary: #00d5ff; /* 科幻蓝 */
        --color-alert: #ff2a2a; /* 警示红 */
        --color-dark: #071a16;
        --hud-font: 'Share Tech Mono', 'Courier New', monospace;
    }

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

    body {
        background-color: #000;
        color: var(--color-primary);
        font-family: var(--hud-font);
        height: 100vh;
        display: flex;
        justify-content: center;
        align-items: center;
        overflow: hidden;
    }

    /* 核心主视场 */
    .fpv-container {
        position: relative;
        width: 100vw;
        height: 100vh;
        max-width: 1920px;
        background: radial-gradient(circle at center, #051318 0%, var(--color-bg) 100%);
        overflow: hidden;
        border: 1px solid rgba(0, 213, 255, 0.2);
        box-shadow: inset 0 0 150px rgba(0,0,0,0.9);
    }

    /* CRT扫描线与暗角滤镜 */
    .crt-overlay {
        position: absolute;
        inset: 0;
        background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.25) 50%), linear-gradient(90deg, rgba(255, 0, 0, 0.06), rgba(0, 255, 0, 0.02), rgba(0, 0, 255, 0.06));
        background-size: 100% 4px, 3px 100%;
        z-index: 100;
        pointer-events: none;
        mix-blend-mode: overlay;
    }
    
    .vignette {
        position: absolute;
        inset: 0;
        box-shadow: inset 0 0 200px rgba(0,0,0,0.9);
        z-index: 99;
        pointer-events: none;
    }

    /* 3D 网格地形 (模拟无人机飞行) */
    .terrain-grid {
        position: absolute;
        bottom: -20%;
        left: -50%;
        width: 200%;
        height: 80%;
        background-image: 
            linear-gradient(to right, rgba(0, 213, 255, 0.1) 1px, transparent 1px),
            linear-gradient(to top, rgba(0, 213, 255, 0.2) 1px, transparent 1px);
        background-size: 50px 50px;
        transform: perspective(600px) rotateX(75deg);
        transform-origin: top center;
        z-index: 1;
        animation: gridMove 2s linear infinite;
    }

    /* 物理世界视口 (包含电线杆和目标) */
    .world-view {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 10;
        transform-origin: center 55%; /* 视线焦点 */
        will-change: transform;
    }

    /* HUD 界面元素布局 */
    .hud-element {
        position: absolute;
        z-index: 80;
        font-size: 12px;
        line-height: 1.4;
        text-shadow: 0 0 4px var(--color-primary);
        opacity: 0.85;
    }

    .hud-tl { top: 30px; left: 40px; color: var(--color-secondary); text-shadow: 0 0 4px var(--color-secondary); }
    .hud-tr { top: 30px; right: 40px; text-align: right; }
    .hud-bl { bottom: 40px; left: 40px; }
    .hud-br { bottom: 40px; right: 40px; text-align: right; }
    
    .hud-box {
        border: 1px solid rgba(0,255,102,0.3);
        background: rgba(0,20,10,0.4);
        padding: 8px 12px;
        backdrop-filter: blur(2px);
    }

    /* 动态日志打字机效果 */
    .log-container { display: flex; flex-direction: column; gap: 4px; }
    .log-line { opacity: 0; }
    .log-line.active { opacity: 1; animation: fadeIn 0.2s ease-out; }

    /* 中央准星系统 */
    .reticle-container {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 600px;
        height: 600px;
        z-index: 50;
        pointer-events: none;
    }
    
    .crosshair {
        position: absolute;
        top: 50%; left: 50%;
        transform: translate(-50%, -50%);
        width: 150px; height: 150px;
        border: 1px solid rgba(0, 213, 255, 0.4);
        border-radius: 50%;
        transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
    }
    
    .crosshair::before, .crosshair::after {
        content: ''; position: absolute; background: var(--color-secondary);
    }
    .crosshair::before { top: 50%; left: -20px; right: -20px; height: 1px; }
    .crosshair::after { left: 50%; top: -20px; bottom: -20px; width: 1px; }
    
    .crosshair.locked {
        width: 80px; height: 80px;
        border-color: var(--color-alert);
        transform: translate(-50%, -50%) rotate(45deg);
    }
    .crosshair.locked::before, .crosshair.locked::after { background: var(--color-alert); }
    
    .crosshair.success {
        border-color: var(--color-primary);
        transform: translate(-50%, -50%) rotate(0deg) scale(1.2);
    }
    .crosshair.success::before, .crosshair.success::after { background: var(--color-primary); }

    /* 姿态仪刻度 */
    .pitch-ladder {
        position: absolute; top: 50%; left: 50%;
        transform: translate(-50%, -50%);
        width: 300px; height: 200px;
        border-left: 2px solid rgba(0, 213, 255, 0.3);
        border-right: 2px solid rgba(0, 213, 255, 0.3);
    }

    /* 状态提示中心文字 */
    .status-msg {
        position: absolute;
        top: calc(50% + 80px);
        left: 50%;
        transform: translateX(-50%);
        font-size: 14px;
        font-weight: bold;
        letter-spacing: 2px;
        text-align: center;
        opacity: 0;
        z-index: 90;
        padding: 4px 16px;
        background: rgba(0,0,0,0.8);
        border-left: 3px solid transparent;
        border-right: 3px solid transparent;
    }

    /* 物理世界SVG样式 */
    .svg-scene { width: 100%; height: 100%; }
    .wire-line { stroke: #334455; stroke-width: 2; }
    .pole-struct { fill: none; stroke: #1a3333; stroke-width: 4; stroke-linejoin: round; }
    .insulator { fill: #0a1a1a; stroke: #00d5ff; stroke-width: 2; }
    
    /* 目标绝缘子热力图 */
    .target-insulator { transition: stroke 0.3s; }
    .heat-glow {
        fill: var(--color-alert);
        opacity: 0;
        filter: blur(8px);
        transition: opacity 0.5s;
    }

    /* 双稳态抱箍动画 */
    .wrap-band {
        fill: none;
        stroke: var(--color-primary);
        stroke-width: 6;
        stroke-linecap: round;
        stroke-dasharray: 150;
        stroke-dashoffset: 150;
        filter: drop-shadow(0 0 6px var(--color-primary));
    }

    /* 动画与特效类 */
    .anim-shake { animation: cameraShake 0.3s cubic-bezier(.36,.07,.19,.97) both; }
    .anim-glitch { animation: chromaticGlitch 0.2s 3 alternate; }

    @keyframes gridMove {
        0% { background-position: 0 0; }
        100% { background-position: 0 50px; }
    }

    @keyframes fadeIn {
        from { opacity: 0; transform: translateY(5px); }
        to { opacity: 1; transform: translateY(0); }
    }

    @keyframes cameraShake {
        0% { transform: translate(0, 0) rotate(0deg); }
        20% { transform: translate(-8px, 6px) rotate(-1deg); }
        40% { transform: translate(6px, -8px) rotate(1deg); }
        60% { transform: translate(-6px, -4px) rotate(0deg); }
        80% { transform: translate(4px, 6px) rotate(-0.5deg); }
        100% { transform: translate(0, 0) rotate(0deg); }
    }

    @keyframes chromaticGlitch {
        0% { text-shadow: 2px 0 red, -2px 0 cyan; transform: scale(1.01) skewX(2deg); }
        50% { text-shadow: -2px 0 red, 2px 0 cyan; transform: scale(0.99) skewX(-2deg); }
        100% { text-shadow: 2px 0 red, -2px 0 cyan; transform: scale(1) skewX(0); }
    }

    /* 数据刷新动效 */
    .data-val { display: inline-block; min-width: 45px; }

</style>
</head>
<body>

<div class="fpv-container" id="sys-container">
    <div class="crt-overlay"></div>
    <div class="vignette"></div>
    
    <!-- 3D 飞行网格 -->
    <div class="terrain-grid" id="terrain"></div>

    <!-- HUD 界面层 -->
    <!-- 左上:系统链接与状态 -->
    <div class="hud-element hud-tl">
        <div>UAV FPV LINK // ACTIVE</div>
        <div>OPTICAL FLOW // 60HZ SYNCHRONIZED</div>
        <div>SYS_MODE // <span style="color:var(--color-primary)">AUTONOMOUS REPAIR</span></div>
        <div style="margin-top: 10px; width: 120px; height: 10px; border: 1px solid var(--color-secondary);">
            <div style="width: 100%; height: 100%; background: var(--color-secondary); animation: pulse 2s infinite;"></div>
        </div>
    </div>

    <!-- 右上:遥测环境数据 -->
    <div class="hud-element hud-tr">
        <div>ALTITUDE : <span class="data-val" id="val-alt">15.2</span> M</div>
        <div>SPEED    : <span class="data-val" id="val-spd">4.5</span> M/S</div>
        <div>WIND     : <span class="data-val" id="val-wnd">2.1</span> M/S</div>
        <div>EMF TENSION: <span class="data-val" id="val-emf">0.65</span> µT</div>
        <div style="margin-top:5px; color: var(--color-alert);" id="val-heat">PEAK TEMP: 32℃</div>
    </div>

    <!-- 左下:操作终端日志 -->
    <div class="hud-element hud-bl hud-box" style="width: 280px; height: 110px;">
        <div class="log-container" id="terminal-log">
            <!-- 日志通过JS动态注入 -->
        </div>
    </div>

    <!-- 右下:辅助雷达及参数 -->
    <div class="hud-element hud-br">
        <div>BISTABLE_TAPE_DEPLOYMENT_SYS: READY</div>
        <div>TENSION_RESERVE: 100%</div>
        <div>STRUCTURAL_INTEGRITY: OPTIMAL</div>
        <svg width="80" height="80" style="margin-top:10px;">
            <circle cx="40" cy="40" r="35" fill="none" stroke="rgba(0,255,102,0.3)" stroke-width="1"/>
            <circle cx="40" cy="40" r="20" fill="none" stroke="rgba(0,255,102,0.3)" stroke-width="1" stroke-dasharray="4 4"/>
            <line x1="40" y1="5" x2="40" y2="75" stroke="rgba(0,255,102,0.2)"/>
            <line x1="5" y1="40" x2="75" y2="40" stroke="rgba(0,255,102,0.2)"/>
            <path d="M40,40 L65,15 A35,35 0 0,1 75,40 Z" fill="rgba(0,255,102,0.2)">
                <animateTransform attributeName="transform" type="rotate" from="0 40 40" to="360 40 40" dur="2s" repeatCount="indefinite"/>
            </path>
            <!-- 目标小红点 -->
            <circle cx="55" cy="25" r="2" fill="var(--color-alert)" id="radar-blip" opacity="0"/>
        </svg>
    </div>

    <!-- 准星与姿态 -->
    <div class="reticle-container">
        <div class="pitch-ladder">
            <div style="position:absolute; top:20%; left:-10px; width:10px; height:1px; background:rgba(0,213,255,0.5)"></div>
            <div style="position:absolute; top:20%; right:-10px; width:10px; height:1px; background:rgba(0,213,255,0.5)"></div>
            <div style="position:absolute; top:80%; left:-10px; width:10px; height:1px; background:rgba(0,213,255,0.5)"></div>
            <div style="position:absolute; top:80%; right:-10px; width:10px; height:1px; background:rgba(0,213,255,0.5)"></div>
        </div>
        <div class="crosshair" id="main-crosshair"></div>
    </div>

    <!-- 核心状态提示词 (置于中央准星下方) -->
    <div class="status-msg" id="status-msg"></div>

    <!-- 物理视口:10kV 电线杆与智能修复动作 -->
    <div class="world-view" id="world">
        <svg class="svg-scene" viewBox="0 0 1000 600" preserveAspectRatio="xMidYMid slice">
            <g id="pole-system" transform="translate(500, 320) scale(0.2)" transform-origin="0 0">
                <!-- 远景高压线 -->
                <path class="wire-line" d="M -2000, -50 Q 0, 50 2000, -50" />
                <path class="wire-line" d="M -2000, -150 Q 0, -20 2000, -150" />
                
                <!-- 电线杆主体结构 (线框科幻风) -->
                <path class="pole-struct" d="M -20, 400 L -20, -100 L 20, -100 L 20, 400 Z" />
                <!-- 横担 -->
                <path class="pole-struct" d="M -250, -80 L 250, -80 L 250, -100 L -250, -100 Z" />
                
                <!-- 左侧正常绝缘子 -->
                <g transform="translate(-200, -140)">
                    <rect x="-15" y="0" width="30" height="40" rx="4" class="insulator" />
                    <line x1="-25" y1="10" x2="25" y2="10" stroke="#00d5ff" stroke-width="2"/>
                    <line x1="-25" y1="25" x2="25" y2="25" stroke="#00d5ff" stroke-width="2"/>
                </g>
                
                <!-- 右侧正常绝缘子 -->
                <g transform="translate(200, -140)">
                    <rect x="-15" y="0" width="30" height="40" rx="4" class="insulator" />
                    <line x1="-25" y1="10" x2="25" y2="10" stroke="#00d5ff" stroke-width="2"/>
                    <line x1="-25" y1="25" x2="25" y2="25" stroke="#00d5ff" stroke-width="2"/>
                </g>

                <!-- 中央故障绝缘子 (目标) -->
                <g transform="translate(0, -150)" id="target-node">
                    <!-- 热力学故障发光层 -->
                    <circle cx="0" cy="20" r="35" class="heat-glow" id="target-heat" />
                    
                    <!-- 绝缘子主体 -->
                    <rect x="-15" y="0" width="30" height="40" rx="4" class="insulator target-insulator" id="target-body" />
                    <line x1="-25" y1="10" x2="25" y2="10" stroke="#00d5ff" stroke-width="2" class="target-insulator" id="target-rib1"/>
                    <line x1="-25" y1="25" x2="25" y2="25" stroke="#00d5ff" stroke-width="2" class="target-insulator" id="target-rib2"/>

                    <!-- 动态断裂纹理 (初始隐藏) -->
                    <path d="M -10,0 L 5,15 L -5,25 L 10,40" stroke="var(--color-alert)" stroke-width="2" fill="none" opacity="0" id="target-crack" />

                    <!-- 双稳态绝缘带 (关键构件:两条协同包覆) -->
                    <!-- 顶端带 -->
                    <path id="wrap-top" class="wrap-band" d="M -35,10 C -15,-5 15,-5 35,10" />
                    <!-- 底端带 -->
                    <path id="wrap-bottom" class="wrap-band" d="M -35,30 C -15,45 15,45 35,30" />
                </g>
            </g>
        </svg>
    </div>
</div>

<script>
document.addEventListener('DOMContentLoaded', () => {
    // 节点获取
    const world = document.getElementById('world');
    const poleSystem = document.getElementById('pole-system');
    const crosshair = document.getElementById('main-crosshair');
    const statusMsg = document.getElementById('status-msg');
    const terminal = document.getElementById('terminal-log');
    const sysContainer = document.getElementById('sys-container');
    const heatGlow = document.getElementById('target-heat');
    const targetCrack = document.getElementById('target-crack');
    const targetBody = document.getElementById('target-body');
    const targetRib1 = document.getElementById('target-rib1');
    const targetRib2 = document.getElementById('target-rib2');
    const wrapTop = document.getElementById('wrap-top');
    const wrapBottom = document.getElementById('wrap-bottom');
    const radarBlip = document.getElementById('radar-blip');
    const heatVal = document.getElementById('val-heat');
    const terrain = document.getElementById('terrain');

    // 动态遥测数据模拟 (60Hz)
    let alt = 15.2, spd = 4.5, wnd = 2.1, emf = 0.65;
    const hudInterval = setInterval(() => {
        alt += (Math.random() - 0.5) * 0.1;
        spd += (Math.random() - 0.5) * 0.2;
        wnd += (Math.random() - 0.5) * 0.3;
        emf += (Math.random() - 0.5) * 0.05;
        document.getElementById('val-alt').innerText = alt.toFixed(1);
        document.getElementById('val-spd').innerText = Math.abs(spd).toFixed(1);
        document.getElementById('val-wnd').innerText = Math.abs(wnd).toFixed(1);
        document.getElementById('val-emf').innerText = Math.abs(emf).toFixed(2);
    }, 1000/60); // 60Hz 刷新率

    // 终端日志打印工具
    let logCount = 0;
    function addLog(text, color = 'var(--color-primary)') {
        const div = document.createElement('div');
        div.className = 'log-line active';
        div.style.color = color;
        div.innerText = `> ${text}`;
        terminal.appendChild(div);
        if(terminal.children.length > 5) terminal.removeChild(terminal.firstChild);
    }

    // 设置状态消息
    function setStatus(msg, type) {
        statusMsg.innerText = msg;
        statusMsg.style.opacity = '1';
        if(type === 'alert') {
            statusMsg.style.color = 'var(--color-alert)';
            statusMsg.style.borderColor = 'var(--color-alert)';
            sysContainer.classList.add('anim-glitch');
            setTimeout(() => sysContainer.classList.remove('anim-glitch'), 600);
        } else if(type === 'success') {
            statusMsg.style.color = 'var(--color-primary)';
            statusMsg.style.borderColor = 'var(--color-primary)';
        } else {
            statusMsg.style.color = 'var(--color-secondary)';
            statusMsg.style.borderColor = 'var(--color-secondary)';
        }
    }

    // 核心动画序列 (重开即播)
    function runSequence() {
        // [初始状态重置]
        poleSystem.style.transform = "translate(500px, 320px) scale(0.2)";
        poleSystem.style.transition = "none";
        crosshair.className = "crosshair";
        statusMsg.style.opacity = '0';
        heatGlow.style.opacity = '0';
        targetCrack.style.opacity = '0';
        targetBody.style.stroke = "#00d5ff";
        targetRib1.style.stroke = "#00d5ff";
        targetRib2.style.stroke = "#00d5ff";
        wrapTop.style.transition = "none";
        wrapBottom.style.transition = "none";
        wrapTop.style.strokeDashoffset = "150";
        wrapBottom.style.strokeDashoffset = "150";
        radarBlip.setAttribute("opacity", "0");
        heatVal.innerText = "PEAK TEMP: 32℃";
        heatVal.style.color = "var(--color-primary)";
        terrain.style.animationPlayState = 'running';
        terminal.innerHTML = "";
        
        // --- 时序开始 ---
        
        // T=0s: 无人机推进,视野拉近
        setTimeout(() => {
            addLog("光流环境感知启动...");
            poleSystem.style.transition = "transform 3s cubic-bezier(0.25, 1, 0.5, 1)";
            poleSystem.style.transform = "translate(500px, 320px) scale(1.6)"; // 放大电线杆
            setStatus("SCANNING // 扫描10kV线路...", "info");
        }, 100);

        // T=1.5s: 传感器检测到异常,热力图升高
        setTimeout(() => {
            radarBlip.setAttribute("opacity", "1"); // 雷达出现红点
            heatGlow.style.opacity = '0.8';
            targetCrack.style.opacity = '1';
            targetBody.style.stroke = "var(--color-alert)";
            targetRib1.style.stroke = "var(--color-alert)";
            targetRib2.style.stroke = "var(--color-alert)";
            
            // 快速更新热力数据
            let temp = 32;
            let tempInterval = setInterval(() => {
                temp += 5;
                heatVal.innerText = `PEAK TEMP: ${temp}℃`;
                if(temp >= 68) {
                    clearInterval(tempInterval);
                    heatVal.style.color = "var(--color-alert)";
                }
            }, 50);

            addLog("红外传感器捕捉高热异常", "var(--color-alert)");
            setStatus("异常识别:断裂绝缘子,温度 > 65℃", "alert");
        }, 1500);

        // T=3.0s: 准星锁定目标 (动画时长0.5s)
        setTimeout(() => {
            crosshair.classList.add("locked");
            addLog("计算空间包覆轨迹...");
            setStatus("目标已锁定,准备实施空间包覆", "success");
        }, 3000);

        // T=4.0s: 触发修复动作,双稳态抱箍弹出 (解决矛盾的核心动作)
        setTimeout(() => {
            // 画面微震增加真实感
            sysContainer.classList.add("anim-shake");
            terrain.style.animationPlayState = 'paused'; // 悬停
            addLog("触发双稳态动作,材料释能包覆!", "var(--color-primary)");
            
            // 抱箍弹射包裹动画 (利用势能瞬发)
            wrapTop.style.transition = "stroke-dashoffset 0.15s ease-out";
            wrapBottom.style.transition = "stroke-dashoffset 0.15s ease-out 0.05s";
            wrapTop.style.strokeDashoffset = "0";
            wrapBottom.style.strokeDashoffset = "0";

            // 故障点降温被绝缘
            setTimeout(() => {
                heatGlow.style.opacity = '0';
                targetBody.style.stroke = "var(--color-primary)";
                targetRib1.style.stroke = "var(--color-primary)";
                targetRib2.style.stroke = "var(--color-primary)";
                heatVal.innerText = "PEAK TEMP: 25℃";
                heatVal.style.color = "var(--color-primary)";
                radarBlip.setAttribute("opacity", "0");
                crosshair.classList.replace("locked", "success");
            }, 200);

            setTimeout(() => sysContainer.classList.remove("anim-shake"), 300);
        }, 4000);

        // T=5.2s: 展示最终理想解
        setTimeout(() => {
            setStatus("修复完成,用时1.2秒,电网零波动", "success");
            addLog("绝缘层重建完毕,威胁解除。");
        }, 5200);

        // T=7.0s: 帅气拉高返航 (循环演示)
        setTimeout(() => {
            addLog("任务完成,执行爬升返航...");
            terrain.style.animationPlayState = 'running';
            poleSystem.style.transition = "transform 2s cubic-bezier(0.5, 0, 0.1, 1)";
            poleSystem.style.transform = "translate(500px, 800px) scale(4)"; // 向下移出视野
            crosshair.className = "crosshair";
            statusMsg.style.opacity = '0';
            
            // 9秒后重置循环
            setTimeout(runSequence, 2000);
        }, 7000);
    }

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