代码
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Pelican Loading Animation</title>
<style>
:root {
color-scheme: light;
--ink: #172033;
--muted: #68748a;
--paper: #f8fbff;
--sky: #dff3ff;
--water: #9ddcf0;
--accent: #ff765f;
--yellow: #ffd35a;
}
* {
box-sizing: border-box;
}
html,
body {
min-height: 100%;
margin: 0;
}
body {
display: grid;
min-height: 100vh;
place-items: center;
overflow: hidden;
background:
radial-gradient(circle at 18% 12%, rgba(255, 255, 255, 0.9), transparent 25%),
linear-gradient(155deg, var(--paper) 0%, #edf8ff 48%, #d4eff8 100%);
color: var(--ink);
font-family:
Inter,
'Noto Sans SC',
system-ui,
-apple-system,
sans-serif;
}
.loader {
width: min(92vw, 720px);
text-align: center;
}
.scene {
position: relative;
width: 100%;
aspect-ratio: 1.55;
overflow: hidden;
border: 1px solid rgba(75, 144, 176, 0.18);
border-radius: 28px;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0) 38%), var(--sky);
box-shadow: 0 22px 60px rgba(73, 127, 153, 0.18);
}
.scene::before,
.scene::after {
position: absolute;
content: '';
border-radius: 999px;
background: rgba(255, 255, 255, 0.62);
filter: blur(1px);
}
.scene::before {
width: 25%;
height: 7%;
top: 20%;
left: 9%;
box-shadow:
54px 9px 0 rgba(255, 255, 255, 0.42),
105px -6px 0 rgba(255, 255, 255, 0.35);
}
.scene::after {
width: 20%;
height: 6%;
top: 34%;
right: 8%;
box-shadow:
-44px 8px 0 rgba(255, 255, 255, 0.42),
-87px -4px 0 rgba(255, 255, 255, 0.32);
}
svg {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
}
.pelican {
transform-box: fill-box;
transform-origin: center bottom;
animation: ride-bob 0.62s ease-in-out infinite alternate;
}
.wheel {
transform-box: fill-box;
transform-origin: center;
animation: wheel-spin 0.72s linear infinite;
}
.pedal-arm {
transform-box: fill-box;
transform-origin: 50% 0;
animation: pedal 0.72s linear infinite;
}
.wing {
transform-box: fill-box;
transform-origin: 82% 80%;
animation: wing-flap 0.9s ease-in-out infinite alternate;
}
.head {
transform-box: fill-box;
transform-origin: 62% 76%;
animation: head-bob 0.62s ease-in-out infinite alternate;
}
.water-line {
stroke-dasharray: 34 24;
animation: water-drift 2.6s linear infinite;
}
.loading-copy {
margin-top: 22px;
}
.loading-copy h1 {
margin: 0;
font-size: clamp(1.35rem, 3vw, 1.85rem);
letter-spacing: 0;
}
.loading-copy p {
margin: 8px 0 0;
color: var(--muted);
font-size: clamp(0.82rem, 2vw, 0.98rem);
}
.dots::after {
content: '';
display: inline-block;
width: 1.6em;
text-align: left;
animation: dots 1.2s steps(4, end) infinite;
}
@keyframes ride-bob {
from {
transform: translateY(0);
}
to {
transform: translateY(-3px);
}
}
@keyframes head-bob {
from {
transform: rotate(-1deg);
}
to {
transform: rotate(2deg);
}
}
@keyframes wing-flap {
from {
transform: rotate(-2deg);
}
to {
transform: rotate(8deg);
}
}
@keyframes wheel-spin {
to {
transform: rotate(360deg);
}
}
@keyframes pedal {
to {
transform: rotate(360deg);
}
}
@keyframes water-drift {
to {
stroke-dashoffset: -116;
}
}
@keyframes dots {
0% {
content: '';
}
25% {
content: '.';
}
50% {
content: '..';
}
75%,
100% {
content: '...';
}
}
@media (max-width: 520px) {
.scene {
border-radius: 20px;
}
.loading-copy {
margin-top: 16px;
}
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.001ms !important;
animation-iteration-count: 1 !important;
}
}
</style>
</head>
</html>
<body>
<main class="loader" aria-label="PBO Wiki 加载动画预览">
<section class="scene" aria-hidden="true">
<svg viewBox="0 0 800 516" role="img" aria-label="一只鹈鹕骑着自行车">
<defs>
<linearGradient id="ground" x1="0" x2="1" y1="0" y2="0">
<stop offset="0" stop-color="#78c8df" stop-opacity="0" />
<stop offset="0.5" stop-color="#78c8df" stop-opacity="0.8" />
<stop offset="1" stop-color="#78c8df" stop-opacity="0" />
</linearGradient>
<filter id="soft-shadow" x="-30%" y="-30%" width="160%" height="160%">
<feGaussianBlur stdDeviation="5" />
</filter>
</defs>
<ellipse cx="400" cy="405" rx="254" ry="22" fill="#5aa9c1" opacity="0.22" filter="url(#soft-shadow)" />
<path class="water-line" d="M54 417 C180 395 260 438 386 416 S610 395 748 421" fill="none" stroke="url(#ground)" stroke-width="7" stroke-linecap="round" />
<path class="water-line" d="M130 449 C236 432 308 458 405 445 S594 429 688 450" fill="none" stroke="#fff" stroke-opacity="0.5" stroke-width="4" stroke-linecap="round" />
<g class="pelican">
<g class="wheel" fill="none" stroke="#26364b" stroke-width="9">
<circle cx="264" cy="373" r="63" />
<circle cx="557" cy="373" r="63" />
<path d="M264 373 L360 265 L557 373 L438 373 L360 265 M438 373 L403 244" stroke="#40536b" stroke-width="8" stroke-linejoin="round" />
</g>
<g fill="none" stroke="#aebdca" stroke-width="3" opacity="0.78">
<circle cx="264" cy="373" r="49" />
<circle cx="557" cy="373" r="49" />
<path d="M264 373h49 M264 373l-22-43 M264 373l-21 42 M264 373l29 39 M557 373h49 M557 373l-22-43 M557 373l-21 42 M557 373l29 39" />
</g>
<g class="pedal-arm" fill="none" stroke="#f08a4b" stroke-width="7" stroke-linecap="round">
<path d="M438 373 L466 344" />
<path d="M466 344 h25" />
<path d="M438 373 L410 402" />
<path d="M410 402 h-25" />
<circle cx="438" cy="373" r="12" fill="#ffd35a" stroke="#f08a4b" />
</g>
<path d="M351 268 C365 219 416 211 454 233 C482 250 490 291 466 319 C438 350 374 340 349 306 C341 294 342 279 351 268Z" fill="#f2f5f4" stroke="#26364b" stroke-width="7" />
<path d="M362 301 C389 322 435 322 461 296 C451 338 405 355 371 328Z" fill="#d7e3e6" opacity="0.9" />
<g class="wing">
<path d="M373 273 C391 242 446 245 469 277 C477 288 467 306 449 310 C416 318 385 306 373 273Z" fill="#c8d8dc" stroke="#26364b" stroke-width="7" />
<path d="M390 278 C412 274 435 281 454 293" fill="none" stroke="#8ba9b4" stroke-width="5" stroke-linecap="round" />
</g>
<path d="M383 320 C389 343 402 349 414 350 L422 373 H396 L378 345Z" fill="#ff765f" stroke="#26364b" stroke-width="7" stroke-linejoin="round" />
<path d="M449 318 C456 340 472 347 484 349 L492 373 H467 L445 344Z" fill="#ff765f" stroke="#26364b" stroke-width="7" stroke-linejoin="round" />
<path d="M392 371 h-27 M475 371 h-28" stroke="#26364b" stroke-width="8" stroke-linecap="round" />
<g class="head">
<path d="M367 245 C345 229 342 185 366 158 C394 127 446 136 463 168 C481 203 457 247 419 258 C399 264 381 257 367 245Z" fill="#f2f5f4" stroke="#26364b" stroke-width="7" />
<path d="M356 197 C322 180 285 189 255 208 C247 213 250 224 260 228 C305 245 350 236 377 218Z" fill="#ffd35a" stroke="#26364b" stroke-width="7" stroke-linejoin="round" />
<path d="M257 208 C280 211 309 218 338 217" fill="none" stroke="#ed9e3c" stroke-width="5" stroke-linecap="round" />
<path d="M366 159 C350 137 360 119 381 112 C406 104 432 117 440 140" fill="#ff765f" stroke="#26364b" stroke-width="7" stroke-linecap="round" />
<circle cx="414" cy="183" r="8" fill="#26364b" />
<circle cx="417" cy="180" r="2.5" fill="#fff" />
<path d="M427 208 C437 214 446 214 454 209" fill="none" stroke="#26364b" stroke-width="4" stroke-linecap="round" />
</g>
<path d="M402 245 C415 237 432 236 448 243" fill="none" stroke="#fff" stroke-width="7" stroke-linecap="round" opacity="0.75" />
</g>
</svg>
</section>
<div class="loading-copy">
<h1>Wiki 正在准备中<span class="dots" aria-hidden="true"></span></h1>
<p>鹈鹕车手正在把最新内容送到你面前</p>
</div>
</main>
</body>
</html>