deepseek v4 flash 正式版做鹈鹕骑自行车

AI摘要
【知识分享】该内容为一份完整的HTML/CSS/JavaScript源代码,使用SVG绘制了鹈鹕骑自行车的2D动画。代码包含场景构建、角色绘制、动画逻辑及交互控制(暂停/速度切换),属于前端开发技术示例,内容健康无害。

提示词:

创建一个HTML,内容是SVG绘制一个鹈鹕骑自行车的2D动画。

deepseek v4 flash 正式版做鹈鹕骑自行车

源代码:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>鹈鹕骑自行车 🚲</title>
<style>
  :root { --ground-speed: 1.6s; }
  * { box-sizing: border-box; }
  body {
    margin: 0; min-height: 100vh;
    display: flex; align-items: center; justify-content: center;
    font-family: "Segoe UI", "Microsoft YaHei", system-ui, sans-serif;
    background: linear-gradient(160deg, #2b3a55 0%, #3f5d8c 45%, #74a8d8 100%);
    padding: 24px;
  }
  .page { width: min(960px, 100%); text-align: center; }
  h1 {
    margin: 0 0 6px; font-size: clamp(24px, 4vw, 36px);
    color: #fff; letter-spacing: 2px; text-shadow: 0 2px 10px rgba(0,0,0,.25);
  }
  .sub { margin: 0 0 18px; color: #d9ecff; font-size: 14px; letter-spacing: 4px; }
  .card {
    background: linear-gradient(180deg, #ffffff, #eef7ff);
    border-radius: 24px; padding: 14px 14px 16px;
    box-shadow: 0 20px 60px rgba(8,20,40,.45);
  }
  svg { width: 100%; height: auto; display: block; border-radius: 16px; }
  .controls { display: flex; gap: 12px; justify-content: center; margin-top: 14px; flex-wrap: wrap; }
  button {
    border: none; cursor: pointer; font-size: 15px; font-family: inherit;
    padding: 9px 22px; border-radius: 999px; color: #fff;
    background: linear-gradient(135deg, #ff9f1c, #f77f00);
    box-shadow: 0 4px 14px rgba(247,127,0,.35);
    transition: transform .15s, box-shadow .15s;
  }
  button:hover { transform: translateY(-2px); box-shadow: 0 6px 18px rgba(247,127,0,.45); }
  button:active { transform: translateY(0); }
  button.ghost { background: linear-gradient(135deg, #5b7db1, #3f5d8c); box-shadow: 0 4px 14px rgba(63,93,140,.35); }
  button.ghost:hover { box-shadow: 0 6px 18px rgba(63,93,140,.45); }
  footer { margin-top: 14px; color: #cfe6ff; font-size: 13px; opacity: .85; }

  /* ---------- SVG 动画 ---------- */
  .ground2 { animation: scroll var(--ground-speed, 1.6s) linear infinite; }
  .cloud { animation: drift 26s linear infinite; }
  .cloud.c2 { animation-duration: 34s; }
  .cloud.c3 { animation-duration: 22s; }
  .dust { animation: dust .5s ease-in infinite; }
  .dust.d2 { animation-delay: .25s; }
  .dust.d3 { animation-delay: .12s; }
  .paused .ground2, .paused .cloud, .paused .dust { animation-play-state: paused; }

  @keyframes scroll { from { transform: translateX(0); } to { transform: translateX(-400px); } }
  @keyframes drift  { from { transform: translateX(0); } to { transform: translateX(-1250px); } }
  @keyframes dust   { 0% { transform: translateY(0); opacity: .7; } 100% { transform: translateY(-16px); opacity: 0; } }
</style>
</head>
<body>
<div class="page">
  <h1>🚲 鹈鹕骑自行车</h1>
  <p class="sub">PELICAN ON A BIKE · 纯 SVG 动画</p>
  <div class="card">
    <svg id="scene" viewBox="0 0 800 500" role="img" aria-label="鹈鹕骑自行车动画">
      <defs>
        <linearGradient id="sky" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stop-color="#8ED3FF"/>
          <stop offset="1" stop-color="#EAF8FF"/>
        </linearGradient>
        <linearGradient id="groundG" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stop-color="#8FD65F"/>
          <stop offset="1" stop-color="#57A83B"/>
        </linearGradient>
        <radialGradient id="sunGlow">
          <stop offset="0" stop-color="#FFE97A" stop-opacity=".9"/>
          <stop offset="1" stop-color="#FFE97A" stop-opacity="0"/>
        </radialGradient>
        <g id="groundPat">
          <!-- 小草 -->
          <line x1="18" y1="428" x2="18" y2="416" stroke="#2F7D3F" stroke-width="2.5" stroke-linecap="round"/>
          <line x1="46" y1="430" x2="46" y2="420" stroke="#3E9B4F" stroke-width="2.5" stroke-linecap="round"/>
          <line x1="72" y1="426" x2="72" y2="414" stroke="#57B857" stroke-width="2.5" stroke-linecap="round"/>
          <line x1="108" y1="432" x2="108" y2="422" stroke="#2F7D3F" stroke-width="2.5" stroke-linecap="round"/>
          <line x1="140" y1="428" x2="140" y2="417" stroke="#3E9B4F" stroke-width="2.5" stroke-linecap="round"/>
          <line x1="172" y1="430" x2="172" y2="418" stroke="#57B857" stroke-width="2.5" stroke-linecap="round"/>
          <line x1="205" y1="426" x2="205" y2="415" stroke="#2F7D3F" stroke-width="2.5" stroke-linecap="round"/>
          <line x1="238" y1="432" x2="238" y2="421" stroke="#3E9B4F" stroke-width="2.5" stroke-linecap="round"/>
          <line x1="270" y1="428" x2="270" y2="416" stroke="#57B857" stroke-width="2.5" stroke-linecap="round"/>
          <line x1="302" y1="430" x2="302" y2="419" stroke="#2F7D3F" stroke-width="2.5" stroke-linecap="round"/>
          <line x1="336" y1="426" x2="336" y2="414" stroke="#3E9B4F" stroke-width="2.5" stroke-linecap="round"/>
          <line x1="368" y1="432" x2="368" y2="422" stroke="#57B857" stroke-width="2.5" stroke-linecap="round"/>
          <!-- 小花 -->
          <circle cx="60" cy="424" r="4.5" fill="#FFF3E0"/>
          <circle cx="60" cy="424" r="2" fill="#FFC300"/>
          <circle cx="150" cy="420" r="4" fill="#FFD166"/>
          <circle cx="150" cy="420" r="1.8" fill="#E8734A"/>
          <circle cx="228" cy="426" r="4.5" fill="#FFF3E0"/>
          <circle cx="228" cy="426" r="2" fill="#FFC300"/>
          <circle cx="320" cy="420" r="4" fill="#FFD166"/>
          <circle cx="320" cy="420" r="1.8" fill="#E8734A"/>
          <circle cx="388" cy="424" r="4" fill="#FFD166"/>
          <circle cx="388" cy="424" r="1.8" fill="#E8734A"/>
          <!-- 石子 -->
          <circle cx="96" cy="436" r="2.6" fill="#9AA58C"/>
          <circle cx="190" cy="438" r="2.2" fill="#8A957F"/>
          <circle cx="352" cy="436" r="2.6" fill="#9AA58C"/>
        </g>
      </defs>

      <!-- 天空 -->
      <rect width="800" height="500" fill="url(#sky)"/>

      <!-- 太阳 + 旋转光芒 -->
      <g>
        <circle cx="690" cy="78" r="52" fill="url(#sunGlow)"/>
        <g>
          <animateTransform attributeName="transform" type="rotate" from="0 690 78" to="360 690 78" dur="40s" repeatCount="indefinite"/>
          <line x1="690" y1="78" x2="690" y2="26" stroke="#FFD93D" stroke-width="5" stroke-linecap="round" opacity=".85"/>
          <line x1="690" y1="78" x2="726.8" y2="41.2" stroke="#FFD93D" stroke-width="5" stroke-linecap="round" opacity=".85"/>
          <line x1="690" y1="78" x2="742" y2="78" stroke="#FFD93D" stroke-width="5" stroke-linecap="round" opacity=".85"/>
          <line x1="690" y1="78" x2="726.8" y2="114.8" stroke="#FFD93D" stroke-width="5" stroke-linecap="round" opacity=".85"/>
          <line x1="690" y1="78" x2="690" y2="130" stroke="#FFD93D" stroke-width="5" stroke-linecap="round" opacity=".85"/>
          <line x1="690" y1="78" x2="653.2" y2="114.8" stroke="#FFD93D" stroke-width="5" stroke-linecap="round" opacity=".85"/>
          <line x1="690" y1="78" x2="638" y2="78" stroke="#FFD93D" stroke-width="5" stroke-linecap="round" opacity=".85"/>
          <line x1="690" y1="78" x2="653.2" y2="41.2" stroke="#FFD93D" stroke-width="5" stroke-linecap="round" opacity=".85"/>
        </g>
        <circle cx="690" cy="78" r="34" fill="#FFD93D" stroke="#FFC300" stroke-width="3"/>
      </g>

      <!-- 云朵 -->
      <g class="cloud">
        <ellipse cx="950" cy="80" rx="58" ry="23" fill="#fff" opacity=".95"/>
        <ellipse cx="995" cy="68" rx="42" ry="19" fill="#fff" opacity=".95"/>
        <ellipse cx="905" cy="70" rx="36" ry="17" fill="#fff" opacity=".95"/>
      </g>
      <g class="cloud c2">
        <ellipse cx="620" cy="58" rx="46" ry="18" fill="#fff" opacity=".9"/>
        <ellipse cx="658" cy="50" rx="32" ry="15" fill="#fff" opacity=".9"/>
        <ellipse cx="582" cy="52" rx="28" ry="13" fill="#fff" opacity=".9"/>
      </g>
      <g class="cloud c3">
        <ellipse cx="1180" cy="112" rx="52" ry="20" fill="#fff" opacity=".92"/>
        <ellipse cx="1222" cy="102" rx="36" ry="16" fill="#fff" opacity=".92"/>
        <ellipse cx="1138" cy="104" rx="30" ry="14" fill="#fff" opacity=".92"/>
      </g>

      <!-- 远山 -->
      <path d="M0 405 Q 90 372 190 400 T 390 396 T 590 402 T 800 396 L 800 405 Z" fill="#A9E08C" opacity=".55"/>

      <!-- 草地 -->
      <rect x="0" y="405" width="800" height="95" fill="url(#groundG)"/>

      <!-- 滚动的地面(草//石子) -->
      <g transform="translate(0,0)"><use class="ground2" href="#groundPat"/></g>
      <g transform="translate(400,0)"><use class="ground2" href="#groundPat"/></g>

      <!-- 扬起的尘土 -->
      <circle class="dust" cx="196" cy="432" r="3.5" fill="#B5B98A"/>
      <circle class="dust d2" cx="178" cy="438" r="2.6" fill="#B5B98A"/>
      <circle class="dust d3" cx="212" cy="436" r="2.2" fill="#B5B98A"/>
      <circle class="dust" cx="498" cy="430" r="3.4" fill="#B5B98A"/>
      <circle class="dust d2" cx="482" cy="436" r="2.4" fill="#B5B98A"/>
      <circle class="dust d3" cx="514" cy="434" r="2.1" fill="#B5B98A"/>

      <!-- ============ 自行车 ============ -->
      <g id="bike">
        <!-- 挡泥板 -->
        <path d="M172 340 A68 68 0 0 1 288 340" fill="none" stroke="#E63946" stroke-width="6" stroke-linecap="round"/>
        <path d="M472 340 A68 68 0 0 1 588 340" fill="none" stroke="#E63946" stroke-width="6" stroke-linecap="round"/>

        <!-- 后轮 -->
        <circle cx="230" cy="340" r="65" fill="none" stroke="#26282C" stroke-width="10"/>
        <circle cx="230" cy="340" r="56" fill="none" stroke="#9AA3AB" stroke-width="3"/>
        <g id="spokes-rear">
          <line x1="230" y1="340" x2="230" y2="292" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="230" y1="340" x2="263.9" y2="306.1" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="230" y1="340" x2="278" y2="340" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="230" y1="340" x2="263.9" y2="373.9" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="230" y1="340" x2="230" y2="388" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="230" y1="340" x2="196.1" y2="373.9" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="230" y1="340" x2="182" y2="340" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="230" y1="340" x2="196.1" y2="306.1" stroke="#B9C2CA" stroke-width="1.6"/>
        </g>
        <circle cx="230" cy="340" r="7" fill="#5E666E"/>

        <!-- 前轮 -->
        <circle cx="530" cy="340" r="65" fill="none" stroke="#26282C" stroke-width="10"/>
        <circle cx="530" cy="340" r="56" fill="none" stroke="#9AA3AB" stroke-width="3"/>
        <g id="spokes-front">
          <line x1="530" y1="340" x2="530" y2="292" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="530" y1="340" x2="563.9" y2="306.1" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="530" y1="340" x2="578" y2="340" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="530" y1="340" x2="563.9" y2="373.9" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="530" y1="340" x2="530" y2="388" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="530" y1="340" x2="496.1" y2="373.9" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="530" y1="340" x2="482" y2="340" stroke="#B9C2CA" stroke-width="1.6"/>
          <line x1="530" y1="340" x2="496.1" y2="306.1" stroke="#B9C2CA" stroke-width="1.6"/>
        </g>
        <circle cx="530" cy="340" r="7" fill="#5E666E"/>

        <!-- 车架 -->
        <g stroke="#E63946" stroke-width="7" stroke-linecap="round" stroke-linejoin="round" fill="none">
          <line x1="230" y1="340" x2="310" y2="210"/>
          <line x1="310" y1="210" x2="330" y2="340"/>
          <line x1="310" y1="210" x2="465" y2="205"/>
          <line x1="330" y1="340" x2="465" y2="205"/>
          <line x1="230" y1="340" x2="330" y2="340"/>
          <path d="M465 205 L 495 275 L 530 340"/>
        </g>
        <rect x="458" y="200" width="15" height="14" rx="4" fill="#E63946"/>
        <circle cx="330" cy="340" r="9" fill="#D7DEE3" stroke="#9AA3AB" stroke-width="2"/>

        <!-- 座垫 -->
        <rect x="283" y="196" width="55" height="14" rx="7" fill="#7A4E2D" stroke="#5C3A20" stroke-width="2"/>

        <!-- 车把 + 车铃 -->
        <path d="M465 205 C 460 186 472 174 490 176" fill="none" stroke="#3A3F45" stroke-width="6" stroke-linecap="round"/>
        <rect x="483" y="172" width="15" height="9" rx="4" fill="#2B2D31"/>
        <circle cx="474" cy="190" r="5" fill="#E8ECEF" stroke="#B7C0C8" stroke-width="1.5"/>

        <!-- 车筐 + 小鱼 -->
        <line x1="490" y1="176" x2="490" y2="188" stroke="#A97C4E" stroke-width="3"/>
        <rect x="478" y="188" width="46" height="32" rx="7" fill="#C89B6A" stroke="#A97C4E" stroke-width="2.5"/>
        <line x1="486" y1="192" x2="486" y2="216" stroke="#A97C4E" stroke-width="1.5"/>
        <line x1="494" y1="190" x2="494" y2="217" stroke="#A97C4E" stroke-width="1.5"/>
        <line x1="502" y1="192" x2="502" y2="216" stroke="#A97C4E" stroke-width="1.5"/>
        <line x1="510" y1="192" x2="510" y2="216" stroke="#A97C4E" stroke-width="1.5"/>
        <path d="M492 208 q 8 -4 16 0 q -8 6 -16 0 Z" fill="#FF9F1C"/>
        <path d="M508 208 l 6 -4 l 0 8 Z" fill="#F77F00"/>
        <circle cx="497" cy="206" r="1.1" fill="#1F2937"/>

        <!-- 尾灯 -->
        <circle cx="298" cy="226" r="4.5" fill="#FF5A5F"/>

        <!-- 曲柄组(JS 驱动旋转) -->
        <g id="crank">
          <line x1="330" y1="340" x2="362" y2="340" stroke="#2B2D31" stroke-width="6" stroke-linecap="round"/>
          <line x1="330" y1="340" x2="298" y2="340" stroke="#5A6068" stroke-width="5" stroke-linecap="round" opacity=".8"/>
          <rect x="353" y="334" width="18" height="11" rx="3" fill="#333" stroke="#1f2226" stroke-width="1.5"/>
          <rect x="289" y="334" width="18" height="11" rx="3" fill="#4A5058" stroke="#2b2f35" stroke-width="1.5" opacity=".85"/>
        </g>
      </g>

      <!-- ============ 鹈鹕(含腿/脚,JS 驱动) ============ -->
      <g id="pelican-top">
        <!-- 尾羽 -->
        <path d="M258 165 Q 234 150 236 138 Q 250 148 270 156 Z" fill="#FFFDF5" stroke="#E0D9C4" stroke-width="1.5"/>

        <!-- 双腿(IK 动画) -->
        <path id="leg-l" d="M313 198 L 330 280 L 330 372" fill="none" stroke="#FF8C42" stroke-width="9" stroke-linecap="round" stroke-linejoin="round"/>
        <path id="leg-r" d="M313 198 L 330 260 L 330 308" fill="none" stroke="#FF8C42" stroke-width="9" stroke-linecap="round" stroke-linejoin="round"/>

        <!-- 双脚(踩在踏板上) -->
        <ellipse id="foot-l" cx="330" cy="366" rx="10" ry="6.5" fill="#FF8C42" stroke="#E07A36" stroke-width="1.5"/>
        <ellipse id="foot-r" cx="330" cy="302" rx="10" ry="6.5" fill="#FF8C42" stroke="#E07A36" stroke-width="1.5"/>

        <!-- 身体 -->
        <ellipse cx="300" cy="165" rx="58" ry="42" fill="#FFFDF5" stroke="#E0D9C4" stroke-width="2"/>

        <!-- 翅膀(微扇) -->
        <g id="wing">
          <path d="M296 160 C 268 128 258 108 262 96 C 280 106 298 116 308 136 C 316 148 314 160 306 164 Z" fill="#F5F1E6" stroke="#DCD5C0" stroke-width="1.5"/>
          <path d="M280 122 Q 288 132 296 140" stroke="#DCD5C0" stroke-width="1.5" fill="none"/>
          <path d="M288 108 Q 296 120 302 130" stroke="#DCD5C0" stroke-width="1.5" fill="none"/>
        </g>

        <!-- 脖子 -->
        <path d="M338 172 Q 372 144 396 124" fill="none" stroke="#E0D9C4" stroke-width="28" stroke-linecap="round"/>
        <path d="M338 172 Q 372 144 396 124" fill="none" stroke="#FFFDF5" stroke-width="24" stroke-linecap="round"/>

        <!--+ 头盔 -->
        <circle cx="405" cy="112" r="23" fill="#FFFDF5" stroke="#E0D9C4" stroke-width="2"/>
        <path d="M 386 118 A 24 24 0 0 1 428 114 L 430 120 L 384 122 Z" fill="#FFC300" stroke="#E6A800" stroke-width="2" stroke-linejoin="round"/>
        <circle cx="406" cy="96" r="4" fill="#FFC300" stroke="#E6A800" stroke-width="1.5"/>

        <!-- 眼睛 + 脸颊 -->
        <circle cx="413" cy="107" r="5" fill="#1F2937"/>
        <circle cx="414.5" cy="105" r="1.8" fill="#fff"/>
        <ellipse cx="419" cy="120" rx="6" ry="4" fill="#FFD9C0" opacity=".7"/>

        <!-- 上喙 -->
        <path d="M 414 102 C 448 98 478 102 502 108 C 488 116 470 113 414 114 Z" fill="#FF9F1C" stroke="#E88600" stroke-width="2" stroke-linejoin="round"/>
        <circle cx="438" cy="105" r="1.4" fill="#C96A00"/>

        <!-- 下喙 + 大喉囊(JS 驱动张合) -->
        <g id="beak">
          <path d="M 414 115 C 442 119 468 123 492 128 C 484 142 470 148 458 150 C 442 160 426 154 420 136 C 417 126 414 120 414 115 Z" fill="#FFB627" stroke="#E89C0D" stroke-width="1.5" opacity=".95"/>
          <path d="M 428 122 C 440 126 452 130 460 134 C 452 142 440 144 430 138 Z" fill="#FFD36B" opacity=".65"/>
        </g>
      </g>
    </svg>

    <div class="controls">
      <button id="btn-play">⏸ 暂停</button>
      <button id="btn-speed" class="ghost">速度 1x</button>
    </div>
  </div>
  <footer><b>空格键</b> 暂停 / 继续 · 点击「速度」切换节奏 🚴</footer>
</div>

<script>
(function () {
  const scene = document.getElementById('scene');
  const el = function (id) { return document.getElementById(id); };

  const BB = { x: 330, y: 340 };        // 中轴
  const R = 32;                          // 曲柄半径
  const L1 = 95, L2 = 85;                // 大腿 / 小腿长
  const HIP = { x: 313, y: 198 };        // 髋关节
  const WHEEL_RATIO = 2.4;               // 轮子/曲柄 转速比

  let angle = -Math.PI / 2;              // 起始:右脚在最高点
  let paused = false;
  let speedIdx = 0;
  const speeds = [1, 2, 4];
  let lastT = null;

  // 双腿 IK:已知髋与脚,解出膝盖位置(膝盖朝前 = 行驶方向 +x 侧)
  function setLeg(path, fx, fy) {
    const dx = fx - HIP.x, dy = fy - HIP.y;
    let d = Math.hypot(dx, dy);
    let kx, ky;
    const max = L1 + L2;
    if (d >= max) {
      kx = HIP.x + dx / d * L1;
      ky = HIP.y + dy / d * L1;
    } else {
      d = Math.max(d, 1e-6);
      const cosA = (L1 * L1 + d * d - L2 * L2) / (2 * L1 * d);
      const A = Math.acos(Math.min(1, Math.max(-1, cosA)));
      const ux = dx / d, uy = dy / d;
      kx = HIP.x + (ux * Math.cos(A) + uy * Math.sin(A)) * L1;
      ky = HIP.y + (-ux * Math.sin(A) + uy * Math.cos(A)) * L1;
    }
    path.setAttribute('d', 'M ' + HIP.x + ' ' + HIP.y + ' L ' + kx + ' ' + ky + ' L ' + fx + ' ' + fy);
  }

  function frame(t) {
    if (!paused) {
      if (lastT === null) lastT = t;
      const dt = Math.min((t - lastT) / 1000, 0.05);
      lastT = t;
      angle += dt * 0.8 * speeds[speedIdx] * Math.PI * 2;

      const deg = angle * 180 / Math.PI;
      el('crank').setAttribute('transform', 'rotate(' + deg + ' 330 340)');

      const wd = deg * WHEEL_RATIO;
      el('spokes-rear').setAttribute('transform', 'rotate(' + wd + ' 230 340)');
      el('spokes-front').setAttribute('transform', 'rotate(' + wd + ' 530 340)');

      // 身体随踩踏轻微起伏
      const bounce = Math.sin(angle * 2) * 2.2;
      el('pelican-top').setAttribute('transform', 'translate(0 ' + bounce.toFixed(2) + ')');

      // 双脚位置(局部坐标 = 世界坐标 - bounce)
      const f1 = { x: BB.x + R * Math.cos(angle), y: BB.y + R * Math.sin(angle) - bounce };
      const f2 = { x: BB.x + R * Math.cos(angle + Math.PI), y: BB.y + R * Math.sin(angle + Math.PI) - bounce };

      setLeg(el('leg-r'), f1.x, f1.y);
      setLeg(el('leg-l'), f2.x, f2.y);

      el('foot-r').setAttribute('cx', f1.x); el('foot-r').setAttribute('cy', f1.y);
      el('foot-l').setAttribute('cx', f2.x); el('foot-l').setAttribute('cy', f2.y);

      // 翅膀随节奏微扇
      const wing = Math.sin(angle * 2) * 5;
      el('wing').setAttribute('transform', 'rotate(' + wing.toFixed(2) + ' 302 158)');

      // 大喉囊随节奏张合
      const beak = -11 * Math.pow(Math.max(0, Math.sin(angle - 0.6)), 2);
      el('beak').setAttribute('transform', 'rotate(' + beak.toFixed(2) + ' 414 115)');
    }
    requestAnimationFrame(frame);
  }
  requestAnimationFrame(frame);

  // 控制
  el('btn-play').addEventListener('click', function () {
    paused = !paused;
    scene.classList.toggle('paused', paused);
    if (paused) { scene.pauseAnimations(); } else { scene.unpauseAnimations(); }
    this.textContent = paused ? '▶ 继续' : '⏸ 暂停';
    lastT = null;
  });

  el('btn-speed').addEventListener('click', function () {
    speedIdx = (speedIdx + 1) % speeds.length;
    this.textContent = '速度 ' + speeds[speedIdx] + 'x';
    scene.style.setProperty('--ground-speed', (1.6 / speeds[speedIdx]) + 's');
  });

  window.addEventListener('keydown', function (e) {
    if (e.code === 'Space') { e.preventDefault(); el('btn-play').click(); }
  });
})();
</script>
</body>
</html>
本作品采用《CC 协议》,转载必须注明作者和本文链接
六月的风
Junwind
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
躺平大叔 @ 躺平社区
文章
207
粉丝
18
喜欢
111
收藏
64
排名:246
访问:3.9 万
私信
所有博文