dsh + deepseekv4pro high + frontenddesign 鹈鹕骑车效果
Marisa
2026-08-14 03:49
1
DSH:

1 轮 · 7 步| LLM 15m22s · 工具调用 0.2s| 首 token 平均 1s · 72 tok/s| 缓存命中 97%| 输入 446K tok · 输出 66.1K tok
效果:

代码:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pelican Pedaler — No. 7</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Karla:wght@400;600&family=Space+Mono:wght@400;700&family=Staatliches&display=swap" rel="stylesheet">
<style>
:root{
--ink:#18323c;
--sky:#bfe0e4;
--sky-hi:#eaf4f1;
--sea:#2e7185;
--sea-hi:#4e93a4;
--sand:#efe2c4;
--ivory:#f8f4e6;
--ivory-shade:#ebe2c8;
--coral:#e9763d;
--coral-deep:#d9612b;
--sun:#f2c14e;
}
*{ box-sizing:border-box; }
html,body{ margin:0; padding:0; }
body{
background:var(--ink);
color:var(--ink);
font-family:'Karla',system-ui,sans-serif;
-webkit-font-smoothing:antialiased;
text-rendering:optimizeLegibility;
}
.poster{ position:relative; min-height:100vh; min-height:100svh; overflow:hidden; background:var(--sky); }
/* ---- stage (the artwork) ---- */
.stage{ position:absolute; inset:0; overflow:hidden; }
#scene{ display:block; width:100%; height:100%; }
.grain{
position:absolute; inset:0; pointer-events:none; opacity:.05; mix-blend-mode:multiply;
background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
background-size:160px 160px;
}
.frame{
position:absolute; inset:14px; border:1.5px solid rgba(24,50,60,.55); pointer-events:none;
}
/* ---- overlay text ---- */
.topbar{
position:absolute; top:clamp(1.1rem,3vw,2.4rem); left:clamp(1.1rem,3vw,2.4rem); right:clamp(1.1rem,3vw,2.4rem);
display:flex; justify-content:space-between; gap:1rem; align-items:baseline; pointer-events:none;
}
.eyebrow{
font-family:'Space Mono',monospace; font-size:12px; font-weight:700; letter-spacing:.22em;
text-transform:uppercase; color:var(--ink); opacity:.85; margin:0;
}
.hint{
font-family:'Space Mono',monospace; font-size:12px; letter-spacing:.16em;
text-transform:uppercase; color:var(--ink); margin:0;
}
.content{
position:absolute; inset:0; display:flex; flex-direction:column; justify-content:space-between;
padding:clamp(1.1rem,3vw,2.4rem); padding-top:clamp(6rem,12vw,9rem); pointer-events:none;
}
.titleblock{ max-width:15ch; }
.title{
font-family:'Staatliches',Impact,'Arial Narrow',sans-serif; font-weight:400;
font-size:clamp(3.4rem,11vw,8rem); line-height:.84; letter-spacing:.01em;
text-transform:uppercase; color:var(--ink); margin:0;
}
.title .dot{ color:var(--coral); }
.sub{
font-size:clamp(1rem,1.5vw,1.2rem); line-height:1.55; max-width:38ch;
color:var(--ink); margin:1.1rem 0 0;
}
.specbar{
pointer-events:auto; display:flex; align-items:center; justify-content:space-between; gap:1rem; flex-wrap:wrap;
background:rgba(248,244,230,.92); border:1.5px solid var(--ink); padding:.7rem 1rem;
backdrop-filter:blur(2px);
}
.specs{
display:flex; gap:1.1rem; flex-wrap:wrap; margin:0;
font-family:'Space Mono',monospace; font-size:12px; letter-spacing:.14em; text-transform:uppercase; color:var(--ink);
}
.specs b{ font-weight:700; }
.specs span{ opacity:.6; }
.controls{ display:flex; align-items:center; gap:.6rem; flex-wrap:wrap; }
.distance{ font-family:'Space Mono',monospace; font-size:13px; font-weight:700; letter-spacing:.06em; color:var(--ink); white-space:nowrap; }
.distance small{ font-weight:400; opacity:.65; }
button.ctl{
font-family:'Space Mono',monospace; font-size:12px; font-weight:700; letter-spacing:.12em; text-transform:uppercase;
color:var(--ink); background:transparent; border:1.5px solid var(--ink); padding:.55rem .8rem; cursor:pointer;
transition:background .15s ease, color .15s ease, border-color .15s ease;
}
button.ctl:hover{ background:var(--coral); color:var(--ivory); border-color:var(--coral); }
button.ctl:focus-visible{ outline:3px solid var(--coral); outline-offset:2px; }
/* ---- SVG styling ---- */
.tire{ fill:none; stroke:var(--ink); stroke-width:12; }
.rim{ fill:none; stroke:var(--ink); stroke-width:3; opacity:.7; }
.hub{ fill:var(--ink); }
.frame-line{ stroke:var(--coral); stroke-width:10; stroke-linecap:round; }
.bar{ fill:none; stroke:var(--coral); stroke-width:9; stroke-linecap:round; stroke-linejoin:round; }
.chainring{ fill:none; stroke:var(--ink); stroke-width:6; }
.chainring-dot{ fill:var(--ink); }
.chain{ stroke:var(--ink); stroke-width:4; stroke-dasharray:5 5; opacity:.28; fill:none; }
.cog{ fill:none; stroke:var(--ink); stroke-width:4; }
.saddle{ fill:var(--ink); }
.crank{ stroke:var(--ink); stroke-width:6; stroke-linecap:round; }
.pedal{ fill:var(--ink); }
.p-body{ fill:var(--ivory); }
.p-shade{ fill:var(--ivory-shade); }
.p-bill{ fill:var(--coral); }
.p-pouch{ fill:var(--coral-deep); }
.p-eye{ fill:var(--ink); }
.p-fish{ fill:var(--sea-hi); }
.leg{ fill:none; stroke:var(--coral); stroke-width:9; stroke-linecap:round; stroke-linejoin:round; }
.leg.far{ stroke:var(--coral-deep); }
.foot{ fill:var(--coral); }
.foot.far{ fill:var(--coral-deep); }
.feather{ stroke:var(--ink); stroke-width:2; opacity:.3; fill:none; stroke-linecap:round; }
.callout .pill{ fill:rgba(248,244,230,.93); stroke:var(--ink); stroke-width:1.5; }
.callout .clabel{ font-family:'Space Mono',monospace; font-size:12px; font-weight:700; letter-spacing:1px; fill:var(--ink); text-transform:uppercase; }
.callout .csub{ font-family:'Space Mono',monospace; font-size:11px; letter-spacing:.4px; fill:var(--ink); opacity:.72; }
.callout .leader{ stroke:var(--ink); stroke-width:1.5; stroke-dasharray:4 4; fill:none; }
.callout .dot{ fill:var(--coral); stroke:var(--ink); stroke-width:1.5; }
.callout{ opacity:0; animation:rise .7s ease forwards; }
@keyframes rise{ from{ opacity:0; transform:translateY(10px); } to{ opacity:1; transform:translateY(0); } }
.bubble-text{ font-family:'Staatliches',Impact,sans-serif; font-size:28px; letter-spacing:.08em; fill:var(--ink); }
#bubble{ opacity:0; pointer-events:none; transform-box:fill-box; transform-origin:50% 100%; }
#upper-bill{ transform-box:fill-box; transform-origin:0% 50%; transition:transform .14s cubic-bezier(.34,1.56,.64,1); }
.poster.honking #upper-bill{ transform:rotate(-14deg); }
.poster.honking #bubble{ animation:honk-pop .52s ease; }
@keyframes honk-pop{ 0%{ opacity:0; transform:scale(.4);} 25%{ opacity:1; transform:scale(1.12);} 60%{ opacity:1; transform:scale(1);} 100%{ opacity:0; transform:scale(1);} }
/* ambient motion */
.cloud{ animation:drift 26s ease-in-out infinite; }
.cloud.c2{ animation-duration:34s; animation-delay:-8s; }
.cloud.c3{ animation-duration:42s; animation-delay:-16s; }
@keyframes drift{ 0%,100%{ transform:translateX(0);} 50%{ transform:translateX(-70px);} }
.sun-rays{ transform-box:view-box; transform-origin:1050px 140px; animation:spin 70s linear infinite; }
@keyframes spin{ to{ transform:rotate(360deg);} }
.foam{ stroke:var(--ivory); stroke-width:5; stroke-linecap:round; stroke-dasharray:22 26; opacity:.92; animation:m1 1.4s linear infinite; }
.glint{ stroke:var(--sky-hi); stroke-width:4; stroke-linecap:round; stroke-dasharray:40 60; opacity:.6; animation:m2 3.4s linear infinite; }
.sandline{ stroke:#d9c79a; stroke-width:9; stroke-linecap:round; stroke-dasharray:70 90; opacity:.55; animation:m3 2.6s linear infinite; }
@keyframes m1{ to{ stroke-dashoffset:-48; } }
@keyframes m2{ to{ stroke-dashoffset:-100; } }
@keyframes m3{ to{ stroke-dashoffset:-160; } }
.speedlines{ animation:pulse 1.2s ease-in-out infinite; }
@keyframes pulse{ 0%,100%{ opacity:.12; } 50%{ opacity:.28; } }
/* ---- responsive ---- */
@media (max-width: 860px){
.poster{ min-height:0; display:flex; flex-direction:column; }
.stage{ position:relative; inset:auto; height:58svh; min-height:320px; flex:none; }
.frame{ display:none; }
.callout{ display:none; }
.topbar{ position:static; padding:1.1rem 1.1rem 0; order:-1; }
.content{ position:static; padding:1.4rem 1.1rem 2rem; gap:1.5rem; justify-content:flex-start; }
.titleblock{ max-width:none; }
.sub{ max-width:46ch; }
}
@media (prefers-reduced-motion: reduce){
.cloud,.sun-rays,.foam,.glint,.sandline,.speedlines,.callout{ animation:none !important; }
.callout{ opacity:1; }
#upper-bill{ transition-duration:.01s; }
.poster.honking #bubble{ animation-duration:.01s; }
}
</style>
</head>
<body>
<div class="poster" id="poster">
<div class="stage">
<svg id="scene" viewBox="0 0 1200 700" preserveAspectRatio="xMidYMid slice"
role="img" aria-label="Animated illustration of a pelican riding a bicycle along the shore">
<defs>
<linearGradient id="skyGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#eaf4f1"/>
<stop offset="0.7" stop-color="#cbe5e7"/>
<stop offset="1" stop-color="#a7d3db"/>
</linearGradient>
<linearGradient id="seaGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#3b8294"/>
<stop offset="1" stop-color="#236070"/>
</linearGradient>
<linearGradient id="sandGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#f7eed8"/>
<stop offset="1" stop-color="#efe2c4"/>
</linearGradient>
<g id="wheelDef">
<circle r="62" class="tire"/>
<circle r="51" class="rim"/>
<g stroke="#18323c" stroke-width="2.4" opacity="0.55">
<line x1="0" y1="0" x2="50" y2="0"/>
<line x1="0" y1="0" x2="35.4" y2="35.4"/>
<line x1="0" y1="0" x2="0" y2="50"/>
<line x1="0" y1="0" x2="-35.4" y2="35.4"/>
<line x1="0" y1="0" x2="-50" y2="0"/>
<line x1="0" y1="0" x2="-35.4" y2="-35.4"/>
<line x1="0" y1="0" x2="0" y2="-50"/>
<line x1="0" y1="0" x2="35.4" y2="-35.4"/>
</g>
<circle r="9" class="hub"/>
</g>
<g id="cloud">
<ellipse cx="0" cy="0" rx="46" ry="20" fill="#f8f4e6"/>
<circle cx="-26" cy="6" r="18" fill="#f8f4e6"/>
<circle cx="26" cy="6" r="18" fill="#f8f4e6"/>
</g>
</defs>
<!-- sky -->
<rect x="0" y="0" width="1200" height="700" fill="url(#skyGrad)"/>
<!-- sun -->
<g>
<circle cx="1050" cy="140" r="62" fill="#f2c14e"/>
<g class="sun-rays" stroke="#f2c14e" stroke-width="5" stroke-linecap="round">
<line x1="1120" y1="140" x2="1142" y2="140"/>
<line x1="1099.5" y1="90.5" x2="1115" y2="75"/>
<line x1="1050" y1="70" x2="1050" y2="48"/>
<line x1="1000.5" y1="90.5" x2="985" y2="75"/>
<line x1="980" y1="140" x2="958" y2="140"/>
<line x1="1000.5" y1="189.5" x2="985" y2="205"/>
<line x1="1050" y1="210" x2="1050" y2="232"/>
<line x1="1099.5" y1="189.5" x2="1115" y2="205"/>
</g>
</g>
<!-- clouds -->
<g class="cloud"><use href="#cloud" transform="translate(300 110) scale(0.8)"/></g>
<g class="cloud c2"><use href="#cloud" transform="translate(880 80) scale(1.05)"/></g>
<g class="cloud c3"><use href="#cloud" transform="translate(540 180) scale(0.6)"/></g>
<!-- sea + sand -->
<path d="M0 450 C 110 442 220 458 340 450 C 460 442 560 458 680 450 C 800 442 920 458 1040 450 C 1100 446 1150 452 1200 450 L 1200 560 L 0 560 Z" fill="url(#seaGrad)"/>
<rect x="0" y="560" width="1200" height="140" fill="url(#sandGrad)"/>
<!-- waterline foam, glints, ground motion, decorations, shadow -->
<line x1="-40" y1="560" x2="1240" y2="560" class="foam"/>
<line x1="60" y1="492" x2="140" y2="492" class="glint"/>
<line x1="360" y1="514" x2="460" y2="514" class="glint"/>
<line x1="820" y1="486" x2="900" y2="486" class="glint"/>
<line x1="-40" y1="620" x2="1240" y2="620" class="sandline"/>
<polygon points="140,626 143.5,635 153,636 146,642 148,651 140,646 132,651 134,642 127,636 136.5,635" fill="#e9763d" opacity="0.45"/>
<path d="M1112 646 C 1108 636 1114 630 1124 630 C 1134 630 1140 636 1136 646 C 1130 642 1118 642 1112 646 Z" fill="#236070" opacity="0.45"/>
<ellipse cx="640" cy="566" rx="190" ry="12" fill="#18323c" opacity="0.08"/>
<!-- speed lines behind the rider -->
<g class="speedlines" stroke="#18323c" stroke-linecap="round">
<line x1="270" y1="352" x2="382" y2="352" stroke-width="6"/>
<line x1="290" y1="382" x2="408" y2="382" stroke-width="5"/>
<line x1="262" y1="412" x2="368" y2="412" stroke-width="4"/>
</g>
<!-- far leg (behind frame) -->
<path id="leg-far" class="leg far" d="M 516 323 L 515.6 442.9 L 614 515"/>
<!-- far crank + pedal + foot (behind frame) -->
<g id="crank-far" transform="translate(640 515) rotate(180)">
<line x1="0" y1="0" x2="26" y2="0" class="crank"/>
</g>
<g id="pedal-far" transform="translate(614 515)">
<rect x="-13" y="-3" width="26" height="7" rx="3" class="pedal"/>
<path class="foot far" d="M 0 0 C 6 -3 16 -3 24 1 C 28 4 27 8 22 10 C 17 8 15 7 13 9 C 11 13 7 15 3 13 C 1 10 3 8 2 6 C 1 3 0 2 0 0 Z"/>
</g>
<!-- wheels -->
<g transform="translate(470 500)"><g id="spin-rear"><use href="#wheelDef"/></g></g>
<g transform="translate(810 500)"><g id="spin-front"><use href="#wheelDef"/></g></g>
<!-- frame -->
<g>
<line x1="640" y1="515" x2="545" y2="350" class="frame-line"/>
<line x1="640" y1="515" x2="795" y2="372" class="frame-line"/>
<line x1="545" y1="350" x2="820" y2="330" class="frame-line"/>
<line x1="470" y1="500" x2="640" y2="515" class="frame-line"/>
<line x1="470" y1="500" x2="545" y2="350" class="frame-line"/>
<line x1="545" y1="350" x2="527" y2="322" class="frame-line"/>
<line x1="810" y1="500" x2="795" y2="372" class="frame-line"/>
<line x1="795" y1="372" x2="820" y2="330" class="frame-line"/>
<!-- handlebar -->
<line x1="820" y1="330" x2="850" y2="312" class="bar"/>
<path d="M 850 312 C 874 304 886 316 878 336 C 872 348 858 350 850 342" class="bar"/>
<!-- chainring + chain -->
<circle cx="640" cy="515" r="30" class="chainring"/>
<circle cx="640" cy="515" r="9" class="chainring-dot"/>
<g class="chainring-dot">
<circle cx="640" cy="496" r="3.4"/>
<circle cx="640" cy="534" r="3.4"/>
<circle cx="621" cy="515" r="3.4"/>
<circle cx="659" cy="515" r="3.4"/>
<circle cx="626.6" cy="501.6" r="3.4"/>
<circle cx="653.4" cy="528.4" r="3.4"/>
<circle cx="626.6" cy="528.4" r="3.4"/>
<circle cx="653.4" cy="501.6" r="3.4"/>
</g>
<line x1="640" y1="485" x2="470" y2="488" class="chain"/>
<line x1="640" y1="545" x2="470" y2="512" class="chain"/>
<circle cx="470" cy="500" r="12" class="cog"/>
<!-- saddle -->
<path class="saddle" d="M 497 322 C 499 308 521 300 541 302 C 559 304 563 314 555 322 C 539 330 507 328 497 322 Z"/>
</g>
<!-- near leg (over frame) -->
<path id="leg-near" class="leg" d="M 525 330 L 568.3 441.9 L 666 515"/>
<!-- pelican body (bobs) -->
<g id="pelican-body" transform="translate(0 0)">
<!-- tail -->
<path class="p-shade" d="M 500 316 C 486 300 472 302 458 292 C 472 302 468 308 476 312 C 460 310 464 320 478 324 C 490 330 496 326 500 316 Z"/>
<!-- body -->
<path class="p-body" d="M 498 340 C 490 306 512 294 548 294 C 584 294 606 310 610 340 C 614 366 578 380 548 380 C 518 380 502 366 498 340 Z"/>
<!-- wing -->
<path class="p-shade" d="M 520 314 C 528 330 552 340 578 342 C 596 344 604 336 604 328 C 582 336 548 332 526 322 C 520 318 518 316 520 314 Z"/>
<path class="feather" d="M 528 322 C 546 332 566 337 588 335"/>
<path class="feather" d="M 524 316 C 544 322 562 324 582 322"/>
<!-- neck + head -->
<path class="p-body" d="M 596 306 C 606 272 622 244 646 226 L 672 236 C 656 250 644 278 626 306 Z"/>
<circle cx="655" cy="208" r="21" class="p-body"/>
<circle cx="663" cy="200" r="4" class="p-eye"/>
<circle cx="664" cy="199" r="1.4" fill="#ffffff"/>
<!-- bill -->
<path id="upper-bill" class="p-bill" d="M 673 200 C 712 194 750 206 790 220 C 793 223 790 227 783 225 C 748 221 706 212 678 207 C 674 205 673 202 673 200 Z"/>
<path class="p-pouch" d="M 676 207 C 690 248 722 272 758 262 C 764 250 758 230 744 222 C 718 213 694 210 676 207 Z"/>
<!-- cargo fish -->
<g class="p-fish" transform="translate(726 240) rotate(-14)">
<ellipse cx="0" cy="0" rx="12" ry="6"/>
<path d="M 10 0 L 20 -6 L 18 6 Z"/>
<circle cx="-4" cy="-1.5" r="1.4" fill="#18323c"/>
</g>
</g>
<!-- near crank + pedal + foot -->
<g id="crank-near" transform="translate(640 515) rotate(0)">
<line x1="0" y1="0" x2="26" y2="0" class="crank"/>
</g>
<g id="pedal-near" transform="translate(666 515)">
<rect x="-13" y="-3" width="26" height="7" rx="3" class="pedal"/>
<path class="foot" d="M 0 0 C 6 -3 16 -3 24 1 C 28 4 27 8 22 10 C 17 8 15 7 13 9 C 11 13 7 15 3 13 C 1 10 3 8 2 6 C 1 3 0 2 0 0 Z"/>
</g>
<!-- spec callouts -->
<g class="callout" style="animation-delay:.2s">
<line class="leader" x1="736" y1="148" x2="782" y2="222"/>
<circle class="dot" cx="782" cy="222" r="4"/>
<g transform="translate(710 126)">
<rect class="pill" x="-105" y="-23" width="210" height="46" rx="13"/>
<text class="clabel" x="0" y="-5" text-anchor="middle">Aero Bill</text>
<text class="csub" x="0" y="11" text-anchor="middle">rated 40 km/h · bone dry</text>
</g>
</g>
<g class="callout" style="animation-delay:.4s">
<line class="leader" x1="706" y1="370" x2="670" y2="262"/>
<circle class="dot" cx="670" cy="262" r="4"/>
<g transform="translate(770 392)">
<rect class="pill" x="-105" y="-23" width="210" height="46" rx="13"/>
<text class="clabel" x="0" y="-5" text-anchor="middle">Cargo Pouch</text>
<text class="csub" x="0" y="11" text-anchor="middle">1 fish · live · secured</text>
</g>
</g>
<g class="callout" style="animation-delay:.6s">
<line class="leader" x1="566" y1="584" x2="640" y2="515"/>
<circle class="dot" cx="640" cy="515" r="4"/>
<g transform="translate(498 600)">
<rect class="pill" x="-105" y="-23" width="210" height="46" rx="13"/>
<text class="clabel" x="0" y="-5" text-anchor="middle">Single Speed</text>
<text class="csub" x="0" y="11" text-anchor="middle">no gears, ever</text>
</g>
</g>
<!-- honk bubble -->
<g id="bubble" transform="translate(645 96)">
<rect x="-52" y="-34" width="104" height="42" rx="13" fill="#f8f4e6" stroke="#18323c" stroke-width="2.5"/>
<path d="M -8 8 L 0 28 L 12 8 Z" fill="#f8f4e6" stroke="#18323c" stroke-width="2.5" stroke-linejoin="round"/>
<text x="0" y="-7" text-anchor="middle" class="bubble-text">HONK!</text>
</g>
</svg>
</div>
<header class="topbar">
<p class="eyebrow">Société Vélocipédique du Littoral · Poster No. 7</p>
<p class="hint">Click the pelican ⟶</p>
</header>
<main class="content">
<div class="titleblock">
<h1 class="title">Pelican<br>Pedaler<span class="dot">.</span></h1>
<p class="sub">A single-speed study in applied optimism. Fourteen kilos of bicycle, three of bird, and one very committed beak — riding the waterline since 1904.</p>
</div>
<footer class="specbar">
<p class="specs">
<b>1</b><span>gear</span>
<b>40</b><span>cm rims</span>
<b>1</b><span>fish · live</span>
<b>2.4</b><span>m wingspan</span>
<b>est.</b><span>1904</span>
</p>
<div class="controls">
<span class="distance"><span id="distance-num">0.00</span> <small>km</small></span>
<button class="ctl" id="toggle" aria-pressed="false">Hold on</button>
<button class="ctl" id="speed" aria-pressed="false">Pace · Cruise</button>
</div>
</footer>
</main>
<div class="grain"></div>
<div class="frame"></div>
</div>
<script>
(function () {
var reduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var poster = document.getElementById('poster');
var body = document.getElementById('pelican-body');
var legN = document.getElementById('leg-near');
var legF = document.getElementById('leg-far');
var crankN = document.getElementById('crank-near');
var crankF = document.getElementById('crank-far');
var pedalN = document.getElementById('pedal-near');
var pedalF = document.getElementById('pedal-far');
var spinR = document.getElementById('spin-rear');
var spinF = document.getElementById('spin-front');
var distEl = document.getElementById('distance-num');
var toggleBtn = document.getElementById('toggle');
var speedBtn = document.getElementById('speed');
var BB = { x: 640, y: 515 };
var R = 26;
var HIPN = { x: 525, y: 330 };
var HIPF = { x: 516, y: 323 };
var L1 = 120, L2 = 122;
var WHEEL_RATIO = 1.6;
var MPR = 3.4; // metres per crank revolution (cartoon physics)
var running = true;
var sprint = false;
var rps = 1.25, target = 1.25;
var angle = 0, wheelAngle = 0, distance = 0;
function knee(H, P) {
var dx = P.x - H.x, dy = P.y - H.y;
var d = Math.hypot(dx, dy);
d = Math.min(Math.max(d, Math.abs(L1 - L2) + 0.01), L1 + L2 - 0.01);
var a = (L1 * L1 - L2 * L2 + d * d) / (2 * d);
var h = Math.sqrt(Math.max(0, L1 * L1 - a * a));
var ux = dx / d, uy = dy / d;
var mx = H.x + ux * a, my = H.y + uy * a;
var px = -uy * h, py = ux * h;
var k1 = { x: mx + px, y: my + py };
var k2 = { x: mx - px, y: my - py };
return (k1.x <= k2.x) ? k1 : k2; // bird knee bends backward
}
function legD(H, P) {
var K = knee(H, P);
return 'M ' + H.x + ' ' + H.y +
' L ' + K.x.toFixed(1) + ' ' + K.y.toFixed(1) +
' L ' + P.x.toFixed(1) + ' ' + P.y.toFixed(1);
}
function deg(a) { return (a * 180 / Math.PI) % 360; }
function update(theta, bx, by) {
var Pn = { x: BB.x + R * Math.cos(theta), y: BB.y + R * Math.sin(theta) };
var Pf = { x: BB.x - R * Math.cos(theta), y: BB.y - R * Math.sin(theta) };
var Hn = { x: HIPN.x + bx, y: HIPN.y + by };
var Hf = { x: HIPF.x + bx * 0.85, y: HIPF.y + by };
legN.setAttribute('d', legD(Hn, Pn));
legF.setAttribute('d', legD(Hf, Pf));
crankN.setAttribute('transform', 'translate(' + BB.x + ' ' + BB.y + ') rotate(' + deg(theta) + ')');
crankF.setAttribute('transform', 'translate(' + BB.x + ' ' + BB.y + ') rotate(' + deg(theta + Math.PI) + ')');
pedalN.setAttribute('transform', 'translate(' + Pn.x.toFixed(2) + ' ' + Pn.y.toFixed(2) + ')');
pedalF.setAttribute('transform', 'translate(' + Pf.x.toFixed(2) + ' ' + Pf.y.toFixed(2) + ')');
var w = deg(wheelAngle);
spinR.setAttribute('transform', 'rotate(' + w + ')');
spinF.setAttribute('transform', 'rotate(' + w + ')');
body.setAttribute('transform', 'translate(' + bx.toFixed(2) + ' ' + by.toFixed(2) + ')');
}
var last = performance.now();
function frame(now) {
var dt = Math.min((now - last) / 1000, 0.05);
last = now;
rps += (target - rps) * Math.min(1, dt * 5);
if (running) {
var dTheta = rps * Math.PI * 2 * dt;
angle += dTheta;
wheelAngle += dTheta * WHEEL_RATIO;
distance += rps * MPR * dt / 1000;
distEl.textContent = distance.toFixed(2);
}
var by = Math.sin(angle * 2) * 2.4;
var bx = Math.cos(angle * 2) * 0.7;
update(angle, bx, by);
requestAnimationFrame(frame);
}
toggleBtn.addEventListener('click', function () {
running = !running;
toggleBtn.textContent = running ? 'Hold on' : 'Ride on';
toggleBtn.setAttribute('aria-pressed', String(!running));
});
speedBtn.addEventListener('click', function () {
sprint = !sprint;
target = sprint ? 2.3 : 1.25;
speedBtn.textContent = sprint ? 'Pace · Sprint' : 'Pace · Cruise';
speedBtn.setAttribute('aria-pressed', String(sprint));
});
var honkT;
body.style.cursor = 'pointer';
body.addEventListener('click', function () {
if (honkT) clearTimeout(honkT);
poster.classList.remove('honking');
void poster.offsetWidth; // restart animation
poster.classList.add('honking');
honkT = setTimeout(function () { poster.classList.remove('honking'); }, 540);
});
if (reduced) {
update(0, 0, 0);
} else {
requestAnimationFrame(frame);
}
})();
</script>
</body>
</html>
最新回复 (2)
-
sandiferresner 08-14 04:141楼为什么不开 max 测, 估计效果会更好.
-
Marisa 楼主 08-14 04:232楼
Max生成的 根本动不了
* 帖子来源Linux.do
附近帖子
- ↑除了醍醐骑自行车外,终于又亲身看到了Grok的另一种口水
- ↑我发现workbuddy还挺好用的。
- ↑关于grok注册机的代理问题
- ↑codex goal模式下出现双倍消耗bug
- ↑越狱机怎么升级系统
- 📍 dsh + deepseekv4pro high + frontenddesign 鹈鹕骑车效果
- ↓求助!拼豆图稿转换问题
- ↓DeepSeek Harness & Cordis: 活着的Nix与AgentOS雏形
- ↓chatgpt手机验证码怎么解决
- ↓deepseek harness轻度体验中,佬友们感觉如何
- ↓Tibo说的1500万用户 真的全是真人吗
飞读
Marisa
|
主题数 1 |
帖子数 1 |
注册排名 3 |