• nodeseeek

    我觉得效果还可以,虽然是让3.1Pro优化了下prompt,但是成品的一次过的

    图片```
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>鹈鹕骑自行车 - 2D 循环动画</title>
    <style>
    * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    }

    body {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    background: radial-gradient(circle at 50% 30%, #bbf2f6 0%, #86d3e3 50%, #5cb8cf 100%);
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    }

    .canvas-container {
    width: 95vw;
    max-width: 1000px;
    height: 85vh;
    max-height: 680px;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    }

    svg {
    width: 100%;
    height: 100%;
    overflow: hidden;
    border-radius: 28px;
    box-shadow: 0 25px 60px rgba(18, 52, 77, 0.25), 0 8px 20px rgba(0, 0, 0, 0.08);
    background: linear-gradient(to bottom, #d4f4fb 0%, #eefbfd 62%, #a8d5ba 62.1%, #7cb896 66%, #525a66 66.1%, #353b45 100%);
    }

    / ================= CSS 循环动画体系 ================= /

    / 1. 车轮 360° 匀速顺时针旋转 (周期与路面位移速度严格匹配) /
    .wheel-spokes {
    animation: spin 1.1s linear infinite;
    transform-box: fill-box;
    transform-origin: center;
    }
    @keyframes spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
    }

    / 2. 背景与环境无限无缝平移 (向左滚动制造向前冲刺感) /
    .scroll-clouds {
    animation: scrollH 22s linear infinite;
    }
    .scroll-hills {
    animation: scrollH 10s linear infinite;
    }
    .scroll-trees {
    animation: scrollH 4.4s linear infinite;
    }
    .scroll-road-dashes {
    animation: scrollRoad 1.1s linear infinite;
    }
    .scroll-bushes {
    animation: scrollH 2.2s linear infinite;
    }

    @keyframes scrollH {
    from { transform: translateX(0); }
    to { transform: translateX(-900px); }
    }

    @keyframes scrollRoad {
    from { transform: translateX(0); }
    to { transform: translateX(-440px); }
    }

    / 3. 鹈鹕躯干呼吸式律动 (上下起伏 + 微倾角度) /
    .pelican-rider {
    animation: pelicanBob 1.1s cubic-bezier(0.45, 0.05, 0.55, 0.95) infinite;
    transform-origin: 390px 320px;
    }
    @keyframes pelicanBob {
    0%, 100% { transform: translateY(0px) rotate(0deg); }
    25% { transform: translateY(-5px) rotate(-0.8deg); }
    50% { transform: translateY(2px) rotate(0.4deg); }
    75% { transform: translateY(-4px) rotate(-0.5deg); }
    }

    / 4. 标志性大鸟囊弹性微颤 (体现充沛弹性与趣味) /
    .gular-pouch {
    animation: pouchJiggle 1.1s ease-in-out infinite;
    transform-origin: 520px 170px;
    }
    @keyframes pouchJiggle {
    0%, 100% { transform: scale(1) rotate(0deg); }
    35% { transform: scale(1.02, 0.96) rotate(1deg); }
    70% { transform: scale(0.98, 1.03) rotate(-1deg); }
    }

    / 5. 随风飞扬的红色围巾飘荡 /
    .scarf-tail-1 {
    animation: scarfFly1 0.55s ease-in-out infinite alternate;
    transform-origin: 405px 215px;
    }
    .scarf-tail-2 {
    animation: scarfFly2 0.7s ease-in-out infinite alternate;
    transform-origin: 405px 215px;
    }
    @keyframes scarfFly1 {
    0% { transform: rotate(-4deg) skewX(2deg); }
    100% { transform: rotate(10deg) skewX(-7deg) scaleY(0.92); }
    }
    @keyframes scarfFly2 {
    0% { transform: rotate(8deg) skewY(-3deg); }
    100% { transform: rotate(-8deg) skewY(6deg) scaleY(1.08); }
    }

    / 6. 自行车整体微弱的路面颠簸震颤 /
    .bike-chassis {
    animation: bikeJitter 0.55s ease-in-out infinite alternate;
    transform-origin: 450px 460px;
    }
    @keyframes bikeJitter {
    0% { transform: translateY(0); }
    100% { transform: translateY(1.2px); }
    }
    </style>
    </head>
    <body>

    <div class="canvas-container">
    <svg id="scene" viewBox="0 0 900 600" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg"&gt;
    <defs>
    <!-- 基础色彩渐变定义 -->
    <linearGradient id="sunGrad" x1="0%" y1="0%" x2="100%" y2="100%">
    <stop offset="0%" stop-color="#fff6cc" />
    <stop offset="100%" stop-color="#ffdd6b" />
    </linearGradient>

    <linearGradient id="pouchGrad" x1="0%" y1="0%" x2="60%" y2="100%">
    <stop offset="0%" stop-color="#ffa42b" />
    <stop offset="70%" stop-color="#f57c00" />
    <stop offset="100%" stop-color="#e65100" />
    </linearGradient>

    <linearGradient id="frameGrad" x1="0%" y1="0%" x2="100%" y2="50%">
    <stop offset="0%" stop-color="#2bd9b6" />
    <stop offset="100%" stop-color="#14a085" />
    </linearGradient>

    <linearGradient id="tireGrad" x1="0%" y1="0%" x2="100%" y2="100%">
    <stop offset="0%" stop-color="#3d444f" />
    <stop offset="100%" stop-color="#22272e" />
    </linearGradient>

    <!-- 车轮辐条复用单元 -->
    <g id="spoke-cluster">
    <line x1="0" y1="-56" x2="0" y2="56" stroke="#c0d3d8" stroke-width="2" />
    <line x1="-56" y1="0" x2="56" y2="0" stroke="#c0d3d8" stroke-width="2" />
    <line x1="-40" y1="-40" x2="40" y2="40" stroke="#c0d3d8" stroke-width="1.8" />
    <line x1="-40" y1="40" x2="40" y2="-40" stroke="#c0d3d8" stroke-width="1.8" />
    <line x1="-52" y1="-21" x2="52" y2="21" stroke="#a0b5bb" stroke-width="1.5" />
    <line x1="-21" y1="-52" x2="21" y2="52" stroke="#a0b5bb" stroke-width="1.5" />
    <line x1="-52" y1="21" x2="52" y2="-21" stroke="#a0b5bb" stroke-width="1.5" />
    <line x1="-21" y1="52" x2="21" y2="-52" stroke="#a0b5bb" stroke-width="1.5" />
    </g>
    </defs>

    <!-- ================= 背景层:太阳与无缝远景 ================= -->
    <g id="background-sky">
    <!-- 温暖的晨阳与光环 -->
    <circle cx="750" cy="120" r="85" fill="#fff9db" opacity="0.4" />
    <circle cx="750" cy="120" r="55" fill="url(#sunGrad)" />

    <!-- 飘动的扁平多边形白云 (两组拼合实现无缝平移) -->
    <g class="scroll-clouds">
    <g>
    <path d="M 120 110 q 25 -30 60 -10 q 30 -25 60 5 q 25 -10 45 15 l -170 0 z" fill="#ffffff" opacity="0.82" />
    <path d="M 460 70 q 35 -35 75 -5 q 30 -25 65 0 q 30 -10 50 15 l -195 0 z" fill="#ffffff" opacity="0.65" />
    <path d="M 720 130 q 20 -20 45 -5 q 25 -20 50 5 l -100 0 z" fill="#ffffff" opacity="0.75" />
    </g>
    <g transform="translate(900, 0)">
    <path d="M 120 110 q 25 -30 60 -10 q 30 -25 60 5 q 25 -10 45 15 l -170 0 z" fill="#ffffff" opacity="0.82" />
    <path d="M 460 70 q 35 -35 75 -5 q 30 -25 65 0 q 30 -10 50 15 l -195 0 z" fill="#ffffff" opacity="0.65" />
    <path d="M 720 130 q 20 -20 45 -5 q 25 -20 50 5 l -100 0 z" fill="#ffffff" opacity="0.75" />
    </g>
    </g>

    <!-- 远山脉叠层 (向左平移) -->
    <g class="scroll-hills">
    <g fill="#9acdb5">
    <polygon points="0,375 80,310 180,375 290,290 410,375 520,325 650,375 760,295 880,375 900,375 900,375 0,375" />
    </g>
    <g transform="translate(900, 0)" fill="#9acdb5">
    <polygon points="0,375 80,310 180,375 290,290 410,375 520,325 650,375 760,295 880,375 900,375 900,375 0,375" />
    </g>
    </g>

    <!-- 扁平化绿树与矮灌木层 -->
    <g class="scroll-trees">
    <g>
    <!-- 几何圆树 -->
    <rect x="70" y="345" width="8" height="30" fill="#69513d" />
    <circle cx="74" cy="330" r="24" fill="#4ea672" />
    <rect x="340" y="340" width="10" height="35" fill="#69513d" />
    <polygon points="315,350 345,280 375,350" fill="#368f5b" />
    <rect x="620" y="348" width="7" height="28" fill="#69513d" />
    <circle cx="623" cy="336" r="20" fill="#60b884" />
    <circle cx="633" cy="340" r="14" fill="#4ea672" />
    </g>
    <g transform="translate(900, 0)">
    <rect x="70" y="345" width="8" height="30" fill="#69513d" />
    <circle cx="74" cy="330" r="24" fill="#4ea672" />
    <rect x="340" y="340" width="10" height="35" fill="#69513d" />
    <polygon points="315,350 345,280 375,350" fill="#368f5b" />
    <rect x="620" y="348" width="7" height="28" fill="#69513d" />
    <circle cx="623" cy="336" r="20" fill="#60b884" />
    <circle cx="633" cy="340" r="14" fill="#4ea672" />
    </g>
    </g>
    </g>

    <!-- ================= 地面与道路 ================= -->
    <g id="ground-and-road">
    <!-- 沥青路面 -->
    <rect x="0" y="396" width="900" height="204" fill="#3a404a" />
    <!-- 路肩石分界线 -->
    <rect x="0" y="396" width="900" height="7" fill="#f1c40f" />

    <!-- 疾驰掠过的路面虚线 -->
    <g class="scroll-road-dashes" stroke="#ffffff" stroke-width="7" stroke-linecap="round" opacity="0.85">
    <line x1="20" y1="520" x2="110" y2="520" />
    <line x1="160" y1="520" x2="250" y2="520" />
    <line x1="300" y1="520" x2="390" y2="520" />
    <line x1="440" y1="520" x2="530" y2="520" />
    <line x1="580" y1="520" x2="670" y2="520" />
    <line x1="720" y1="520" x2="810" y2="520" />
    <line x1="860" y1="520" x2="950" y2="520" />
    <line x1="1000" y1="520" x2="1090" y2="520" />
    <line x1="1140" y1="520" x2="1230" y2="520" />
    <line x1="1280" y1="520" x2="1370" y2="520" />
    </g>
    </g>

    <!-- ================= 动态主体:自行车与鹈鹕骑士 ================= -->
    <g id="bicycle-and-pelican">
    <!-- 地面接触阴影 (随骑行产生弹性形变) -->
    <ellipse id="shadow" cx="440" cy="512" rx="265" ry="14" fill="#1b2129" opacity="0.45" />

    <!-- ================= 1. 远端腿与踏板 (背景层,位于车身之后) ================= -->
    <g id="far-leg-group">
    <!-- 远端曲柄 -->
    <line id="crank-far" x1="435" y1="445" x2="410" y2="465" stroke="#718096" stroke-width="7" stroke-linecap="round" />
    <!-- 远端脚踏板 -->
    <rect id="pedal-far" x="396" y="462" width="26" height="7" rx="3" fill="#2d3748" />
    <!-- 远端大腿与小腿 (深橙色阴影腿) -->
    <path id="leg-far" d="M 385 300 Q 380 370 410 465" fill="none" stroke="#d96b00" stroke-width="14" stroke-linecap="round" stroke-linejoin="round" />
    <!-- 远端蹼足 -->
    <path id="foot-far" d="M 400 465 L 428 465 L 415 455 Z" fill="#b85300" />
    </g>

    <!-- ================= 2. 经典复古自行车实体 ================= -->
    <g id="bicycle-frame" class="bike-chassis">
    <!-- 后轮组 (圆心: 255, 442) -->
    <g id="rear-wheel" transform="translate(255, 442)">
    <!-- 轮胎 -->
    <circle cx="0" cy="0" r="68" fill="none" stroke="url(#tireGrad)" stroke-width="12" />
    <circle cx="0" cy="0" r="62" fill="none" stroke="#e6edf0" stroke-width="3" />
    <!-- 辐条组 (CSS旋转) -->
    <g class="wheel-spokes">
    <use href="#spoke-cluster" />
    </g>
    <!-- 轴心 -->
    <circle cx="0" cy="0" r="11" fill="#4a5568" />
    <circle cx="0" cy="0" r="5" fill="#f7fafc" />
    <!-- 后挡泥板 -->
    <path d="M -66 0 A 66 66 0 0 1 45 -48" fill="none" stroke="#2bd9b6" stroke-width="9" stroke-linecap="round" />
    </g>

    <!-- 前轮组 (圆心: 635, 442) -->
    <g id="front-wheel" transform="translate(635, 442)">
    <!-- 轮胎 -->
    <circle cx="0" cy="0" r="68" fill="none" stroke="url(#tireGrad)" stroke-width="12" />
    <circle cx="0" cy="0" r="62" fill="none" stroke="#e6edf0" stroke-width="3" />
    <!-- 辐条组 (CSS旋转) -->
    <g class="wheel-spokes">
    <use href="#spoke-cluster" />
    </g>
    <!-- 轴心 -->
    <circle cx="0" cy="0" r="11" fill="#4a5568" />
    <circle cx="0" cy="0" r="5" fill="#f7fafc" />
    <!-- 前挡泥板 -->
    <path d="M -40 -52 A 66 66 0 0 1 65 -10" fill="none" stroke="#2bd9b6" stroke-width="9" stroke-linecap="round" />
    </g>

    <!-- 复古流线型车架管件结构 -->
    <g id="frame-tubes" stroke="url(#frameGrad)" stroke-width="10" stroke-linecap="round" stroke-linejoin="round" fill="none">
    <!-- 平衡下叉 (后轴到中轴) -->
    <line x1="255" y1="442" x2="435" y2="445" />
    <!-- 后上叉 (后轴到座管下接头) -->
    <line x1="255" y1="442" x2="375" y2="330" />
    <!-- 立管 (座管到底部中轴) -->
    <line x1="375" y1="330" x2="435" y2="445" />
    <!-- 下管 (车头腕到底部中轴) -->
    <line x1="575" y1="315" x2="435" y2="445" />
    <!-- 弧形复古主上梁管 -->
    <path d="M 375 340 C 430 330, 520 310, 575 315" />
    <!-- 前叉 (前轮轴至把手立管) -->
    <line x1="635" y1="442" x2="575" y2="315" stroke="#22aa8e" />
    </g>

    <!-- 镀铬车把立管与优雅向后弯折燕把 -->
    <path d="M 575 315 L 565 242 C 555 238, 525 240, 505 255" fill="none" stroke="#cbd5e0" stroke-width="7" stroke-linecap="round" />
    <!-- 橡胶握把套 -->
    <path d="M 515 250 L 498 259" stroke="#744210" stroke-width="9" stroke-linecap="round" />

    <!-- 前照复古大灯与铃铛 -->
    <path d="M 578 285 L 595 288 L 595 300 L 578 297 Z" fill="#ffd166" />
    <circle cx="578" cy="291" r="9" fill="#f6ad55" />
    <circle cx="560" cy="240" r="7" fill="#ecc94b" />

    <!-- 皮革坐垫与支撑减震弹簧 -->
    <g id="saddle" transform="translate(370, 312)">
    <line x1="5" y1="18" x2="5" y2="0" stroke="#718096" stroke-width="8" stroke-linecap="round" />
    <path d="M -6 6 Q 5 12 16 6" fill="none" stroke="#a0aec0" stroke-width="3" />
    <path d="M -22 0 C -15 -8, 20 -8, 32 3 C 25 7, 5 5, -8 5 C -16 5, -20 3, -22 0 Z" fill="#5c2e0b" />
    </g>

    <!-- 大齿盘链轮盘与金色链条 -->
    <circle cx="435" cy="445" r="22" fill="#a0aec0" stroke="#718096" stroke-width="3" />
    <circle cx="435" cy="445" r="8" fill="#4a5568" />
    <!-- 链条外轮廓 -->
    <path d="M 255 435 L 435 425 A 20 20 0 0 1 450 455 L 255 450 Z" fill="none" stroke="#d69e2e" stroke-width="3.5" stroke-dasharray="7,3" />
    </g>

    <!-- ================= 3. 主角:佩戴飞行护目镜的鹈鹕 ================= -->
    <g id="pelican" class="pelican-rider">
    <!-- 短萌俏皮小尾羽 -->
    <path d="M 330 280 C 315 272, 305 285, 290 270 C 308 290, 322 295, 335 292 Z" fill="#e2e8f0" />

    <!-- 丰满白皙的主躯干 (微向前俯身冲刺姿态) -->
    <path d="M 345 285 C 335 235, 370 195, 415 190 C 450 186, 465 210, 455 260 C 445 305, 375 325, 345 285 Z" fill="#f8fafc" stroke="#edf2f7" stroke-width="1.5" />

    <!-- 优雅且富有力量感的S形长颈 -->
    <path d="M 425 205 C 435 175, 435 155, 460 145 C 475 160, 460 195, 440 215 Z" fill="#ffffff" />

    <!-- 头部基底 -->
    <circle cx="468" cy="142" r="23" fill="#ffffff" />

    <!-- ===== 鹈鹕的灵魂:超大橙黄色喉囊 (Gular Pouch) ===== -->
    <g class="gular-pouch">
    <!-- 标志性弹性喉囊大口袋 -->
    <path d="M 480 148 C 485 195, 520 240, 565 195 C 595 165, 630 155, 640 148 C 580 170, 515 170, 480 148 Z" fill="url(#pouchGrad)" opacity="0.95" />
    <!-- 喉囊微凸的半透明高光线条 -->
    <path d="M 505 168 Q 535 208 565 188" fill="none" stroke="#ffb74d" stroke-width="3" stroke-linecap="round" opacity="0.8" />
    </g>

    <!-- 坚硬狭长的粉黄上喙 (与尖端小勾爪) -->
    <path d="M 472 135 L 638 144 C 646 145, 645 152, 636 153 L 478 152 Z" fill="#ffa726" stroke="#f57c00" stroke-width="1.5" />
    <!-- 喙尖小倒钩钩爪 -->
    <path d="M 636 144 Q 643 148 637 154" fill="none" stroke="#d84315" stroke-width="2.5" stroke-linecap="round" />

    <!-- 炯炯有神的卡通大眼睛 -->
    <ellipse cx="463" cy="133" rx="6.5" ry="7.5" fill="#2d3748" />
    <circle cx="461" cy="131" r="2.5" fill="#ffffff" />
    <!-- 翘起的专注自信眉毛 -->
    <path d="M 454 125 Q 465 121 474 126" fill="none" stroke="#cbd5e0" stroke-width="3" stroke-linecap="round" />

    <!-- 复古复古飞行员皮帽 -->
    <path d="M 445 136 C 445 118, 465 116, 485 125 C 488 135, 482 142, 482 142 C 468 130, 452 132, 445 136 Z" fill="#6b4423" />
    <!-- 绑带 -->
    <path d="M 452 135 Q 456 152 462 154" fill="none" stroke="#4a2e16" stroke-width="3" />

    <!-- 额头上酷帅的飞行员铜框护目镜 -->
    <g id="goggles" transform="translate(460, 116) rotate(12)">
    <rect x="-14" y="-7" width="28" height="14" rx="6" fill="#8c5828" stroke="#3d2108" stroke-width="1.5" />
    <!-- 双目镜片高亮反光 -->
    <circle cx="-6" cy="0" r="5.5" fill="#64d8cb" stroke="#ffe082" stroke-width="1.5" />
    <circle cx="6" cy="0" r="5.5" fill="#64d8cb" stroke="#ffe082" stroke-width="1.5" />
    <!-- 镜片白色斜切反光 -->
    <line x1="-8" y1="-3" x2="-4" y2="3" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" />
    <line x1="4" y1="-3" x2="8" y2="3" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" />
    </g>

    <!-- 随风迎面狂舞的红色波点围巾 (双尾随风抖动) -->
    <g id="scarf-group">
    <!-- 围巾尾巴 1 (飘在下方) -->
    <path class="scarf-tail-1" d="M 412 218 C 365 210, 335 240, 275 220 C 325 245, 360 230, 412 226 Z" fill="#e53e3e" />
    <!-- 围巾尾巴 2 (飘在上方) -->
    <path class="scarf-tail-2" d="M 415 212 C 375 195, 340 215, 290 190 C 335 220, 375 210, 415 220 Z" fill="#c53030" />
    <!-- 围在脖颈的主围巾圈与结 -->
    <path d="M 418 202 C 438 202, 442 220, 432 226 C 418 232, 408 218, 418 202 Z" fill="#e53e3e" stroke="#9b2c2c" stroke-width="1" />
    <circle cx="414" cy="220" r="4.5" fill="#feb2b2" />
    </g>

    <!-- 鹈鹕翅膀 (如手臂般坚定自然握住把手) -->
    <!-- 翅膀主体上臂 -->
    <path d="M 375 240 C 385 215, 420 220, 450 240 C 475 255, 495 256, 508 255 C 495 268, 455 285, 410 282 C 385 280, 365 260, 375 240 Z" fill="#edf2f7" stroke="#cbd5e0" stroke-width="1.5" />
    <!-- 灰色层次飞羽羽翼细节 -->
    <path d="M 425 265 C 455 268, 485 262, 506 254 C 490 275, 450 282, 425 280 Z" fill="#718096" />
    <!-- 握住车把的拟人翅尖羽毛小手 -->
    <path d="M 502 248 C 512 245, 520 252, 516 260 C 510 266, 498 262, 502 248 Z" fill="#e2e8f0" />
    </g>

    <!-- ================= 4. 近端腿与脚踏联动 (前景层,遮挡车架) ================= -->
    <g id="near-leg-group">
    <!-- 靠近观察者的链轮曲柄臂 -->
    <line id="crank-near" x1="435" y1="445" x2="460" y2="425" stroke="#a0aec0" stroke-width="8" stroke-linecap="round" />
    <!-- 中轴螺栓亮盖 -->
    <circle cx="435" cy="445" r="7" fill="#edf2f7" />
    <!-- 近端脚踏板 -->
    <rect id="pedal-near" x="445" y="420" width="28" height="8" rx="3.5" fill="#1a202c" stroke="#4a5568" stroke-width="1.5" />

    <!-- 具有 IK 动态的近端强健大腿与小腿 -->
    <path id="thigh-near" d="M 390 295 L 430 365" fill="none" stroke="#f6ad55" stroke-width="16" stroke-linecap="round" />
    <path id="shin-near" d="M 430 365 L 458 424" fill="none" stroke="#ed8936" stroke-width="13" stroke-linecap="round" />

    <!-- 亮橙色鲜明鸟蹼足 (稳稳踏在踏板上) -->
    <g id="foot-near-group">
    <path id="foot-near" d="M 445 422 L 478 422 L 465 410 Z" fill="#dd6b20" />
    </g>
    </g>
    </g>

    <!-- 前景近景:极速掠过的草叶质感层 (增加空间进深) -->
    <g class="scroll-bushes" fill="#2d3748" opacity="0.15">
    <polygon points="120,590 140,550 160,590" />
    <polygon points="450,595 470,560 490,595" />
    <polygon points="760,590 785,545 810,590" />
    </g>
    </svg>
    </div>

    <!-- ================= 精密腿部逆运动学 (IK) 动力联动脚本 ================= -->
    <script>
    (function () {
    // 核心几何锚点参数 (基于 SVG ViewBox 坐标系统 900x600)
    const CRANK_CENTER = { x: 435, y: 445 }; // 中轴中心
    const CRANK_RADIUS = 30; // 踏板回转半径

    // 鹈鹕髋关节基础挂载点 (坐垫上方臀部)
    const HIP_BASE = { x: 388, y: 298 };

    // 鸟类腿骨长度 (大腿与小腿骨骼比例)
    const THIGH_LEN = 78;
    const SHIN_LEN = 76;

    // 获取各交互 SVG DOM 节点引用
    const crankNear = document.getElementById('crank-near');
    const pedalNear = document.getElementById('pedal-near');
    const thighNear = document.getElementById('thigh-near');
    const shinNear = document.getElementById('shin-near');
    const footNear = document.getElementById('foot-near');

    const crankFar = document.getElementById('crank-far');
    const pedalFar = document.getElementById('pedal-far');
    const legFar = document.getElementById('leg-far');
    const footFar = document.getElementById('foot-far');

    const shadow = document.getElementById('shadow');

    // 骑行时间步进变量
    let angle = 0;
    // 速度参数:与车轮 CSS 旋转周期 1.1s 保持高精度数学同步 (2 PI / (1.1s 60fps) ≈ 0.095 rad/frame)
    const speed = 0.0952;

    // 2-Bone 逆向运动学求解器 (IK Solver)
    // 计算给定臀部(h)与脚踏板(f)位置时,向前弯曲的膝关节(K)坐标
    function solveKnee(h, f, l1, l2) {
    const dx = f.x - h.x;
    const dy = f.y - h.y;
    const dist = Math.sqrt(dx dx + dy dy);

    // 极限拉伸保护(避免开方负数导致关节脱臼)
    const clampedDist = Math.min(dist, l1 + l2 - 0.01);

    // 余弦定理计算大腿与目标基准线的夹角
    const baseAngle = Math.atan2(dy, dx);
    const cosAngle = (l1 l1 + clampedDist clampedDist - l2 l2) / (2 l1 * clampedDist);
    const flexAngle = Math.acos(Math.max(-1, Math.min(1, cosAngle)));

    // 鸟类向前蹬踏膝盖向前突出弯折 (取减号使其膝盖朝右/朝前)
    const kneeAngle = baseAngle - flexAngle;

    return {
    x: h.x + l1 * Math.cos(kneeAngle),
    y: h.y + l1 * Math.sin(kneeAngle)
    };
    }

    function animate() {
    angle += speed;

    // 鹈鹕由于踩踏用力引发的臀部微小生理位移 (Bobbing 联动)
    const hipBobY = Math.sin(angle 2) 2.8;
    const currentHip = {
    x: HIP_BASE.x + Math.sin(angle) * 1.2,
    y: HIP_BASE.y + hipBobY
    };

    // 地面阴影随下压节奏产生缩放与透明度呼吸感
    if (shadow) {
    const sScale = 265 + Math.sin(angle 2) 6;
    shadow.setAttribute('rx', sScale);
    shadow.setAttribute('opacity', 0.42 + Math.cos(angle 2) 0.05);
    }

    // ================= A. 前景近端腿动力学计算 =================
    const pedalNearPos = {
    x: CRANK_CENTER.x + CRANK_RADIUS * Math.cos(angle),
    y: CRANK_CENTER.y + CRANK_RADIUS * Math.sin(angle)
    };

    // 求解近端膝盖位置
    const kneeNear = solveKnee(currentHip, pedalNearPos, THIGH_LEN, SHIN_LEN);

    // 渲染近端曲柄与踏板
    crankNear.setAttribute('x1', CRANK_CENTER.x);
    crankNear.setAttribute('y1', CRANK_CENTER.y);
    crankNear.setAttribute('x2', pedalNearPos.x);
    crankNear.setAttribute('y2', pedalNearPos.y);

    pedalNear.setAttribute('x', pedalNearPos.x - 14);
    pedalNear.setAttribute('y', pedalNearPos.y - 4);

    // 渲染近端骨骼连线
    thighNear.setAttribute('d', M ${currentHip.x} ${currentHip.y} L ${kneeNear.x} ${kneeNear.y});
    shinNear.setAttribute('d', M ${kneeNear.x} ${kneeNear.y} L ${pedalNearPos.x} ${pedalNearPos.y});

    // 渲染贴合踏板角度的近端蹼足
    footNear.setAttribute('d', M ${pedalNearPos.x - 12} ${pedalNearPos.y + 1} L ${pedalNearPos.x + 18} ${pedalNearPos.y + 1} L ${pedalNearPos.x + 4} ${pedalNearPos.y - 8} Z);

    // ================= B. 背景远端腿动力学计算 (相位差 180° / PI) =================
    const farAngle = angle + Math.PI;
    const pedalFarPos = {
    x: CRANK_CENTER.x + CRANK_RADIUS * Math.cos(farAngle),
    y: CRANK_CENTER.y + CRANK_RADIUS * Math.sin(farAngle)
    };

    // 远端臀部稍微靠内侧偏移
    const farHip = { x: currentHip.x - 4, y: currentHip.y - 2 };
    const kneeFar = solveKnee(farHip, pedalFarPos, THIGH_LEN, SHIN_LEN);

    // 渲染远端曲柄与踏板
    crankFar.setAttribute('x1', CRANK_CENTER.x);
    crankFar.setAttribute('y1', CRANK_CENTER.y);
    crankFar.setAttribute('x2', pedalFarPos.x);
    crankFar.setAttribute('y2', pedalFarPos.y);

    pedalFar.setAttribute('x', pedalFarPos.x - 13);
    pedalFar.setAttribute('y', pedalFarPos.y - 3.5);

    // 远端腿采用连续平滑三次贝塞尔曲线绘制,显得更具空间层次感
    legFar.setAttribute('d', M ${farHip.x} ${farHip.y} Q ${kneeFar.x} ${kneeFar.y} ${pedalFarPos.x} ${pedalFarPos.y});
    footFar.setAttribute('d', M ${pedalFarPos.x - 10} ${pedalFarPos.y + 1} L ${pedalFarPos.x + 16} ${pedalFarPos.y + 1} L ${pedalFarPos.x + 3} ${pedalFarPos.y - 7} Z);

    requestAnimationFrame(animate);
    }

    // 启动平滑 60FPS 运动学计算循环
    requestAnimationFrame(animate);
    })();
    </script>
    </body>
    </html>

    主楼
  • IPO-nodeseek

    想起帝胡云

    #1
  • hoofei

    不错的

    #2
  • CIYYYT

    哈基米的前端还是很好看 ^-^

    #3
  • 爱云网络科技

    一个个发 ,我也试试去 ^-^

    #4
  • amashazzz

    貌似不错

    #5
  • 冰镇可乐

    不错

    #6
  • 涤尘

    哈基咪前端依然可以 ^-^

    #7

发表回复

登录后回复