• ybqx1314

    难道gemini真的王朝了

    🖼️预览

    图片

    💻代码```
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>鹈鹕翘头骑自行车牵引波音747 - SVG 2D动画</title>
    <script src="https://cdn.tailwindcss.com"></script&gt;
    <style>
    @import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@500;700;900&display=swap');

    • {

    box-sizing: border-box;
    user-select: none;
    -webkit-user-select: none;
    }

    body {
    margin: 0;
    padding: 0;
    font-family: 'Noto Sans SC', system-ui, -apple-system, sans-serif;
    background: #0f172a;
    color: #f8fafc;
    overflow-x: hidden;
    }

    .scene-container {
    box-shadow: 0 25px 60px -15px rgba(0, 0, 0, 0.7), 0 0 0 1px rgba(255, 255, 255, 0.12);
    }

    / Engine turbine spin animation /
    @keyframes spinFast {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
    }

    .turbine-spin {
    transform-box: fill-box;
    transform-origin: center;
    animation: spinFast 0.18s linear infinite;
    }

    / Interactive cursor for draggable 747 /
    #boeing-747-group {
    cursor: grab;
    transition: filter 0.2s ease;
    }
    #boeing-747-group:hover {
    filter: drop-shadow(0 0 12px rgba(255, 255, 255, 0.55));
    }
    #boeing-747-group:active {
    cursor: grabbing;
    }

    / Custom range slider styling /
    input[type="range"] {
    accent-color: #f59e0b;
    }
    </style>
    </head>
    <body class="min-h-screen flex flex-col items-center justify-between p-3 sm:p-5 bg-gradient-to-b from-slate-950 via-slate-900 to-slate-950">

    <!-- Top Header Bar -->
    <header class="w-full max-w-6xl flex flex-wrap items-center justify-between gap-3 mb-3 px-2">
    <div class="flex items-center gap-3">
    <div class="w-10 h-10 rounded-xl bg-gradient-to-br from-amber-400 to-orange-600 flex items-center justify-center shadow-lg shadow-orange-500/30 text-xl font-black text-slate-950">
    🦩
    </div>
    <div>
    <h1 class="text-lg sm:text-2xl font-black tracking-tight bg-gradient-to-r from-amber-200 via-orange-300 to-sky-300 bg-clip-text text-transparent">
    鹈鹕单轮翘头骑行 × 牵引波音747
    </h1>
    <p class="text-xs sm:text-sm text-slate-400">
    2D 物理联动骨骼与悬链线动画 · 支持鼠标/触控直接拖拽空中的波音747
    </p>
    </div>
    </div>

    <!-- Real-time Telemetry Pill -->
    <div class="flex items-center gap-2 sm:gap-3 bg-slate-900/90 border border-slate-700/80 px-3.5 py-2 rounded-2xl text-xs sm:text-sm shadow-inner">
    <span class="flex items-center gap-1.5 text-amber-400 font-bold">
    <span class="w-2 h-2 rounded-full bg-amber-400 animate-ping"></span>
    翘头倾角: <strong id="pitch-readout" class="font-mono">27.5°</strong>
    </span>
    <span class="text-slate-600">|</span>
    <span class="text-sky-300 font-bold">
    牵引拉力: <strong id="tension-readout" class="font-mono">42.8 kN</strong>
    </span>
    <span class="text-slate-600 hidden sm:inline">|</span>
    <span class="text-emerald-400 font-bold hidden sm:inline">
    地速: <strong id="speed-readout" class="font-mono">38 km/h</strong>
    </span>
    </div>
    </header>

    <!-- Main SVG Animation Viewport -->
    <main class="w-full max-w-6xl flex-1 flex items-center justify-center">
    <div class="scene-container relative w-full aspect-[16/10] max-h-[74vh] rounded-3xl overflow-hidden bg-sky-900 border border-slate-700/70">
    <svg
    id="main-svg"
    viewBox="0 0 1280 800"
    preserveAspectRatio="xMidYMid slice"
    class="w-full h-full block"
    xmlns="http://www.w3.org/2000/svg&quot;

    <defs>
    <!-- Sky Gradients for Day / Sunset / Night -->
    <linearGradient id="sky-grad-day" x1="0%" y1="0%" x2="0%" y2="100%">
    <stop offset="0%" stop-color="#0284c7" />
    <stop offset="48%" stop-color="#38bdf8" />
    <stop offset="85%" stop-color="#bae6fd" />
    <stop offset="100%" stop-color="#fef3c7" />
    </linearGradient>

    <linearGradient id="sky-grad-sunset" x1="0%" y1="0%" x2="0%" y2="100%">
    <stop offset="0%" stop-color="#1e1b4b" />
    <stop offset="35%" stop-color="#7c2d12" />
    <stop offset="70%" stop-color="#ea580c" />
    <stop offset="92%" stop-color="#facc15" />
    <stop offset="100%" stop-color="#fef08a" />
    </linearGradient>

    <linearGradient id="sky-grad-night" x1="0%" y1="0%" x2="0%" y2="100%">
    <stop offset="0%" stop-color="#020617" />
    <stop offset="50%" stop-color="#0f172a" />
    <stop offset="88%" stop-color="#1e293b" />
    <stop offset="100%" stop-color="#334155" />
    </linearGradient>

    <!-- Sun / Moon Glow -->
    <radialGradient id="sun-glow" cx="50%" cy="50%" r="50%">
    <stop offset="0%" stop-color="#fffbeb" stop-opacity="1" />
    <stop offset="35%" stop-color="#fde047" stop-opacity="0.9" />
    <stop offset="70%" stop-color="#f97316" stop-opacity="0.3" />
    <stop offset="100%" stop-color="#f97316" stop-opacity="0" />
    </radialGradient>

    <!-- Distant Mountains Gradient -->
    <linearGradient id="mountain-far" x1="0%" y1="0%" x2="0%" y2="100%">
    <stop offset="0%" stop-color="#64748b" stop-opacity="0.55" />
    <stop offset="100%" stop-color="#94a3b8" stop-opacity="0.2" />
    </linearGradient>

    <linearGradient id="mountain-near" x1="0%" y1="0%" x2="0%" y2="100%">
    <stop offset="0%" stop-color="#334155" stop-opacity="0.75" />
    <stop offset="100%" stop-color="#475569" stop-opacity="0.9" />
    </linearGradient>

    <!-- Road Asphalt Gradient -->
    <linearGradient id="road-grad" x1="0%" y1="0%" x2="0%" y2="100%">
    <stop offset="0%" stop-color="#334155" />
    <stop offset="15%" stop-color="#1e293b" />
    <stop offset="85%" stop-color="#0f172a" />
    <stop offset="100%" stop-color="#020617" />
    </linearGradient>

    <!-- Pelican Pouch (Gular Pouch) Gradient -->
    <linearGradient id="pouch-grad" x1="0%" y1="0%" x2="100%" y2="100%">
    <stop offset="0%" stop-color="#fbbf24" />
    <stop offset="55%" stop-color="#f97316" />
    <stop offset="100%" stop-color="#ea580c" />
    </linearGradient>

    <!-- Pelican Upper Beak Gradient -->
    <linearGradient id="beak-grad" x1="0%" y1="0%" x2="100%" y2="0%">
    <stop offset="0%" stop-color="#fde047" />
    <stop offset="75%" stop-color="#f59e0b" />
    <stop offset="100%" stop-color="#dc2626" />
    </linearGradient>

    <!-- Pelican Feather Body Gradient -->
    <linearGradient id="pelican-body-grad" x1="0%" y1="0%" x2="0%" y2="100%">
    <stop offset="0%" stop-color="#ffffff" />
    <stop offset="70%" stop-color="#f1f5f9" />
    <stop offset="100%" stop-color="#cbd5e1" />
    </linearGradient>

    <!-- Bike Frame Metallic Red/Orange Gradient -->
    <linearGradient id="bike-frame-grad" x1="0%" y1="0%" x2="100%" y2="100%">
    <stop offset="0%" stop-color="#ef4444" />
    <stop offset="50%" stop-color="#dc2626" />
    <stop offset="100%" stop-color="#991b1b" />
    </linearGradient>

    <!-- Chrome / Alloy Rim Gradient -->
    <linearGradient id="chrome-grad" x1="0%" y1="0%" x2="100%" y2="100%">
    <stop offset="0%" stop-color="#f8fafc" />
    <stop offset="50%" stop-color="#94a3b8" />
    <stop offset="100%" stop-color="#475569" />
    </linearGradient>

    <!-- Boeing 747 Fuselage Metallic White/Silver Gradient -->
    <linearGradient id="b747-fuselage-grad" x1="0%" y1="0%" x2="0%" y2="100%">
    <stop offset="0%" stop-color="#ffffff" />
    <stop offset="58%" stop-color="#f8fafc" />
    <stop offset="82%" stop-color="#cbd5e1" />
    <stop offset="100%" stop-color="#64748b" />
    </linearGradient>

    <!-- Boeing 747 Tail Fin Blue/Gold Livery Gradient -->
    <linearGradient id="b747-tail-grad" x1="0%" y1="0%" x2="100%" y2="100%">
    <stop offset="0%" stop-color="#0284c7" />
    <stop offset="55%" stop-color="#1d4ed8" />
    <stop offset="100%" stop-color="#1e3a8a" />
    </linearGradient>

    <!-- Jet Contrail / Exhaust Gradient -->
    <linearGradient id="jet-exhaust-grad" x1="100%" y1="0%" x2="0%" y2="0%">
    <stop offset="0%" stop-color="#38bdf8" stop-opacity="0.85" />
    <stop offset="25%" stop-color="#e0f2fe" stop-opacity="0.65" />
    <stop offset="70%" stop-color="#ffffff" stop-opacity="0.25" />
    <stop offset="100%" stop-color="#ffffff" stop-opacity="0" />
    </linearGradient>

    <!-- Rope Pattern for Braided Look -->
    <linearGradient id="rope-grad" x1="0%" y1="0%" x2="100%" y2="0%">
    <stop offset="0%" stop-color="#d97706" />
    <stop offset="50%" stop-color="#fde68a" />
    <stop offset="100%" stop-color="#b45309" />
    </linearGradient>

    <!-- Soft Shadow Filter -->
    <filter id="drop-shadow" x="-15%" y="-15%" width="135%" height="135%">
    <feDropShadow dx="0" dy="8" stdDeviation="6" flood-color="#0f172a" flood-opacity="0.35" />
    </filter>
    </defs>

    <!-- 1. SKY BACKGROUND -->
    <rect id="sky-rect" x="0" y="0" width="1280" height="650" fill="url(#sky-grad-day)" />

    <!-- Night Stars Layer (visible in night/sunset modes) -->
    <g id="stars-layer" opacity="0" style="transition: opacity 0.6s ease;">
    <circle cx="120" cy="80" r="1.8" fill="#fff" />
    <circle cx="290" cy="45" r="2.4" fill="#fde047" />
    <circle cx="460" cy="110" r="1.5" fill="#fff" />
    <circle cx="650" cy="60" r="2.2" fill="#fff" />
    <circle cx="820" cy="40" r="1.6" fill="#bae6fd" />
    <circle cx="1040" cy="95" r="2.5" fill="#fde047" />
    <circle cx="1180" cy="50" r="1.7" fill="#fff" />
    <circle cx="200" cy="160" r="1.4" fill="#fff" />
    <circle cx="540" cy="180" r="2.0" fill="#fff" />
    <circle cx="950" cy="155" r="1.5" fill="#fff" />
    </g>

    <!-- Sun / Celestial Body -->
    <g id="sun-group" transform="translate(210, 145)">
    <circle cx="0" cy="0" r="95" fill="url(#sun-glow)" />
    <circle cx="0" cy="0" r="42" fill="#fef9c3" />
    </g>

    <!-- 2. PARALLAX CLOUDS (Far & Mid Sky) -->
    <g id="clouds-far-layer" opacity="0.72">
    <g class="cloud-item" data-speed="0.35" data-x="150" data-y="110" data-scale="0.85">
    <path d="M0,0 Q20,-28 52,-18 Q80,-45 120,-20 Q158,-30 175,-2 Q205,2 200,26 Q195,42 165,42 L-10,42 Q-35,42 -30,18 Q-25,0 0,0 Z" fill="#ffffff" />
    </g>
    <g class="cloud-item" data-speed="0.28" data-x="680" data-y="75" data-scale="0.65">
    <path d="M0,0 Q20,-28 52,-18 Q80,-45 120,-20 Q158,-30 175,-2 Q205,2 200,26 Q195,42 165,42 L-10,42 Q-35,42 -30,18 Q-25,0 0,0 Z" fill="#ffffff" />
    </g>
    <g class="cloud-item" data-speed="0.42" data-x="1090" data-y="135" data-scale="0.95">
    <path d="M0,0 Q20,-28 52,-18 Q80,-45 120,-20 Q158,-30 175,-2 Q205,2 200,26 Q195,42 165,42 L-10,42 Q-35,42 -30,18 Q-25,0 0,0 Z" fill="#ffffff" />
    </g>
    </g>

    <!-- Distant Mountain Range (Scrolling slowly left) -->
    <g id="mountains-far" transform="translate(0, 0)">
    <path d="M-100,640 L110,455 L280,565 L490,410 L710,550 L920,435 L1140,560 L1320,445 L1520,570 L1700,420 L1950,640 Z" fill="url(#mountain-far)" />
    </g>
    <g id="mountains-near" transform="translate(0, 0)">
    <path d="M-150,640 L60,520 L230,590 L420,485 L640,585 L830,500 L1050,590 L1240,490 L1460,580 L1680,495 L1900,640 Z" fill="url(#mountain-near)" />
    </g>

    <!-- 3. ROAD & GROUND LAYER -->
    <g id="ground-layer">
    <!-- Roadside Grass Verge -->
    <rect x="0" y="622" width="1280" height="18" fill="#16a34a" />
    <rect x="0" y="636" width="1280" height="6" fill="#15803d" />

    <!-- Main Asphalt Road -->
    <rect x="0" y="640" width="1280" height="160" fill="url(#road-grad)" />

    <!-- Road Top Shoulder Line -->
    <line x1="0" y1="646" x2="1280" y2="646" stroke="#cbd5e1" stroke-width="3" stroke-opacity="0.6" />

    <!-- Scrolling Center Dashed Yellow Road Lines -->
    <g id="road-dashes"></g>

    <!-- Scrolling Roadside Milestones, Shrubs & Pebbles -->
    <g id="road-props"></g>

    <!-- Dynamic Ground Shadow directly under Rear Wheel & Bike -->
    <ellipse id="bike-ground-shadow" cx="370" cy="656" rx="88" ry="11" fill="#020617" opacity="0.55" />
    <!-- Shadow of the 747 far on the road -->
    <ellipse id="plane-ground-shadow" cx="920" cy="662" rx="145" ry="9" fill="#020617" opacity="0.24" />
    </g>

    <!-- 4. BOEING 747 IN THE SKY (Towed by Rope, Facing Right) -->
    <g id="boeing-747-group" filter="url(#drop-shadow)" transform="translate(910, 175) rotate(-8)">
    <!-- Jet Engine Contrails / Airflow Streaks (Streaming Left behind engines) -->
    <g id="jet-contrails">
    <path id="contrail-1" d="M-65,42 Q-210,48 -380,38" stroke="url(#jet-exhaust-grad)" stroke-width="14" stroke-linecap="round" fill="none" />
    <path id="contrail-2" d="M-15,56 Q-180,64 -340,54" stroke="url(#jet-exhaust-grad)" stroke-width="18" stroke-linecap="round" fill="none" />
    <path id="contrail-3" d="M25,22 Q-120,25 -260,18" stroke="url(#jet-exhaust-grad)" stroke-width="11" stroke-linecap="round" fill="none" />
    </g>

    <!-- Far-side (Port/Left) Swept Wing & Far Engines (Behind Fuselage) -->
    <g id="b747-far-wing">
    <!-- Far Wing Surface -->
    <path d="M-20,6 L-125,-34 L-152,-32 L-75,14 Z" fill="#94a3b8" stroke="#475569" stroke-width="1.5" />
    <!-- Winglet Far -->
    <path d="M-125,-34 L-138,-48 L-152,-32 Z" fill="#1d4ed8" />
    <!-- Far Engine #1 -->
    <g transform="translate(-95, -18)">
    <rect x="-16" y="-7" width="28" height="14" rx="5" fill="#64748b" stroke="#334155" stroke-width="1.2" />
    <ellipse cx="12" cy="0" rx="3.5" ry="6.5" fill="#1e293b" />
    </g>
    </g>

    <!-- Tail Horizontal Stabilizer (Far side) -->
    <path d="M-215,2 L-272,-12 L-285,-8 L-240,8 Z" fill="#94a3b8" />

    <!-- Iconic Tall Swept Vertical Stabilizer (Tail Fin) -->
    <g id="b747-tail-fin">
    <path d="M-175,-6 L-248,-108 L-282,-108 L-246,4 Z" fill="url(#b747-tail-grad)" stroke="#1e3a8a" stroke-width="2" />
    <!-- Decorative Airline Golden Speedbird / Globe Emblem on Tail -->
    <path d="M-208,-48 Q-235,-52 -260,-78 Q-238,-42 -222,-32 Z" fill="#fbbf24" />
    <circle cx="-238" cy="-65" r="8" fill="#fde047" opacity="0.9" />
    <!-- Rudder Divider Line -->
    <line x1="-256" y1="-108" x2="-232" y2="-2" stroke="#93c5fd" stroke-width="1.2" stroke-opacity="0.6" />
    </g>

    <!-- MAIN FUSELAGE with Iconic Boeing 747 Upper Deck Hump ("Queen of the Skies" 鹅头双层隆起) -->
    <!-- Facing Right: Tail is on Left (-265), Nose Cone is on Right (+215) -->
    <path
    d="M -265,2
    L -235,-8
    L -70,-12
    C -30,-12, 5,-28, 42,-32
    C 85,-35, 128,-33, 152,-20
    C 168,-11, 182,-4, 198,3
    C 218,11, 224,20, 212,27
    C 198,35, 165,38, 120,38
    L -145,36
    C -195,35, -242,20, -265,8
    Z"
    fill="url(#b747-fuselage-grad)"
    stroke="#334155"
    stroke-width="2.2"
    />

    <!-- Classic Airline Red & Blue Cheatline Stripe along Fuselage -->
    <path
    d="M -252,4 L 198,12 C 208,15 212,19 208,22 L -246,12 Z"
    fill="#dc2626"
    />
    <path
    d="M -246,12 L 208,22 C 204,25 196,27 185,27 L -238,18 Z"
    fill="#1d4ed8"
    />

    <!-- Nose Radome Cone Shading (Right Tip) -->
    <path
    d="M 196,2 C 216,10, 224,20, 212,27 C 204,31, 196,33, 190,34 C 194,22, 195,12, 196,2 Z"
    fill="#1e293b"
    />

    <!-- Cockpit Windshield Windows (Nestled on the front slope of the 747 Upper Deck Hump!) -->
    <path
    d="M 135,-24 L 154,-16 L 150,-8 L 130,-12 Z"
    fill="#0f172a"
    stroke="#38bdf8"
    stroke-width="1.2"
    />
    <line x1="142" y1="-21" x2="140" y2="-10" stroke="#94a3b8" stroke-width="1.2" />

    <!-- Iconic Upper Deck Passenger Windows (2nd Floor Hump Windows!) -->
    <g fill="#0f172a" stroke="#64748b" stroke-width="0.8">
    <rect x="42" y="-23" width="6" height="8" rx="2.5" />
    <rect x="54" y="-23" width="6" height="8" rx="2.5" />
    <rect x="66" y="-23" width="6" height="8" rx="2.5" />
    <rect x="78" y="-23" width="6" height="8" rx="2.5" />
    <rect x="90" y="-23" width="6" height="8" rx="2.5" />
    <rect x="102" y="-22" width="6" height="8" rx="2.5" />
    <rect x="114" y="-21" width="6" height="8" rx="2.5" />
    </g>

    <!-- Main Deck Passenger Windows & Cabin Doors -->
    <g fill="#0f172a">
    <!-- Forward Section Windows -->
    <rect x="155" y="0" width="5.5" height="7.5" rx="2" />
    <rect x="143" y="0" width="5.5" height="7.5" rx="2" />
    <rect x="131" y="0" width="5.5" height="7.5" rx="2" />
    <rect x="119" y="0" width="5.5" height="7.5" rx="2" />
    <!-- Door 1 -->
    <rect x="102" y="-3" width="10" height="16" rx="2" fill="none" stroke="#475569" stroke-width="1.3" />
    <!-- Mid Section Windows -->
    <rect x="85" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="73" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="61" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="49" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="37" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="25" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="13" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="1" y="-1" width="5.5" height="7.5" rx="2" />
    <!-- Door 2 -->
    <rect x="-15" y="-3" width="10" height="16" rx="2" fill="none" stroke="#475569" stroke-width="1.3" />
    <!-- Aft Section Windows -->
    <rect x="-32" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="-44" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="-56" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="-68" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="-80" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="-92" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="-104" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="-116" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="-128" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="-140" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="-152" y="-1" width="5.5" height="7.5" rx="2" />
    <rect x="-164" y="-1" width="5.5" height="7.5" rx="2" />
    <!-- Aft Door -->
    <rect x="-184" y="-3" width="10" height="16" rx="2" fill="none" stroke="#475569" stroke-width="1.3" />
    </g>

    <!-- "747 PELICAN AIR" Fuselage Title -->
    <text x="-35" y="-13" font-size="9.5" font-weight="900" fill="#1e3a8a" letter-spacing="1.5">BOEING 747-400</text>

    <!-- Near-Side (Starboard/Right) Swept Main Wing & Two Big Underwing Turbofan Engines -->
    <g id="b747-near-wing">
    <!-- Wing Root Fairing -->
    <ellipse cx="15" cy="28" rx="58" ry="9" fill="#e2e8f0" stroke="#94a3b8" stroke-width="1" />

    <!-- Swept Main Wing Surface (extending back and down-left in perspective) -->
    <path
    d="M 55,22 L -95,62 L -132,60 L -25,20 Z"
    fill="#f1f5f9"
    stroke="#475569"
    stroke-width="2"
    />
    <!-- Wing Flap Corrugations -->
    <line x1="-10" y1="28" x2="-102" y2="57" stroke="#94a3b8" stroke-width="1.4" />
    <!-- Iconic 747-400 Angled Winglet (Near Wingtip) -->
    <path d="M -95,62 L -114,44 L -132,60 Z" fill="#dc2626" stroke="#991b1b" stroke-width="1.2" />

    <!-- Near-Side Engine #3 (Outboard Underwing Pylon & Turbofan Pod) -->
    <g transform="translate(-52, 56)">
    <!-- Pylon Strut -->
    <path d="M -5,-8 L 8,-12 L 14,-2 L -2,-2 Z" fill="#94a3b8" />
    <!-- Exhaust Nozzle Cone -->
    <path d="M -24,-6 L -12,-9 L -12,9 L -24,6 Z" fill="#334155" />
    <!-- Engine Cowling Nacelle -->
    <rect x="-14" y="-11" width="36" height="22" rx="7" fill="#ffffff" stroke="#334155" stroke-width="1.8" />
    <line x1="-6" y1="-10" x2="-6" y2="10" stroke="#dc2626" stroke-width="2.5" />
    <!-- Front Air Intake & Spinning Fan Blades -->
    <ellipse cx="22" cy="0" rx="5" ry="10" fill="#0f172a" stroke="#cbd5e1" stroke-width="1.5" />
    <g transform="translate(22, 0)">
    <g class="turbine-spin">
    <line x1="-3" y1="-7" x2="3" y2="7" stroke="#94a3b8" stroke-width="1.6" />
    <line x1="-3" y1="7" x2="3" y2="-7" stroke="#94a3b8" stroke-width="1.6" />
    <circle cx="0" cy="0" r="2.2" fill="#f8fafc" />
    </g>
    </g>
    </g>

    <!-- Near-Side Engine #2 (Inboard Underwing Pylon & Larger Turbofan Pod) -->
    <g transform="translate(8, 42)">
    <!-- Pylon Strut -->
    <path d="M -6,-10 L 10,-15 L 16,-3 L -2,-3 Z" fill="#94a3b8" />
    <!-- Exhaust Nozzle Cone -->
    <path d="M -28,-7 L -14,-11 L -14,11 L -28,7 Z" fill="#334155" />
    <!-- Engine Cowling Nacelle -->
    <rect x="-16" y="-13" width="42" height="26" rx="8" fill="#ffffff" stroke="#334155" stroke-width="2" />
    <line x1="-6" y1="-12" x2="-6" y2="12" stroke="#dc2626" stroke-width="3" />
    <!-- Front Air Intake & Spinning Fan Blades -->
    <ellipse cx="26" cy="0" rx="5.5" ry="12" fill="#0f172a" stroke="#cbd5e1" stroke-width="1.8" />
    <g transform="translate(26, 0)">
    <g class="turbine-spin">
    <line x1="-3.5" y1="-8.5" x2="3.5" y2="8.5" stroke="#cbd5e1" stroke-width="1.8" />
    <line x1="-3.5" y1="8.5" x2="3.5" y2="-8.5" stroke="#cbd5e1" stroke-width="1.8" />
    <circle cx="0" cy="0" r="2.5" fill="#f8fafc" />
    </g>
    </g>
    </g>
    </g>

    <!-- Tail Horizontal Stabilizer (Near side) -->
    <path d="M -205,12 L -268,26 L -284,22 L -235,8 Z" fill="#e2e8f0" stroke="#475569" stroke-width="1.6" />

    <!-- Tow Hook / Bridle Ring under Forward Fuselage (at local coordinates (125, 39)) -->
    <g id="b747-tow-ring" transform="translate(125, 39)">
    <path d="M -10,-2 L 10,-2 L 6,7 L -6,7 Z" fill="#f59e0b" stroke="#78350f" stroke-width="1.5" />
    <circle cx="0" cy="9" r="5.5" fill="none" stroke="#fbbf24" stroke-width="3" />
    </g>

    <!-- Blinking Navigation Strobes -->
    <circle cx="145" cy="-26" r="3.5" fill="#ef4444">
    <animate attributeName="opacity" values="1;0.1;1" dur="0.9s" repeatCount="indefinite" />
    </circle>
    <circle cx="-114" cy="44" r="3" fill="#22c55e">
    <animate attributeName="opacity" values="0.2;1;0.2" dur="1.1s" repeatCount="indefinite" />
    </circle>
    <circle cx="-265" cy="-108" r="3.5" fill="#ffffff">
    <animate attributeName="opacity" values="1;0;1" dur="0.7s" repeatCount="indefinite" />
    </circle>
    </g>

    <!-- 5. TOW ROPE CONNECTING BIKE HANDLEBAR TO BOEING 747 -->
    <g id="tow-rope-layer">
    <!-- Rope Shadow / Outer Casing -->
    <path id="tow-rope-outline" d="" fill="none" stroke="#451a03" stroke-width="8" stroke-linecap="round" />
    <!-- Main Braided Rope Core -->
    <path id="tow-rope-main" d="" fill="none" stroke="url(#rope-grad)" stroke-width="5" stroke-linecap="round" />
    <!-- Dashed Twist Texture along Rope -->
    <path id="tow-rope-twist" d="" fill="none" stroke="#78350f" stroke-width="4" stroke-dasharray="7 9" stroke-linecap="round" />

    <!-- Red Aviation Tow Pennant Flag fluttering in the middle of the rope -->
    <g id="rope-pennant" transform="translate(700, 260)">
    <path id="pennant-shape" d="M 0,0 L -38,12 L -28,0 L -42,-10 Z" fill="#ef4444" stroke="#991b1b" stroke-width="1.5" />
    <circle cx="0" cy="0" r="3.5" fill="#fde047" stroke="#78350f" stroke-width="1.2" />
    </g>
    </g>

    <!-- 6. PELICAN & WHEELIE BICYCLE ASSEMBLY (Pivoting around Rear Wheel Axle (350, 576)) -->
    <!-- Rear Wheel radius = 66, so bottom of tire touches road at y = 576 + 66 = 642 -->
    <g id="wheelie-assembly" transform="translate(0, 0)">

    <!-- 6A. PELICAN FAR LEG (Left Leg behind bike frame, dynamically driven by IK) -->
    <g id="pelican-left-leg">
    <!-- Left Thigh -->
    <line id="leg-l-thigh" x1="370" y1="430" x2="430" y2="480" stroke="#e2e8f0" stroke-width="14" stroke-linecap="round" />
    <!-- Left Knee Joint -->
    <circle id="leg-l-knee" cx="430" cy="480" r="6" fill="#ea580c" />
    <!-- Left Orange Scaly Shin -->
    <line id="leg-l-shin" x1="430" y1="480" x2="445" y2="540" stroke="#ea580c" stroke-width="8.5" stroke-linecap="round" />
    <!-- Left Webbed Foot on Left Pedal -->
    <path id="leg-l-foot" d="M 435,540 L 465,536 L 460,546 L 435,545 Z" fill="#c2410c" stroke="#7c2d12" stroke-width="1.5" />
    </g>

    <!-- Far Pedal Crank Arm (Left Crank behind frame) -->
    <g id="crank-left-group">
    <line id="crank-l-arm" x1="452" y1="538" x2="452" y2="568" stroke="#64748b" stroke-width="7" stroke-linecap="round" />
    <rect id="pedal-l-body" x="438" y="564" width="28" height="8" rx="3" fill="#1e293b" stroke="#475569" stroke-width="1.5" />
    </g>

    <!-- Pelican Far Wing (Left Wing reaching toward handlebar behind neck) -->
    <path
    id="pelican-left-wing"
    d="M 412,385 Q 475,365 538,352 Q 492,390 422,405 Z"
    fill="#cbd5e1"
    stroke="#64748b"
    stroke-width="2"
    />

    <!-- 6B. REAR WHEEL (Supporting the entire wheelie on the road at (350, 576)) -->
    <g id="rear-wheel-center" transform="translate(350, 576)">
    <g id="rear-wheel-spin">
    <!-- Outer Rubber Tire -->
    <circle cx="0" cy="0" r="66" fill="none" stroke="#0f172a" stroke-width="13" />
    <!-- Tire Tread Notches -->
    <circle cx="0" cy="0" r="66" fill="none" stroke="#334155" stroke-width="13" stroke-dasharray="8 12" />
    <!-- Alloy Rim -->
    <circle cx="0" cy="0" r="56" fill="none" stroke="url(#chrome-grad)" stroke-width="4.5" />
    <!-- High-visibility Orange Rim Stripe -->
    <circle cx="0" cy="0" r="52" fill="none" stroke="#f97316" stroke-width="2" stroke-dasharray="28 18" />
    <!-- Wheel Spokes (12 spokes) -->
    <g stroke="#cbd5e1" stroke-width="1.8">
    <line x1="-54" y1="0" x2="54" y2="0" />
    <line x1="0" y1="-54" x2="0" y2="54" />
    <line x1="-38" y1="-38" x2="38" y2="38" />
    <line x1="-38" y1="38" x2="38" y2="-38" />
    <line x1="-47" y1="-27" x2="47" y2="27" />
    <line x1="-27" y1="-47" x2="27" y2="47" />
    <line x1="-47" y1="27" x2="47" y2="-27" />
    <line x1="-27" y1="47" x2="27" y2="-47" />
    </g>
    <!-- Gold Tire Valve & Reflector -->
    <rect x="28" y="-8" width="12" height="6" rx="2" fill="#facc15" stroke="#ca8a04" stroke-width="1" />
    <!-- Rear Sprocket Cassette -->
    <circle cx="0" cy="0" r="15" fill="#475569" stroke="#1e293b" stroke-width="2" stroke-dasharray="4 3" />
    </g>
    <!-- Rear Hub Center -->
    <circle cx="0" cy="0" r="8" fill="#e2e8f0" stroke="#1e293b" stroke-width="2.5" />
    </g>

    <!-- 6C. FRONT WHEEL (Lifted high in the air doing a wheelie at (622, 456)!) -->
    <g id="front-wheel-center" transform="translate(622, 456)">
    <!-- Motion Blur Arc around elevated spinning front wheel -->
    <path d="M -76,-15 A 78,78 0 0,1 65,-42" fill="none" stroke="#ffffff" stroke-width="2.5" stroke-opacity="0.45" stroke-dasharray="18 12" />
    <g id="front-wheel-spin">
    <!-- Outer Rubber Tire -->
    <circle cx="0" cy="0" r="66" fill="none" stroke="#0f172a" stroke-width="13" />
    <!-- Tire Tread Notches -->
    <circle cx="0" cy="0" r="66" fill="none" stroke="#334155" stroke-width="13" stroke-dasharray="8 12" />
    <!-- Alloy Rim -->
    <circle cx="0" cy="0" r="56" fill="none" stroke="url(#chrome-grad)" stroke-width="4.5" />
    <!-- High-visibility Orange Rim Stripe -->
    <circle cx="0" cy="0" r="52" fill="none" stroke="#f97316" stroke-width="2" stroke-dasharray="28 18" />
    <!-- Wheel Spokes -->
    <g stroke="#cbd5e1" stroke-width="1.8">
    <line x1="-54" y1="0" x2="54" y2="0" />
    <line x1="0" y1="-54" x2="0" y2="54" />
    <line x1="-38" y1="-38" x2="38" y2="38" />
    <line x1="-38" y1="38" x2="38" y2="-38" />
    <line x1="-47" y1="-27" x2="47" y2="27" />
    <line x1="-27" y1="-47" x2="27" y2="47" />
    <line x1="-47" y1="27" x2="47" y2="-27" />
    <line x1="-27" y1="47" x2="27" y2="-47" />
    </g>
    <!-- Reflector -->
    <rect x="-40" y="-8" width="12" height="6" rx="2" fill="#facc15" stroke="#ca8a04" stroke-width="1" />
    <!-- Front Brake Disc -->
    <circle cx="0" cy="0" r="16" fill="none" stroke="#94a3b8" stroke-width="3" stroke-dasharray="5 3" />
    </g>
    <!-- Front Hub Center -->
    <circle cx="0" cy="0" r="8" fill="#e2e8f0" stroke="#1e293b" stroke-width="2.5" />
    </g>

    <!-- 6D. BICYCLE DRIVETRAIN & FRAME (Pitched up in Wheelie Posture, Facing Right) -->
    <g id="bicycle-frame">
    <!-- Drive Chain Loop connecting Rear Hub (350, 576) and Bottom Bracket (452, 538) -->
    <path
    id="bike-chain"
    d="M 346,562 L 448,516 A 22,22 0 1,1 456,560 L 354,590 A 14,14 0 1,1 346,562 Z"
    fill="none"
    stroke="#1e293b"
    stroke-width="4"
    stroke-dasharray="6 4"
    />

    <!-- Rear Fender / Mudguard -->
    <path d="M 278,568 A 74,74 0 0,1 368,504" fill="none" stroke="#f59e0b" stroke-width="6" stroke-linecap="round" />

    <!-- Frame Tubes (Red Metallic Tubing) -->
    <!-- Chainstay: Rear Axle (350,576) -> Bottom Bracket (452,538) -->
    <line x1="350" y1="576" x2="452" y2="538" stroke="url(#bike-frame-grad)" stroke-width="10" stroke-linecap="round" />
    <!-- Seatstay: Rear Axle (350,576) -> Seat Cluster (384,442) -->
    <line x1="350" y1="576" x2="384" y2="442" stroke="url(#bike-frame-grad)" stroke-width="9" stroke-linecap="round" />
    <!-- Seat Tube: Bottom Bracket (452,538) -> Seat Cluster (384,442) -->
    <line x1="452" y1="538" x2="384" y2="442" stroke="url(#bike-frame-grad)" stroke-width="11" stroke-linecap="round" />
    <!-- Down Tube: Bottom Bracket (452,538) -> Head Tube Lower (562,406) -->
    <line x1="452" y1="538" x2="562" y2="406" stroke="url(#bike-frame-grad)" stroke-width="13" stroke-linecap="round" />
    <!-- Top Tube: Seat Cluster (384,442) -> Head Tube Upper (546,374) -->
    <line x1="384" y1="442" x2="546" y2="374" stroke="url(#bike-frame-grad)" stroke-width="11" stroke-linecap="round" />

    <!-- Frame Brand Decal -->
    <text x="458" y="476" transform="rotate(-48, 458, 476)" font-size="8.5" font-weight="900" fill="#fef08a" letter-spacing="1.2">PELICAN-PRO</text>

    <!-- Seatpost & Saddle -->
    <line x1="384" y1="442" x2="372" y2="420" stroke="#94a3b8" stroke-width="8" stroke-linecap="round" />
    <path d="M 342,418 Q 372,412 402,420 Q 396,430 370,428 Q 348,428 342,418 Z" fill="#1e293b" stroke="#0f172a" stroke-width="2" />

    <!-- Front Fork: Head Tube Lower (562,406) -> Front Wheel Axle (622,456) -->
    <path d="M 558,402 L 622,456" stroke="url(#chrome-grad)" stroke-width="10" stroke-linecap="round" />
    <path d="M 558,402 L 622,456" stroke="#f59e0b" stroke-width="4" stroke-linecap="round" />

    <!-- Head Tube & Handlebar Stem (Facing Right) -->
    <line x1="542" y1="368" x2="566" y2="412" stroke="url(#bike-frame-grad)" stroke-width="14" stroke-linecap="round" />
    <!-- Chrome Riser Stem & Curved Cruiser/BMX Handlebars -->
    <path d="M 544,370 L 558,342 L 535,346" fill="none" stroke="#e2e8f0" stroke-width="8" stroke-linecap="round" stroke-linejoin="round" />
    <!-- Classic Vintage Headlight on Front of Stem (Facing Right!) -->
    <path d="M 562,350 L 578,344 L 578,360 L 562,356 Z" fill="#facc15" stroke="#ca8a04" stroke-width="1.5" />
    <!-- Headlight Beam Cone -->
    <path id="headlight-beam" d="M 578,346 L 675,315 L 685,375 L 578,358 Z" fill="#fef08a" opacity="0.22" />

    <!-- TOW ROPE KNOT ON HANDLEBAR STEM (Exact anchor point at local (562, 342)) -->
    <g id="handlebar-rope-knot" transform="translate(562, 342)">
    <circle cx="0" cy="0" r="8" fill="#d97706" stroke="#78350f" stroke-width="2.2" />
    <path d="M -5,-4 Q 0,-9 6,-3 Q 4,5 -4,4 Z" fill="#fbbf24" stroke="#78350f" stroke-width="1.5" />
    </g>

    <!-- Handlebar Rubber Grip (at (532, 347)) -->
    <rect x="518" y="341" width="22" height="10" rx="5" transform="rotate(-12, 529, 346)" fill="#0f172a" stroke="#f59e0b" stroke-width="1.5" />

    <!-- Bottom Bracket Chainring (at (452, 538)) -->
    <g transform="translate(452, 538)">
    <g id="chainring-spin">
    <circle cx="0" cy="0" r="23" fill="#334155" stroke="#94a3b8" stroke-width="3" stroke-dasharray="5 3" />
    <circle cx="0" cy="0" r="16" fill="none" stroke="#cbd5e1" stroke-width="2" />
    <line x1="-20" y1="0" x2="20" y2="0" stroke="#94a3b8" stroke-width="3" />
    <line x1="0" y1="-20" x2="0" y2="20" stroke="#94a3b8" stroke-width="3" />
    </g>
    <circle cx="0" cy="0" r="6" fill="#e2e8f0" />
    </g>
    </g>

    <!-- 6E. PELICAN BODY, NECK, HEAD & ICONIC GULAR POUCH (Facing Right) -->
    <g id="pelican-character">
    <!-- Plump White Feathered Torso sitting on Saddle -->
    <path
    d="M 332,402
    L 310,392
    L 325,384
    L 308,374
    L 335,372
    C 355,342, 412,338, 434,368
    C 448,388, 436,422, 405,426
    C 374,430, 346,420, 332,402 Z"
    fill="url(#pelican-body-grad)"
    stroke="#475569"
    stroke-width="2.5"
    stroke-linejoin="round"
    />
    <!-- Subtle Feather Wing Scallops on Back -->
    <path d="M 358,366 Q 382,376 404,364" fill="none" stroke="#94a3b8" stroke-width="2" stroke-linecap="round" />
    <path d="M 350,382 Q 376,392 400,378" fill="none" stroke="#94a3b8" stroke-width="2" stroke-linecap="round" />

    <!-- Pelican Long Curved S-Neck & Head (bobbing slightly with pedaling effort) -->
    <g id="pelican-head-group" transform="translate(0, 0)">
    <!-- S-Curved White Neck rising from Chest (422, 368) to Head (458, 268) -->
    <path
    d="M 412,374
    C 402,340, 422,300, 436,274
    C 442,256, 464,250, 476,262
    C 484,272, 476,292, 464,306
    C 448,326, 438,354, 434,378 Z"
    fill="url(#pelican-body-grad)"
    stroke="#475569"
    stroke-width="2.5"
    />

    <!-- Tuft of Feathers on Crown of Head -->
    <path d="M 442,256 L 426,244 L 446,250 L 434,236 L 456,248 Z" fill="#f8fafc" stroke="#475569" stroke-width="2" stroke-linejoin="round" />

    <!-- ICONIC GIANT PELICAN THROAT POUCH (Gular Pouch - 弹性大喉囊, Facing Right) -->
    <path
    id="pelican-pouch"
    d="M 472,278
    L 598,282
    C 592,324, 548,344, 504,334
    C 476,328, 464,304, 472,278 Z"
    fill="url(#pouch-grad)"
    stroke="#9a3412"
    stroke-width="2.5"
    stroke-linejoin="round"
    />
    <!-- Pouch Stretch Ribs / Striations -->
    <path d="M 488,284 Q 505,318 532,326" fill="none" stroke="#c2410c" stroke-width="1.6" stroke-opacity="0.65" />
    <path d="M 518,284 Q 532,314 558,318" fill="none" stroke="#c2410c" stroke-width="1.6" stroke-opacity="0.65" />

    <!-- Cute Little Fish Tail Poking Out of the Pelican's Beak Pouch! -->
    <g id="pouch-fish" transform="translate(556, 280)">
    <path d="M 0,0 L 16,-12 L 13,-1 L 20,6 L 2,3 Z" fill="#38bdf8" stroke="#0369a1" stroke-width="1.5" />
    </g>

    <!-- LONG UPPER BEAK with Hooked Tip (Pointing Right!) -->
    <path
    d="M 472,262
    L 596,274
    C 606,275, 610,283, 603,290
    L 597,293
    L 594,284
    L 470,280 Z"
    fill="url(#beak-grad)"
    stroke="#9a3412"
    stroke-width="2.2"
    stroke-linejoin="round"
    />

    <!-- Pelican Eye & Cool Aviator Sunglasses -->
    <circle cx="464" cy="266" r="7.5" fill="#fef08a" stroke="#475569" stroke-width="1.8" />
    <circle cx="466" cy="266" r="3.5" fill="#0f172a" />
    <circle cx="467.5" cy="264.5" r="1.3" fill="#ffffff" />

    <!-- Aviator Captain Cap on Pelican's Head -->
    <g transform="translate(454, 246) rotate(-10)">
    <path d="M -18,4 C -16,-10, 12,-12, 18,2 Z" fill="#1e3a8a" stroke="#0f172a" stroke-width="1.8" />
    <path d="M -16,3 L 26,3 L 22,8 L -16,6 Z" fill="#0f172a" />
    <circle cx="2" cy="-2" r="3.5" fill="#fbbf24" />
    </g>

    <!-- Fluttering Red Aviator Scarf Streaming Left in the Wind -->
    <g id="pelican-scarf" transform="translate(432, 332)">
    <path
    id="scarf-tail"
    d="M 0,0 Q -38,-12 -72,4 Q -98,16 -122,2 Q -90,26 -56,16 Q -25,8 4,12 Z"
    fill="#ef4444"
    stroke="#991b1b"
    stroke-width="1.8"
    />
    <ellipse cx="4" cy="6" rx="14" ry="7" transform="rotate(18)" fill="#dc2626" stroke="#991b1b" stroke-width="1.8" />
    </g>
    </g>

    <!-- Near Pedal Crank Arm (Right Crank in foreground) -->
    <g id="crank-right-group">
    <line id="crank-r-arm" x1="452" y1="538" x2="452" y2="510" stroke="#cbd5e1" stroke-width="7.5" stroke-linecap="round" />
    <rect id="pedal-r-body" x="438" y="506" width="28" height="8" rx="3" fill="#0f172a" stroke="#f59e0b" stroke-width="1.8" />
    </g>

    <!-- 6F. PELICAN NEAR LEG (Right Leg in foreground, dynamically driven by IK) -->
    <g id="pelican-right-leg">
    <!-- Fluffy White Upper Thigh -->
    <line id="leg-r-thigh" x1="382" y1="422" x2="442" y2="468" stroke="#ffffff" stroke-width="16" stroke-linecap="round" />
    <line id="leg-r-thigh-inner" x1="382" y1="422" x2="442" y2="468" stroke="#f1f5f9" stroke-width="12" stroke-linecap="round" />
    <!-- Orange Knee Joint -->
    <circle id="leg-r-knee" cx="442" cy="468" r="6.5" fill="#f97316" stroke="#9a3412" stroke-width="1.5" />
    <!-- Orange Lower Shin -->
    <line id="leg-r-shin" x1="442" y1="468" x2="452" y2="510" stroke="#f97316" stroke-width="9" stroke-linecap="round" />
    <!-- Webbed Orange Foot firmly pressing the Right Pedal -->
    <path id="leg-r-foot" d="M 442,510 L 474,506 L 468,516 L 442,515 Z" fill="#fb923c" stroke="#9a3412" stroke-width="1.8" />
    </g>

    <!-- 6G. PELICAN NEAR WING (Right Wing stretching forward to grip the Handlebar!) -->
    <g id="pelican-right-wing-group">
    <path
    id="pelican-right-wing"
    d="M 402,378
    C 438,358, 488,342, 532,346
    C 538,347, 540,355, 530,358
    C 492,368, 448,398, 412,402
    C 396,402, 392,386, 402,378 Z"
    fill="#ffffff"
    stroke="#475569"
    stroke-width="2.5"
    stroke-linejoin="round"
    />
    <!-- Wing Primary Feather Details gripping the handlebar -->
    <path d="M 442,384 Q 482,368 522,354" fill="none" stroke="#94a3b8" stroke-width="2" stroke-linecap="round" />
    <path d="M 426,392 Q 468,378 510,360" fill="none" stroke="#94a3b8" stroke-width="2" stroke-linecap="round" />
    </g>
    </g>

    <!-- Wheelie Balance Sparks / Tire Dust Particles behind Rear Wheel Contact Point -->
    <g id="wheel-dust-layer"></g>
    </g>

    <!-- 7. FOREGROUND WIND SPEED STREAKS (Moving Left to emphasize rightward motion) -->
    <g id="wind-lines-layer"></g>

    <!-- 8. ON-CANVAS VECTOR LABELS (Subtle callouts) -->
    <g id="hud-annotations" opacity="0.88" class="pointer-events-none">
    <!-- Callout badge near 747 Hump -->
    <g id="callout-747" transform="translate(880, 68)">
    <rect x="-95" y="-18" width="190" height="26" rx="13" fill="#0f172a" fill-opacity="0.72" stroke="#38bdf8" stroke-width="1.2" />
    <text x="0" y="-1" text-anchor="middle" fill="#e0f2fe" font-size="11" font-weight="700">✈️ 波音747 (可按住拖动位置)</text>
    </g>
    </g>
    </svg>

    <!-- Floating Boost Toast Notification -->
    <div
    id="boost-toast"
    class="pointer-events-none absolute top-4 left-4 bg-amber-500/95 text-slate-950 font-black text-xs sm:text-sm px-3.5 py-1.5 rounded-full shadow-lg opacity-0 transition-opacity duration-300"

    🔥 涡轮蹬车加速!波音747拉升中!
    </div>
    </div>
    </main>

    <!-- Interactive Control Panel -->
    <footer class="w-full max-w-6xl mt-3 bg-slate-900/90 border border-slate-800 rounded-2xl p-3 sm:px-6 sm:py-3.5 flex flex-wrap items-center justify-between gap-4 shadow-xl">
    <!-- Sliders Group -->
    <div class="flex flex-wrap items-center gap-4 sm:gap-6">
    <!-- Speed Control -->
    <label class="flex items-center gap-2.5 text-xs sm:text-sm font-medium text-slate-300">
    <span>🚴 骑行速度</span>
    <input
    id="speed-slider"
    type="range"
    min="0.3"
    max="2.6"
    step="0.1"
    value="1.2"
    class="w-24 sm:w-32 cursor-pointer"
    />
    </label>

    <!-- Wheelie Pitch Bias Control -->
    <label class="flex items-center gap-2.5 text-xs sm:text-sm font-medium text-slate-300">
    <span>📐 翘头高度</span>
    <input
    id="wheelie-slider"
    type="range"
    min="-14"
    max="14"
    step="1"
    value="2"
    class="w-24 sm:w-32 cursor-pointer"
    />
    </label>

    <!-- Rope Length / Plane Altitude Control -->
    <label class="flex items-center gap-2.5 text-xs sm:text-sm font-medium text-slate-300">
    <span>🪢 放飞高度</span>
    <input
    id="altitude-slider"
    type="range"
    min="95"
    max="310"
    step="5"
    value="175"
    class="w-24 sm:w-32 cursor-pointer"
    />
    </label>
    </div>

    <!-- Action Buttons & Theme Switcher -->
    <div class="flex items-center gap-2.5">
    <!-- Sky Theme Buttons -->
    <div class="flex bg-slate-950 p-1 rounded-xl border border-slate-800">
    <button
    data-theme="day"
    class="theme-btn px-2.5 py-1 rounded-lg text-xs font-bold bg-sky-500 text-slate-950 transition"

    ☀️ 晴空
    </button>
    <button
    data-theme="sunset"
    class="theme-btn px-2.5 py-1 rounded-lg text-xs font-bold text-slate-400 hover:text-white transition"

    🌇 晚霞
    </button>
    <button
    data-theme="night"
    class="theme-btn px-2.5 py-1 rounded-lg text-xs font-bold text-slate-400 hover:text-white transition"

    🌙 星夜
    </button>
    </div>

    <!-- Boost Stunt Action Button -->
    <button
    id="boost-btn"
    class="px-4 py-2 rounded-xl font-black text-xs sm:text-sm bg-gradient-to-r from-amber-400 via-orange-500 to-red-500 text-slate-950 shadow-lg shadow-orange-500/25 hover:brightness-110 active:scale-95 transition flex items-center gap-1.5"

    <span>⚡ 猛踩特技拉升</span>
    </button>
    </div>
    </footer>

    <script>
    window.onload = function () {
    const svgNS = 'http://www.w3.org/2000/svg&#039;;

    // DOM Element References
    const mainSvg = document.getElementById('main-svg');
    const wheelieAssembly = document.getElementById('wheelie-assembly');
    const rearWheelSpin = document.getElementById('rear-wheel-spin');
    const frontWheelSpin = document.getElementById('front-wheel-spin');
    const chainringSpin = document.getElementById('chainring-spin');
    const bikeChain = document.getElementById('bike-chain');

    // Pelican & IK Leg elements
    const pelicanHeadGroup = document.getElementById('pelican-head-group');
    const pelicanPouch = document.getElementById('pelican-pouch');
    const pouchFish = document.getElementById('pouch-fish');
    const scarfTail = document.getElementById('scarf-tail');
    const pelicanRightWing = document.getElementById('pelican-right-wing');

    const crankRArm = document.getElementById('crank-r-arm');
    const pedalRBody = document.getElementById('pedal-r-body');
    const crankLArm = document.getElementById('crank-l-arm');
    const pedalLBody = document.getElementById('pedal-l-body');

    const legRThigh = document.getElementById('leg-r-thigh');
    const legRThighInner = document.getElementById('leg-r-thigh-inner');
    const legRKnee = document.getElementById('leg-r-knee');
    const legRShin = document.getElementById('leg-r-shin');
    const legRFoot = document.getElementById('leg-r-foot');

    const legLThigh = document.getElementById('leg-l-thigh');
    const legLKnee = document.getElementById('leg-l-knee');
    const legLShin = document.getElementById('leg-l-shin');
    const legLFoot = document.getElementById('leg-l-foot');

    // Boeing 747 & Tow Rope elements
    const boeingGroup = document.getElementById('boeing-747-group');
    const callout747 = document.getElementById('callout-747');
    const towRopeOutline = document.getElementById('tow-rope-outline');
    const towRopeMain = document.getElementById('tow-rope-main');
    const towRopeTwist = document.getElementById('tow-rope-twist');
    const ropePennant = document.getElementById('rope-pennant');
    const pennantShape = document.getElementById('pennant-shape');

    // Environment & Shadows
    const roadDashesGroup = document.getElementById('road-dashes');
    const roadPropsGroup = document.getElementById('road-props');
    const windLinesLayer = document.getElementById('wind-lines-layer');
    const wheelDustLayer = document.getElementById('wheel-dust-layer');
    const mountainsFar = document.getElementById('mountains-far');
    const mountainsNear = document.getElementById('mountains-near');
    const bikeGroundShadow = document.getElementById('bike-ground-shadow');
    const planeGroundShadow = document.getElementById('plane-ground-shadow');

    // Telemetry & Controls
    const pitchReadout = document.getElementById('pitch-readout');
    const tensionReadout = document.getElementById('tension-readout');
    const speedReadout = document.getElementById('speed-readout');
    const speedSlider = document.getElementById('speed-slider');
    const wheelieSlider = document.getElementById('wheelie-slider');
    const altitudeSlider = document.getElementById('altitude-slider');
    const boostBtn = document.getElementById('boost-btn');
    const boostToast = document.getElementById('boost-toast');

    // ============================================================================
    // 1. PROCEDURAL SCENE GENERATION (Road Dashes, Pebbles/Bushes, Wind Streaks)
    // ============================================================================
    const roadDashes = [];
    for (let i = 0; i < 12; i++) {
    const rect = document.createElementNS(svgNS, 'rect');
    const x = i * 120;
    rect.setAttribute('x', x);
    rect.setAttribute('y', 698);
    rect.setAttribute('width', 64);
    rect.setAttribute('height', 8);
    rect.setAttribute('rx', 4);
    rect.setAttribute('fill', '#facc15');
    rect.setAttribute('opacity', '0.88');
    roadDashesGroup.appendChild(rect);
    roadDashes.push({ el: rect, x: x });
    }

    const roadProps = [];
    for (let i = 0; i < 10; i++) {
    const g = document.createElementNS(svgNS, 'g');
    const x = i 145 + (i % 2) 30;
    const isBush = i % 3 === 0;
    if (isBush) {
    const bush = document.createElementNS(svgNS, 'path');
    bush.setAttribute('d', 'M-18,0 Q-14,-16 0,-12 Q10,-22 22,-10 Q32,-12 30,0 Z');
    bush.setAttribute('fill', '#15803d');
    g.appendChild(bush);
    } else {
    const pebble = document.createElementNS(svgNS, 'ellipse');
    pebble.setAttribute('cx', 0);
    pebble.setAttribute('cy', 0);
    pebble.setAttribute('rx', 7 + (i % 4) * 2);
    pebble.setAttribute('ry', 2.5);
    pebble.setAttribute('fill', '#64748b');
    g.appendChild(pebble);
    }
    const y = isBush ? 626 : 665 + (i % 5) * 22;
    g.setAttribute('transform', translate(${x}, ${y}));
    roadPropsGroup.appendChild(g);
    roadProps.push({ el: g, x: x, y: y, speedMult: isBush ? 0.92 : 1.05 });
    }

    const windLines = [];
    for (let i = 0; i < 9; i++) {
    const line = document.createElementNS(svgNS, 'line');
    const x = Math.random() * 1280;
    const y = 90 + i * 62;
    const len = 55 + (i % 3) * 35;
    line.setAttribute('x1', x);
    line.setAttribute('y1', y);
    line.setAttribute('x2', x + len);
    line.setAttribute('y2', y);
    line.setAttribute('stroke', '#ffffff');
    line.setAttribute('stroke-width', i % 2 === 0 ? '2' : '1.2');
    line.setAttribute('stroke-linecap', 'round');
    line.setAttribute('stroke-opacity', '0.28');
    windLinesLayer.appendChild(line);
    windLines.push({ el: line, x: x, y: y, len: len, speed: 1.3 + (i % 4) * 0.25 });
    }

    // Dust particles at rear wheel contact point (350, 642)
    const dustParticles = [];
    for (let i = 0; i < 8; i++) {
    const c = document.createElementNS(svgNS, 'circle');
    c.setAttribute('r', 4 + (i % 3) * 2.5);
    c.setAttribute('fill', i % 2 === 0 ? '#fde68a' : '#cbd5e1');
    wheelDustLayer.appendChild(c);
    dustParticles.push({
    el: c,
    phase: i / 8
    });
    }

    // ============================================================================
    // 2. ANALYTICAL 2-BONE INVERSE KINEMATICS (Pelican Hip -> Knee -> Pedal)
    // ============================================================================
    function solveTwoBoneIK(hipX, hipY, footX, footY, L1, L2) {
    const dx = footX - hipX;
    const dy = footY - hipY;
    let dist = Math.hypot(dx, dy);

    // Clamp reach so legs never detach
    const maxReach = (L1 + L2) * 0.992;
    const minReach = Math.abs(L1 - L2) * 1.05;
    if (dist > maxReach) dist = maxReach;
    if (dist < minReach) dist = minReach;

    // Law of cosines for knee bend (bending forward-right like a bird/cyclist knee)
    const cosAngle = (L1 L1 + dist dist - L2 L2) / (2 L1 * dist);
    const clampedCos = Math.max(-1, Math.min(1, cosAngle));
    const baseAngle = Math.atan2(dy, dx);
    const bendAngle = Math.acos(clampedCos);

    // Knee bends upward/rightward (subtract bendAngle)
    const thighAngle = baseAngle - bendAngle;
    const kneeX = hipX + L1 * Math.cos(thighAngle);
    const kneeY = hipY + L1 * Math.sin(thighAngle);

    return { kneeX, kneeY };
    }

    // Helper to transform a point (x, y) rotated around pivot (px, py) by angleDeg
    function rotatePointAround(x, y, px, py, angleDeg) {
    const rad = (angleDeg * Math.PI) / 180;
    const cos = Math.cos(rad);
    const sin = Math.sin(rad);
    const dx = x - px;
    const dy = y - py;
    return {
    x: px + dx cos - dy sin,
    y: py + dx sin + dy cos
    };
    }

    // ============================================================================
    // 3. ANIMATION STATE & INTERACTIVE DRAGGING FOR BOEING 747
    // ============================================================================
    const state = {
    time: 0,
    wheelAngle: 0,
    crankAngle: 0,
    roadOffset: 0,
    mountainFarOffset: 0,
    mountainNearOffset: 0,
    speedMultiplier: 1.2,
    wheelieBias: 2,
    boostRemaining: 0,
    // Boeing 747 base position in SVG coordinates
    planeBaseX: 925,
    planeBaseY: 175,
    isDraggingPlane: false
    };

    // Convert client mouse/touch coordinates into SVG viewBox coordinates
    function getSvgPoint(clientX, clientY) {
    const pt = mainSvg.createSVGPoint();
    pt.x = clientX;
    pt.y = clientY;
    const ctm = mainSvg.getScreenCTM();
    if (!ctm) return { x: 925, y: 175 };
    return pt.matrixTransform(ctm.inverse());
    }

    boeingGroup.addEventListener('pointerdown', (e) => {
    state.isDraggingPlane = true;
    boeingGroup.setPointerCapture(e.pointerId);
    });

    window.addEventListener('pointermove', (e) => {
    if (!state.isDraggingPlane) return;
    const svgPt = getSvgPoint(e.clientX, e.clientY);
    state.planeBaseX = Math.max(580, Math.min(1150, svgPt.x));
    state.planeBaseY = Math.max(75, Math.min(390, svgPt.y));
    altitudeSlider.value = Math.round(state.planeBaseY);
    });

    window.addEventListener('pointerup', () => {
    state.isDraggingPlane = false;
    });

    // UI Controls Event Listeners
    speedSlider.addEventListener('input', (e) => {
    state.speedMultiplier = parseFloat(e.target.value);
    });

    wheelieSlider.addEventListener('input', (e) => {
    state.wheelieBias = parseFloat(e.target.value);
    });

    altitudeSlider.addEventListener('input', (e) => {
    state.planeBaseY = parseFloat(e.target.value);
    });

    boostBtn.addEventListener('click', () => {
    state.boostRemaining = 2.6; // 2.6 seconds of turbo boost
    boostToast.style.opacity = '1';
    setTimeout(() => {
    boostToast.style.opacity = '0';
    }, 2200);
    });

    // Theme Switcher
    const skyRect = document.getElementById('sky-rect');
    const starsLayer = document.getElementById('stars-layer');
    const themeBtns = document.querySelectorAll('.theme-btn');

    themeBtns.forEach((btn) => {
    btn.addEventListener('click', () => {
    const theme = btn.getAttribute('data-theme');
    themeBtns.forEach((b) => {
    b.className = 'theme-btn px-2.5 py-1 rounded-lg text-xs font-bold text-slate-400 hover:text-white transition';
    });
    btn.className = 'theme-btn px-2.5 py-1 rounded-lg text-xs font-bold bg-sky-500 text-slate-950 transition';

    if (theme === 'day') {
    skyRect.setAttribute('fill', 'url(#sky-grad-day)');
    starsLayer.setAttribute('opacity', '0');
    } else if (theme === 'sunset') {
    skyRect.setAttribute('fill', 'url(#sky-grad-sunset)');
    starsLayer.setAttribute('opacity', '0.45');
    } else if (theme === 'night') {
    skyRect.setAttribute('fill', 'url(#sky-grad-night)');
    starsLayer.setAttribute('opacity', '0.95');
    }
    });
    });

    // Clouds array initialization
    const cloudItems = Array.from(document.querySelectorAll('.cloud-item')).map((el) => ({
    el,
    speed: parseFloat(el.getAttribute('data-speed')),
    x: parseFloat(el.getAttribute('data-x')),
    y: parseFloat(el.getAttribute('data-y')),
    scale: parseFloat(el.getAttribute('data-scale'))
    }));

    // ============================================================================
    // 4. MAIN ANIMATION LOOP (60fps Physics & SVG Synchronization)
    // ============================================================================
    let lastTimestamp = performance.now();

    function animate(now) {
    const dt = Math.min(0.05, (now - lastTimestamp) / 1000);
    lastTimestamp = now;

    // Handle Turbo Boost decay
    if (state.boostRemaining > 0) {
    state.boostRemaining = Math.max(0, state.boostRemaining - dt);
    }
    const boostFactor = state.boostRemaining > 0 ? 1.85 : 1.0;
    const effectiveSpeed = state.speedMultiplier * boostFactor;

    state.time += dt * effectiveSpeed;
    const t = state.time;

    // ------------------------------------------------------------------------
    // A. WHEEL ROTATION & CRANK PEDALING (Moving Forward to the Right -> Clockwise)
    // ------------------------------------------------------------------------
    state.wheelAngle = (state.wheelAngle + dt effectiveSpeed 420) % 360;
    state.crankAngle = (state.crankAngle + dt effectiveSpeed 5.2) % (Math.PI * 2);

    rearWheelSpin.setAttribute('transform', rotate(${state.wheelAngle}));
    frontWheelSpin.setAttribute('transform', rotate(${state.wheelAngle * 0.92}));
    chainringSpin.setAttribute('transform', rotate(${(state.crankAngle * 180) / Math.PI}));
    bikeChain.setAttribute('stroke-dashoffset', -(t * 45) % 20);

    // ------------------------------------------------------------------------
    // B. WHEELIE BALANCING PITCH OSCILLATION (Pivoting at Rear Axle (350, 576))
    // ------------------------------------------------------------------------
    // Positive angle tilts front wheel down, negative angle lifts front wheel higher!
    const altitudePull = (175 - state.planeBaseY) * 0.035;
    const boostWheelieLift = state.boostRemaining > 0 ? -4.5 : 0;
    const wheelieRockingDeg =
    -state.wheelieBias -
    altitudePull +
    boostWheelieLift +
    Math.sin(t 3.2) 2.8 +
    Math.cos(t 1.7) 1.2;

    wheelieAssembly.setAttribute(
    'transform',
    rotate(${wheelieRockingDeg.toFixed(2)}, 350, 576)
    );

    // Update ground shadow width based on wheelie pitch
    bikeGroundShadow.setAttribute('rx', (86 + wheelieRockingDeg * 0.9).toFixed(1));

    // ------------------------------------------------------------------------
    // C. PELICAN PEDALING INVERSE KINEMATICS (2 Legs + Cranks + Webbed Feet)
    // ------------------------------------------------------------------------
    const crankCenterX = 452;
    const crankCenterY = 538;
    const crankRadius = 26;

    // Right Pedal (Near side)
    const rPedalX = crankCenterX + crankRadius * Math.cos(state.crankAngle);
    const rPedalY = crankCenterY + crankRadius * Math.sin(state.crankAngle);
    crankRArm.setAttribute('x2', rPedalX.toFixed(1));
    crankRArm.setAttribute('y2', rPedalY.toFixed(1));
    pedalRBody.setAttribute('x', (rPedalX - 14).toFixed(1));
    pedalRBody.setAttribute('y', (rPedalY - 4).toFixed(1));

    // Left Pedal (Far side, 180 degrees opposite)
    const lPedalX = crankCenterX + crankRadius * Math.cos(state.crankAngle + Math.PI);
    const lPedalY = crankCenterY + crankRadius * Math.sin(state.crankAngle + Math.PI);
    crankLArm.setAttribute('x2', lPedalX.toFixed(1));
    crankLArm.setAttribute('y2', lPedalY.toFixed(1));
    pedalLBody.setAttribute('x', (lPedalX - 14).toFixed(1));
    pedalLBody.setAttribute('y', (lPedalY - 4).toFixed(1));

    // Solve IK for Right Leg (Hip at (382, 422))
    const rHipX = 382, rHipY = 422;
    const rIK = solveTwoBoneIK(rHipX, rHipY, rPedalX, rPedalY, 68, 66);
    legRThigh.setAttribute('x2', rIK.kneeX.toFixed(1));
    legRThigh.setAttribute('y2', rIK.kneeY.toFixed(1));
    legRThighInner.setAttribute('x2', rIK.kneeX.toFixed(1));
    legRThighInner.setAttribute('y2', rIK.kneeY.toFixed(1));
    legRKnee.setAttribute('cx', rIK.kneeX.toFixed(1));
    legRKnee.setAttribute('cy', rIK.kneeY.toFixed(1));
    legRShin.setAttribute('x1', rIK.kneeX.toFixed(1));
    legRShin.setAttribute('y1', rIK.kneeY.toFixed(1));
    legRShin.setAttribute('x2', rPedalX.toFixed(1));
    legRShin.setAttribute('y2', rPedalY.toFixed(1));
    legRFoot.setAttribute(
    'd',
    M ${(rPedalX - 10).toFixed(1)},${rPedalY.toFixed(1)} L ${(rPedalX + 22).toFixed(1)},${(rPedalY - 5).toFixed(1)} L ${(rPedalX + 16).toFixed(1)},${(rPedalY + 5).toFixed(1)} L ${(rPedalX - 10).toFixed(1)},${(rPedalY + 4).toFixed(1)} Z
    );

    // Solve IK for Left Leg (Hip at (374, 426))
    const lHipX = 374, lHipY = 426;
    const lIK = solveTwoBoneIK(lHipX, lHipY, lPedalX, lPedalY, 68, 66);
    legLThigh.setAttribute('x2', lIK.kneeX.toFixed(1));
    legLThigh.setAttribute('y2', lIK.kneeY.toFixed(1));
    legLKnee.setAttribute('cx', lIK.kneeX.toFixed(1));
    legLKnee.setAttribute('cy', lIK.kneeY.toFixed(1));
    legLShin.setAttribute('x1', lIK.kneeX.toFixed(1));
    legLShin.setAttribute('y1', lIK.kneeY.toFixed(1));
    legLShin.setAttribute('x2', lPedalX.toFixed(1));
    legLShin.setAttribute('y2', lPedalY.toFixed(1));
    legLFoot.setAttribute(
    'd',
    M ${(lPedalX - 10).toFixed(1)},${lPedalY.toFixed(1)} L ${(lPedalX + 20).toFixed(1)},${(lPedalY - 5).toFixed(1)} L ${(lPedalX + 15).toFixed(1)},${(lPedalY + 5).toFixed(1)} L ${(lPedalX - 10).toFixed(1)},${(lPedalY + 4).toFixed(1)} Z
    );

    // ------------------------------------------------------------------------
    // D. PELICAN SECONDARY ANIMATIONS (Head Bob, Throat Pouch Jiggle, Scarf)
    // ------------------------------------------------------------------------
    const headBobY = Math.sin(state.crankAngle 2) 3.2;
    const headTilt = Math.cos(state.crankAngle) * 2.2;
    pelicanHeadGroup.setAttribute(
    'transform',
    translate(0, ${headBobY.toFixed(2)}) rotate(${headTilt.toFixed(2)}, 445, 310)
    );

    // Throat pouch elastic jiggle
    const pouchSag = 342 + Math.sin(t 7.5) 6.5;
    pelicanPouch.setAttribute(
    'd',
    M 472,278 L 598,282 C 592,${(pouchSag - 16).toFixed(1)}, 548,${pouchSag.toFixed(1)}, 504,${(pouchSag - 8).toFixed(1)} C 476,328, 464,304, 472,278 Z
    );
    // Little fish tail wiggling in the pouch
    pouchFish.setAttribute(
    'transform',
    translate(556, 280) rotate(${(Math.sin(t * 11) * 12).toFixed(1)})
    );

    // Fluttering aviator scarf wave
    const scarfWave1 = -12 + Math.sin(t 12) 9;
    const scarfWave2 = 2 + Math.cos(t 10) 12;
    scarfTail.setAttribute(
    'd',
    M 0,0 Q -38,${scarfWave1.toFixed(1)} -72,4 Q -98,16 -122,${scarfWave2.toFixed(1)} Q -90,26 -56,16 Q -25,8 4,12 Z
    );

    // ------------------------------------------------------------------------
    // E. BOEING 747 SKY FLOATING MOTION & EXACT TOW ROPE PHYSICS
    // ------------------------------------------------------------------------
    const planeFloatX = state.planeBaseX + Math.sin(t 1.4) 16;
    const planeFloatY =
    state.planeBaseY +
    Math.sin(t 2.3) 14 -
    (state.boostRemaining > 0 ? 18 : 0);
    const planePitchDeg = -8.5 + Math.cos(t 2.3) 3.2 - (state.boostRemaining > 0 ? 4 : 0);

    boeingGroup.setAttribute(
    'transform',
    translate(${planeFloatX.toFixed(2)}, ${planeFloatY.toFixed(2)}) rotate(${planePitchDeg.toFixed(2)})
    );

    // Update callout badge above 747
    callout747.setAttribute(
    'transform',
    translate(${(planeFloatX - 25).toFixed(1)}, ${(planeFloatY - 108).toFixed(1)})
    );
    planeGroundShadow.setAttribute('cx', planeFloatX.toFixed(1));
    planeGroundShadow.setAttribute('rx', (155 - planeFloatY * 0.15).toFixed(1));

    // Compute Exact World Position of Bike Handlebar Knot (local (562, 342) rotated around (350, 576))
    const handlebarWorld = rotatePointAround(562, 342, 350, 576, wheelieRockingDeg);

    // Compute Exact World Position of Boeing 747 Tow Ring (local (125, 45) inside boeingGroup)
    const planeTowLocalRotated = rotatePointAround(125, 45, 0, 0, planePitchDeg);
    const planeTowWorld = {
    x: planeFloatX + planeTowLocalRotated.x,
    y: planeFloatY + planeTowLocalRotated.y
    };

    // Construct Quadratic/Cubic Bezier Rope Curve with realistic aerodynamic sag & vibration
    const midX = (handlebarWorld.x + planeTowWorld.x) * 0.5;
    const midY = (handlebarWorld.y + planeTowWorld.y) * 0.5;
    const ropeVibration = Math.sin(t 14) 4.5;
    const ropeSag = 26 - effectiveSpeed * 6 + ropeVibration;

    const ctrlX = midX + 18;
    const ctrlY = midY + ropeSag;

    const ropePathData = M ${handlebarWorld.x.toFixed(1)},${handlebarWorld.y.toFixed(1)} Q ${ctrlX.toFixed(1)},${ctrlY.toFixed(1)} ${planeTowWorld.x.toFixed(1)},${planeTowWorld.y.toFixed(1)};
    towRopeOutline.setAttribute('d', ropePathData);
    towRopeMain.setAttribute('d', ropePathData);
    towRopeTwist.setAttribute('d', ropePathData);

    // Position the Red Warning Pennant at t = 0.5 on the quadratic Bezier curve
    const flagX = 0.25 handlebarWorld.x + 0.5 ctrlX + 0.25 * planeTowWorld.x;
    const flagY = 0.25 handlebarWorld.y + 0.5 ctrlY + 0.25 * planeTowWorld.y;
    const flagFlutter = Math.sin(t 16) 8;
    ropePennant.setAttribute(
    'transform',
    translate(${flagX.toFixed(1)}, ${flagY.toFixed(1)}) rotate(${flagFlutter.toFixed(1)})
    );

    // ------------------------------------------------------------------------
    // F. SCROLLING ROAD, PARALLAX MOUNTAINS, CLOUDS & DUST PARTICLES
    // ------------------------------------------------------------------------
    const scrollPixels = dt effectiveSpeed 340;

    // Road center dashes
    roadDashes.forEach((d) => {
    d.x -= scrollPixels;
    if (d.x < -80) d.x += 12 * 120;
    d.el.setAttribute('x', d.x.toFixed(1));
    });

    // Roadside bushes & pebbles
    roadProps.forEach((p) => {
    p.x -= scrollPixels * p.speedMult;
    if (p.x < -60) p.x += 10 * 145;
    p.el.setAttribute('transform', translate(${p.x.toFixed(1)}, ${p.y}));
    });

    // Foreground wind speed lines
    windLines.forEach((w) => {
    w.x -= scrollPixels w.speed 1.35;
    if (w.x < -150) w.x = 1320 + Math.random() * 120;
    w.el.setAttribute('x1', w.x.toFixed(1));
    w.el.setAttribute('x2', (w.x + w.len).toFixed(1));
    });

    // Parallax clouds
    cloudItems.forEach((c) => {
    c.x -= scrollPixels c.speed 0.22;
    if (c.x < -240) c.x = 1360;
    c.el.setAttribute(
    'transform',
    translate(${c.x.toFixed(1)}, ${c.y}) scale(${c.scale})
    );
    });

    // Parallax mountains
    state.mountainFarOffset = (state.mountainFarOffset - scrollPixels * 0.08) % 600;
    state.mountainNearOffset = (state.mountainNearOffset - scrollPixels * 0.18) % 600;
    mountainsFar.setAttribute('transform', translate(${state.mountainFarOffset.toFixed(1)}, 0));
    mountainsNear.setAttribute('transform', translate(${state.mountainNearOffset.toFixed(1)}, 0));

    // Rear tire dust puffs (kicked backward to the left from (336, 638))
    dustParticles.forEach((p) => {
    const progress = (t * 1.9 + p.phase) % 1;
    const px = 340 - progress * 115;
    const py = 638 - Math.sin(progress Math.PI) 24 - progress * 12;
    const scale = (1 - progress) * 1.3;
    p.el.setAttribute('cx', px.toFixed(1));
    p.el.setAttribute('cy', py.toFixed(1));
    p.el.setAttribute('opacity', ((1 - progress) * 0.65).toFixed(2));
    p.el.setAttribute('r', (3 + scale * 5).toFixed(1));
    });

    // ------------------------------------------------------------------------
    // G. UPDATE LIVE TELEMETRY BADGES
    // ------------------------------------------------------------------------
    const displayPitch = Math.abs(26 - wheelieRockingDeg);
    const ropeDist = Math.hypot(
    planeTowWorld.x - handlebarWorld.x,
    planeTowWorld.y - handlebarWorld.y
    );
    const displayTension = 35 + ropeDist 0.045 + effectiveSpeed 4.2;
    const displaySpeed = Math.round(effectiveSpeed * 32);

    pitchReadout.textContent = ${displayPitch.toFixed(1)}°;
    tensionReadout.textContent = ${displayTension.toFixed(1)} kN;
    speedReadout.textContent = ${displaySpeed} km/h;

    requestAnimationFrame(animate);
    }

    requestAnimationFrame(animate);
    };
    </script>
    </body>
    </html>

    主楼
  • nini

    这个厉害呀。

    #1
  • mutouren2026

    这尼玛有点离谱了吧

    #2
  • 活在梦里怎么了

    别用鹈鹕了,换成三条腿的癞蛤蟆试试

    #3
  • 1uh5an

    哈哈哈,离谱

    #4
  • violetooop-1127

    牛逼啊这个

    #5
  • lighthappy

    这得起飞啊

    #6

发表回复

登录后回复