<!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>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background: #cbe7ec;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow: hidden;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.scene-container {
width: 100%;
max-width: 960px;
aspect-ratio: 16 / 9;
background: linear-gradient(to bottom, #72c3dc 0%, #b2e3e8 65%, #d8ebd6 65%, #c5dfc1 76%, #68747a 76%, #4b5459 100%);
border-radius: 20px;
box-shadow: 0 20px 45px rgba(0, 0, 0, 0.15);
position: relative;
overflow: hidden;
}
svg {
width: 100%;
height: 100%;
display: block;
}
/* ================= 动画定义 ================= */
/* 车轮与曲柄旋转 (顺时针) */
.spin {
animation: wheel-spin 0.8s linear infinite;
}
#wheel-rear, #spokes-rear {
transform-origin: 260px 410px;
}
#wheel-front, #spokes-front {
transform-origin: 620px 410px;
}
#crank-group {
transform-origin: 430px 410px;
animation: wheel-spin 0.8s linear infinite;
}
/* 保持踏板水平 */
.pedal-counter {
transform-origin: center;
animation: wheel-spin 0.8s linear infinite reverse;
}
@keyframes wheel-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* 地面与标线后退动画 */
.road-dashes {
stroke-dasharray: 40 30;
animation: move-road 0.4s linear infinite;
}
@keyframes move-road {
from { stroke-dashoffset: 0; }
to { stroke-dashoffset: 70; }
}
.ground-stripes {
animation: move-stripes 0.8s linear infinite;
}
@keyframes move-stripes {
from { transform: translateX(0); }
to { transform: translateX(-120px); }
}
/* 云朵飘动 */
.cloud-slow {
animation: cloud-pass 16s linear infinite;
}
.cloud-fast {
animation: cloud-pass 10s linear infinite;
}
@keyframes cloud-pass {
from { transform: translateX(1000px); }
to { transform: translateX(-300px); }
}
/* 鹈鹕与车架颠簸微颤动 */
.bike-pelican {
animation: ride-bounce 0.4s ease-in-out infinite alternate;
transform-origin: 430px 410px;
}
@keyframes ride-bounce {
0% { transform: translateY(0px) rotate(0deg); }
100% { transform: translateY(-3.5px) rotate(0.4deg); }
}
/* 鹈鹕头部与大嘴的弹性微颤 */
.pelican-head-group {
animation: head-nod 0.4s ease-in-out infinite alternate;
transform-origin: 440px 190px;
}
@keyframes head-nod {
0% { transform: rotate(0deg); }
100% { transform: rotate(2deg) translateY(-1px); }
}
/* 喉囊抖动 */
.pouch-jiggle {
animation: pouch-wiggle 0.4s ease-in-out infinite alternate;
transform-origin: 490px 220px;
}
@keyframes pouch-wiggle {
0% { transform: scale(1, 1); }
100% { transform: scale(1.04, 0.96); }
}
/* 围巾飘扬 */
.scarf-tail {
animation: scarf-wave 0.3s ease-in-out infinite alternate;
transform-origin: 380px 220px;
}
@keyframes scarf-wave {
0% { transform: rotate(-6deg) skewX(-4deg); }
100% { transform: rotate(8deg) skewX(6deg); }
}
/* 腿部蹬车动画 */
.front-leg {
animation: leg-pedal 0.8s ease-in-out infinite;
transform-origin: 390px 280px;
}
@keyframes leg-pedal {
0% { transform: rotate(0deg); }
25% { transform: rotate(18deg) translateY(3px); }
50% { transform: rotate(3deg) translateY(6px); }
75% { transform: rotate(-15deg) translateY(1px); }
100% { transform: rotate(0deg); }
}
/* 眼睛眨眼动画 */
.eye-blink {
animation: blink 3.5s infinite;
transform-origin: 442px 172px;
}
@keyframes blink {
0%, 94%, 100% { transform: scaleY(1); }
97% { transform: scaleY(0.1); }
}
</style>
</head>
<body>
<div class="scene-container">
<svg viewBox="0 0 960 540">
<defs>
<!-- 喉囊渐变 -->
<linearGradient id="pouchGrad" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stop-color="#f8b133"/>
<stop offset="100%" stop-color="#ea7326"/>
</linearGradient>
<!-- 鸟身渐变 -->
<linearGradient id="bodyGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#ffffff"/>
<stop offset="100%" stop-color="#d6e4ea"/>
</linearGradient>
<!-- 车架金属色 -->
<linearGradient id="frameGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#00b4d8"/>
<stop offset="100%" stop-color="#0077b6"/>
</linearGradient>
<!-- 轮毂与辐条模板 -->
<g id="wheel-spokes">
<circle cx="0" cy="0" r="68" fill="none" stroke="#2b2d42" stroke-width="12"/>
<circle cx="0" cy="0" r="63" fill="none" stroke="#cbd5e1" stroke-width="2"/>
<line x1="-62" y1="0" x2="62" y2="0" stroke="#94a3b8" stroke-width="1.8"/>
<line x1="0" y1="-62" x2="0" y2="62" stroke="#94a3b8" stroke-width="1.8"/>
<line x1="-44" y1="-44" x2="44" y2="44" stroke="#94a3b8" stroke-width="1.8"/>
<line x1="-44" y1="44" x2="44" y2="-44" stroke="#94a3b8" stroke-width="1.8"/>
<line x1="-58" y1="-23" x2="58" y2="23" stroke="#94a3b8" stroke-width="1.5"/>
<line x1="-23" y1="-58" x2="23" y2="58" stroke="#94a3b8" stroke-width="1.5"/>
<circle cx="0" cy="0" r="10" fill="#475569"/>
</g>
</defs>
<!-- ================= 背景元素 ================= -->
<!-- 远景山脉 -->
<path d="M-50 355 L120 250 L280 355 L450 220 L680 355 L850 260 L1020 355 Z" fill="#99c9af" opacity="0.6"/>
<path d="M50 355 L210 280 L360 355 L580 270 L750 355 L900 295 L1020 355 Z" fill="#b9dec7" opacity="0.7"/>
<!-- 云朵 -->
<g class="cloud-slow">
<path d="M 0 110 Q 20 80 50 90 Q 70 65 100 80 Q 130 70 145 95 Q 165 95 165 120 Q 155 140 125 135 L 20 135 Q -5 130 0 110 Z" fill="#ffffff" opacity="0.85"/>
</g>
<g class="cloud-fast" style="animation-delay: -5s;">
<path d="M 0 70 Q 25 45 60 55 Q 85 30 120 45 Q 150 40 165 65 Q 190 70 185 95 Q 170 115 140 110 L 25 110 Q -5 105 0 70 Z" fill="#ffffff" opacity="0.9"/>
</g>
<!-- 地面草皮小杂点与路面 -->
<g class="ground-stripes">
<line x1="0" y1="390" x2="1100" y2="390" stroke="#a7cb9f" stroke-width="3" stroke-dasharray="15 45"/>
<line x1="20" y1="400" x2="1120" y2="400" stroke="#95ba8d" stroke-width="2.5" stroke-dasharray="25 60"/>
</g>
<!-- 道路中心虚线 -->
<line x1="-100" y1="475" x2="1060" y2="475" stroke="#ffffff" stroke-width="7" stroke-linecap="round" class="road-dashes" opacity="0.75"/>
<line x1="0" y1="416" x2="960" y2="416" stroke="#333c41" stroke-width="3" opacity="0.4"/>
<!-- ================= 自行车后层 (远端脚蹬与曲柄) ================= -->
<g id="crank-back" class="spin" style="transform-origin: 430px 410px;">
<line x1="430" y1="410" x2="395" y2="385" stroke="#64748b" stroke-width="6" stroke-linecap="round"/>
<!-- 远端脚踏板 -->
<g class="pedal-counter" style="transform-origin: 395px 385px;">
<rect x="382" y="382" width="26" height="7" rx="3" fill="#334155"/>
</g>
</g>
<!-- ================= 骑车主体(车架 + 鹈鹕) ================= -->
<g class="bike-pelican">
<!-- 后轮 -->
<g id="wheel-rear" class="spin">
<use href="#wheel-spokes" x="260" y="410"/>
</g>
<!-- 前轮 -->
<g id="wheel-front" class="spin">
<use href="#wheel-spokes" x="620" y="410"/>
</g>
<!-- 自行车车架 -->
<g id="bike-frame">
<!-- 链条与齿轮盘 -->
<circle cx="430" cy="410" r="20" fill="none" stroke="#64748b" stroke-width="6"/>
<line x1="260" y1="410" x2="430" y2="410" stroke="#475569" stroke-width="4"/> <!-- 平叉 -->
<line x1="260" y1="410" x2="370" y2="295" stroke="url(#frameGrad)" stroke-width="9" stroke-linecap="round"/> <!-- 后上叉 -->
<line x1="430" y1="410" x2="370" y2="295" stroke="url(#frameGrad)" stroke-width="11" stroke-linecap="round"/> <!-- 立管 -->
<line x1="430" y1="410" x2="550" y2="285" stroke="url(#frameGrad)" stroke-width="11" stroke-linecap="round"/> <!-- 下管 -->
<line x1="370" y1="295" x2="540" y2="270" stroke="url(#frameGrad)" stroke-width="9" stroke-linecap="round"/> <!-- 上管 -->
<line x1="550" y1="260" x2="620" y2="410" stroke="url(#frameGrad)" stroke-width="9" stroke-linecap="round"/> <!-- 前叉 -->
<!-- 车座 -->
<path d="M 370 295 L 365 270" stroke="#334155" stroke-width="8" stroke-linecap="round"/>
<path d="M 330 268 C 345 264, 385 264, 400 274 C 385 277, 360 277, 330 268 Z" fill="#1e293b"/>
<!-- 车把与把立 -->
<line x1="550" y1="260" x2="538" y2="225" stroke="#94a3b8" stroke-width="7" stroke-linecap="round"/>
<!-- 经典弯把 -->
<path d="M 538 225 Q 565 205 570 230 Q 570 245 555 245" fill="none" stroke="#0f172a" stroke-width="6" stroke-linecap="round"/>
</g>
<!-- ================= 鹈鹕角色 ================= -->
<g id="pelican">
<!-- 尾羽 -->
<path d="M 320 280 C 285 275 275 295 290 310 C 315 315 330 305 340 290 Z" fill="#94a3b8"/>
<path d="M 315 285 C 290 285 282 302 295 315 Z" fill="#64748b"/>
<!-- 身体/腹部 -->
<path d="M 335 285 C 330 250 365 220 410 225 C 440 230 455 260 445 300 C 430 330 360 330 335 285 Z" fill="url(#bodyGrad)"/>
<!-- 飘舞的红色围巾 (后层) -->
<g class="scarf-tail">
<path d="M 395 228 C 365 225 330 215 305 225 C 320 235 345 240 385 238 Z" fill="#e63946"/>
<path d="M 390 232 C 355 235 320 235 295 250 C 315 255 350 250 385 240 Z" fill="#d90429"/>
</g>
<!-- 颈部与头部组 -->
<g class="pelican-head-group">
<!-- 粗壮 S 形脖子 -->
<path d="M 405 235 C 400 200 425 180 435 160 C 445 145 465 145 470 160 C 475 180 440 205 435 235 Z" fill="url(#bodyGrad)"/>
<!-- 头部圆顶 -->
<circle cx="450" cy="165" r="24" fill="#ffffff"/>
<!-- 呆萌呆毛 -->
<path d="M 442 143 C 435 130 425 132 420 135 C 430 142 436 145 440 148 Z" fill="#cbd5e1"/>
<!-- 眼睛 -->
<ellipse class="eye-blink" cx="452" cy="162" rx="4.5" ry="5.5" fill="#1e293b"/>
<circle cx="454" cy="160" r="1.5" fill="#ffffff"/>
<!-- 巨大的标志性下喉囊 -->
<g class="pouch-jiggle">
<!-- 喉囊囊袋 -->
<path d="M 465 174 C 485 185 580 180 610 178 C 595 235 520 265 462 215 C 455 198 458 185 465 174 Z" fill="url(#pouchGrad)"/>
<!-- 喉囊上的纹理线条 -->
<path d="M 480 195 Q 520 240 560 195" fill="none" stroke="#d96a1a" stroke-width="2" opacity="0.4"/>
<path d="M 500 190 Q 535 235 580 185" fill="none" stroke="#d96a1a" stroke-width="2" opacity="0.4"/>
</g>
<!-- 坚硬上喙与尖端小倒钩 -->
<path d="M 458 162 C 485 162 570 168 625 173 C 628 178 620 183 615 182 C 570 178 485 172 460 172 Z" fill="#f59e0b"/>
<path d="M 622 171 Q 632 175 624 182" fill="none" stroke="#d97706" stroke-width="3" stroke-linecap="round"/>
<!-- 鼻孔 -->
<ellipse cx="478" cy="167" rx="2.5" ry="1" fill="#b45309"/>
<!-- 骑手飞行风镜 -->
<path d="M 438 152 Q 452 148 468 154" fill="none" stroke="#78350f" stroke-width="3.5"/>
<rect x="444" y="152" width="13" height="11" rx="4" fill="#38bdf8" stroke="#78350f" stroke-width="2" opacity="0.85"/>
<line x1="446" y1="155" x2="452" y2="160" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round"/>
</g>
<!-- 围巾结 (前层) -->
<circle cx="418" cy="225" r="10" fill="#d90429"/>
<!-- 翅膀 / 手臂(正紧握着把手) -->
<!-- 上臂 -->
<path d="M 390 235 C 375 255 385 285 410 290 C 435 295 440 280 450 260 C 430 250 405 240 390 235 Z" fill="#e2e8f0"/>
<!-- 前臂延伸握把 -->
<path d="M 432 260 Q 490 250 545 235 Q 550 242 538 250 Q 485 268 428 275 Z" fill="#f8fafc"/>
<!-- 翅膀羽毛末梢(手掌指头) -->
<path d="M 540 232 C 555 228 560 240 546 244 Z" fill="#cbd5e1"/>
<!-- 近景腿部与脚蹼 (踩在前踏板上) -->
<g class="front-leg">
<!-- 大腿骨 -->
<path d="M 390 295 L 415 350" stroke="#f59e0b" stroke-width="9" stroke-linecap="round"/>
<!-- 小腿骨连到踏板 -->
<path d="M 415 350 L 460 425" stroke="#f59e0b" stroke-width="7" stroke-linecap="round"/>
<!-- 橙黄色大脚蹼 -->
<path d="M 445 425 L 485 435 L 480 442 L 440 432 Z" fill="#ea580c"/>
</g>
</g> <!-- end #pelican -->
<!-- ================= 自行车前层(近端脚蹬曲柄组) ================= -->
<g id="crank-group">
<!-- 齿轮盘中轴盖 -->
<circle cx="430" cy="410" r="8" fill="#1e293b"/>
<!-- 前曲柄臂 (与后曲柄差180度) -->
<line x1="430" y1="410" x2="465" y2="435" stroke="#94a3b8" stroke-width="7" stroke-linecap="round"/>
<!-- 近端踏板保持水平 -->
<g class="pedal-counter" style="transform-origin: 465px 435px;">
<rect x="450" y="431" width="30" height="8" rx="3.5" fill="#0f172a"/>
</g>
</g>
</g> <!-- end .bike-pelican -->
<!-- 速度风线(增强动感) -->
<g stroke="#ffffff" stroke-width="2" stroke-linecap="round" opacity="0.6">
<line x1="220" y1="180" x2="160" y2="180" class="road-dashes" style="animation-duration: 0.3s;"/>
<line x1="180" y1="210" x2="100" y2="210" class="road-dashes" style="animation-duration: 0.25s;"/>
<line x1="200" y1="250" x2="130" y2="250" class="road-dashes" style="animation-duration: 0.35s;"/>
</g>
</svg>
</div>
</body>
</html>