Add colored egg/fry, cookie/dunk, rainbow/arc, planet/orbit, volcano/erupt, wave/crash, cactus/sway, mushroom/bounce, star/shoot, tree/sway

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-22 20:52:53 +00:00
co-authored by Claude Opus 5.5
parent 505b07e549
commit d067f0b6bb
30 changed files with 219 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
// potted cactus swaying to music, arms waving, pink flower bobbing on its head
const{sin,cos,PI}=Math,T=2*PI
export const frames=20,delay=80
const G='#51cf66',GD='#2f9e44',POT='#ff922b',PD='#e8590c',FL='#f783ac',FC='#ffd43b',BL='#ffa8a8'
export default(c,t)=>{
const r=.09*sin(t*T),aL=.18*sin(t*T*2),aR=.18*sin(t*T*2+PI)
c.save();c.translate(128,182);c.rotate(r);c.translate(-128,-182)
const body=()=>c.roundRect(98,48,60,150,30)
const arm=(d,a)=>{c.save();c.translate(128+d*28,132);c.rotate(d*a);c.beginPath();c.moveTo(0,0);c.lineTo(d*30,0);c.lineTo(d*30,-40);c.restore()}
c.lineWidth=40;for(const[d,a]of[[-1,aL],[1,aR]])arm(d,a),c.stroke()
c.lineWidth=7;c.beginPath();body();c.stroke();c.lineWidth=14;c.beginPath();body();c.stroke()
c.strokeStyle=G;c.lineWidth=26;for(const[d,a]of[[-1,aL],[1,aR]])arm(d,a),c.stroke()
c.fillStyle=G;c.beginPath();body();c.fill()
c.strokeStyle=GD;c.lineWidth=4;for(const x of[114,142])c.beginPath(),c.moveTo(x,66),c.lineTo(x,190),c.stroke()
c.strokeStyle='#111';c.lineWidth=3;for(const[x,y]of[[106,80],[150,96],[106,170],[150,180],[128,62]])c.beginPath(),c.moveTo(x-4,y),c.lineTo(x+4,y-4),c.moveTo(x-4,y-4),c.lineTo(x+4,y),c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+d*13,106,5,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(128+d*13-2,104,1.8,0,T),c.fill()
c.lineWidth=5;c.beginPath();c.arc(128,114,8,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*22,118,6,3.5,0,0,T),c.fill()
c.lineWidth=5;const fy=46+3*sin(t*T*2)
c.fillStyle=FL;for(let k=0;k<5;k++){const a=k*T/5-PI/2;c.beginPath();c.ellipse(128+cos(a)*11,fy+sin(a)*11,9,6,a,0,T);c.fill();c.stroke()}
c.fillStyle=FC;c.beginPath();c.arc(128,fy,6,0,T);c.fill();c.stroke()
c.restore();c.lineWidth=7
c.fillStyle=POT;c.beginPath();c.moveTo(80,196);c.lineTo(176,196);c.lineTo(164,244);c.lineTo(92,244);c.closePath();c.fill();c.stroke()
c.fillStyle=PD;c.beginPath();c.roundRect(72,184,112,20,6);c.fill();c.stroke()
}
+20
View File
@@ -0,0 +1,20 @@
// chocolate chip cookie dunking itself in a glass of milk, splashing drops each time
const{sin,cos,PI,max}=Math,T=2*PI
export const frames=20,delay=70
const GL='#e7f5ff',CK='#e0a96d',CH='#5c3d2e',BL='#ffa8a8'
const glass=c=>{c.beginPath();c.moveTo(62,112);c.lineTo(194,112);c.lineTo(184,236);c.quadraticCurveTo(183,242,176,242);c.lineTo(80,242);c.quadraticCurveTo(73,242,72,236);c.closePath()}
export default(c,t)=>{
const d=(1-cos(t*T))/2,cy=58+70*d,hit=d>.82,ml=150+(hit?4*sin(t*T*6):0)
glass(c);c.fillStyle=GL;c.fill()
c.save();c.translate(128,cy);c.rotate(.3*sin(t*T))
c.fillStyle=CK;c.beginPath();for(let a=0;a<=T+.01;a+=.2)c.lineTo(cos(a)*(44+2*sin(a*7)),sin(a)*(44+2*sin(a*7)));c.closePath();c.fill();c.stroke()
c.fillStyle=CH;for(const[x,y]of[[-22,-18],[18,-24],[26,10],[-28,14],[0,24],[-4,-30]])c.beginPath(),c.ellipse(x,y,6,5,x,0,T),c.fill()
c.fillStyle='#111';for(const k of[-1,1])c.beginPath(),c.arc(k*12,-4,4.5,0,T),c.fill()
c.lineWidth=4;c.beginPath();c.arc(0,4,7,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const k of[-1,1])c.beginPath(),c.ellipse(k*22,4,5,3,0,0,T),c.fill()
c.restore()
c.save();glass(c);c.clip();c.fillStyle='#fff';c.beginPath();c.moveTo(50,ml);for(let x=50;x<=206;x+=6)c.lineTo(x,ml+(hit?3*sin(x/10+t*T*4):0));c.lineTo(206,250);c.lineTo(50,250);c.fill();c.lineWidth=5;c.stroke();c.restore()
c.lineWidth=7;glass(c);c.stroke()
c.lineWidth=4;c.beginPath();c.moveTo(178,126);c.lineTo(172,220);c.stroke()
if(d>.6){const u=(d-.6)/.4;c.lineWidth=4;c.fillStyle='#fff';for(const[vx,vy]of[[-40,-60],[-20,-80],[24,-74],[44,-56]])c.beginPath(),c.arc(128+vx*u,ml-10+vy*u*(1.2-u),5,0,T),c.fill(),c.stroke()}
}
+26
View File
@@ -0,0 +1,26 @@
// egg sizzling in a pan: the white wobbles, bubbles pop around its edge, the yolk bobs, steam curls up
const{sin,cos,PI,max}=Math,T=2*PI
export const frames=20,delay=70
const PAN='#868e96',IN='#495057',YK='#ffd43b',BL='#ffa8a8'
export default(c,t)=>{
c.fillStyle=PAN;c.save();c.translate(196,196);c.rotate(PI/4);c.beginPath();c.roundRect(0,-13,74,26,13);c.restore();c.fill();c.stroke()
c.beginPath();c.arc(112,140,94,0,T);c.fill();c.stroke()
c.fillStyle=IN;c.beginPath();c.arc(112,140,80,0,T);c.fill();c.lineWidth=4;c.stroke();c.lineWidth=7
c.fillStyle='#fff';c.beginPath()
for(let a=0;a<=T+.01;a+=.08){const r=58+8*sin(3*a+1)+5*sin(5*a+2)+2.5*sin(4*a-2*T*t);c.lineTo(112+cos(a)*r,140+sin(a)*r)}
c.closePath();c.fill();c.stroke()
c.lineWidth=4
for(let k=0;k<6;k++){const a=k*T/6+.4,p=(t*2+k/6)%1,s=6*sin(PI*p);if(s>1)c.beginPath(),c.arc(112+cos(a)*72,140+sin(a)*72,s,0,T),c.fill(),c.stroke()}
const y=3*sin(2*T*t)
c.lineWidth=7;c.fillStyle=YK;c.beginPath();c.arc(104,132+y,26,0,T);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.ellipse(96,122+y,7,4,-.5,0,T);c.fill()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(104+d*9,134+y,3.5,0,T),c.fill()
c.lineWidth=4;c.beginPath();c.arc(104,139+y,5,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(104+d*16,140+y,4,2.5,0,0,T),c.fill()
for(const[x0,o]of[[160,0],[188,.5]])for(const[w,s]of[[11,'#111'],[4,'#fff']]){
c.lineWidth=w;c.strokeStyle=s;c.beginPath()
for(let yy=54;yy>=14;yy-=2)c.lineTo(x0+5*sin((54-yy)/20*T-t*T*2+o*6),yy)
c.stroke()
}
c.strokeStyle='#111'
}
+18
View File
@@ -0,0 +1,18 @@
// red spotted mushroom hopping in place with squash and stretch, grass tuft waving below
const{sin,cos,PI,abs}=Math,T=2*PI
export const frames=20,delay=60
const CAP='#fa5252',ST='#fff4e6',GR='#69db7c',BL='#ffa8a8'
export default(c,t)=>{
const h=abs(sin(PI*t)),y=-56*h,sq=h<.18?1-(.18-h)*1.1:1+.06*h
c.fillStyle=GR
for(const[x,a]of[[86,-.4],[100,-.15],[156,.15],[170,.4]]){c.save();c.translate(x,236);c.rotate(a+.1*sin(t*T*2+x));c.beginPath();c.moveTo(-6,0);c.quadraticCurveTo(-2,-20,0,-30);c.quadraticCurveTo(4,-16,6,0);c.closePath();c.restore();c.fill();c.stroke()}
c.fillStyle='rgba(0,0,0,0)'
c.translate(128,232);c.scale(2-sq,sq);c.translate(-128,-232+y/sq)
c.fillStyle=ST;c.beginPath();c.moveTo(100,232);c.quadraticCurveTo(96,170,108,140);c.lineTo(148,140);c.quadraticCurveTo(160,170,156,232);c.closePath();c.fill();c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+d*12,182,5,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(128+d*12-2,180,1.8,0,T),c.fill()
c.lineWidth=5;c.beginPath();c.arc(128,190,7,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*22,194,5,3,0,0,T),c.fill()
c.lineWidth=7;c.fillStyle=CAP;c.beginPath();c.moveTo(40,146);c.bezierCurveTo(40,46,216,46,216,146);c.quadraticCurveTo(216,156,204,156);c.lineTo(52,156);c.quadraticCurveTo(40,156,40,146);c.fill();c.stroke()
c.fillStyle='#fff';c.lineWidth=4;for(const[x,yy,r]of[[96,92,13],[148,80,10],[176,118,11],[70,130,8],[124,124,9]])c.beginPath(),c.arc(x,yy,r,0,T),c.fill(),c.stroke()
}
+25
View File
@@ -0,0 +1,25 @@
// ringed planet with a little moon orbiting behind and in front of it, stars twinkling around
const{sin,cos,PI,max}=Math,T=2*PI
export const frames=24,delay=70
const PL='#ffa94d',B1='#ff922b',B2='#ffd8a8',RG='#ffe066',MN='#ced4da',BL='#ff8787'
const tilt=-.28
export default(c,t)=>{
const th=t*T,mx=112*cos(th),my=40*sin(th),Mx=128+mx*cos(tilt)-my*sin(tilt),My=128+mx*sin(tilt)+my*cos(tilt)
const moon=()=>{c.fillStyle=MN;c.beginPath();c.arc(Mx,My,15,0,T);c.fill();c.stroke();c.lineWidth=3;c.beginPath();c.arc(Mx-4,My-4,4,0,T);c.arc(Mx+6,My+5,3,0,T);c.stroke();c.lineWidth=7}
for(const[x,y,o]of[[30,40,0],[226,46,.4],[220,214,.7],[40,206,.2]]){
const s=4+5*(1+sin((t+o)*T*2))/2;c.lineWidth=4;c.fillStyle='#fff';c.beginPath();c.moveTo(x,y-s);for(const[px,py,qx,qy]of[[s,0,s*.2,-s*.2],[0,s,s*.2,s*.2],[-s,0,-s*.2,s*.2],[0,-s,-s*.2,-s*.2]])c.quadraticCurveTo(x+qx,y+qy,x+px,y+py);c.fill();c.stroke()
}
c.lineWidth=7
if(sin(th)<0)moon()
const ring=(a,b)=>{c.save();c.translate(128,128);c.rotate(tilt);for(const[w,s]of[[24,'#111'],[12,RG]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.ellipse(0,0,98,24,0,a,b),c.stroke();c.restore();c.strokeStyle='#111';c.lineWidth=7}
ring(PI,T)
c.fillStyle=PL;c.beginPath();c.arc(128,128,56,0,T);c.fill()
c.save();c.clip();c.translate(128,128);c.rotate(tilt);c.fillStyle=B1;c.fillRect(-60,-34,120,12);c.fillRect(-60,26,120,10);c.fillStyle=B2;c.fillRect(-60,-14,120,8);c.restore()
c.beginPath();c.arc(128,128,56,0,T);c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+d*18,124,5.5,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(128+d*18-2,122,2,0,T),c.fill()
c.lineWidth=5;c.beginPath();c.arc(128,132,8,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*32,136,7,4,0,0,T),c.fill()
ring(0,PI)
if(sin(th)>=0)moon()
}
+22
View File
@@ -0,0 +1,22 @@
// rainbow paints itself across between two smiling clouds, shines for a bit, then wipes away
const{sin,cos,PI,min,max}=Math,T=2*PI
export const frames=24,delay=70
const C=['#ff6b6b','#ffa94d','#ffd43b','#69db7c','#4dabf7','#b197fc']
const cloud=(c,x,y)=>{
const P=[[x-22,y+4,18],[x,y-8,24],[x+22,y+4,18]],base=()=>c.roundRect(x-40,y,80,26,13)
c.lineWidth=14;for(const[a,b,r]of P)c.beginPath(),c.arc(a,b,r,0,T),c.stroke();c.beginPath();base();c.stroke()
c.fillStyle='#fff';for(const[a,b,r]of P)c.beginPath(),c.arc(a,b,r,0,T),c.fill();c.beginPath();base();c.fill()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(x+d*10,y+6,3,0,T),c.fill()
c.lineWidth=3;c.beginPath();c.arc(x,y+10,5,.15*PI,.85*PI);c.stroke();c.lineWidth=7
}
export default(c,t)=>{
const p=min(1,t/.38),q=max(0,(t-.8)/.2),a0=PI+PI*q,a1=PI+PI*p
if(a1>a0+.01){
c.lineCap='butt';c.lineWidth=74;c.beginPath();c.arc(128,186,72,a0,a1);c.stroke()
C.forEach((col,k)=>{c.strokeStyle=col;c.lineWidth=11;c.beginPath();c.arc(128,186,97-k*10,a0,a1);c.stroke()})
c.strokeStyle='#111'
}
c.lineCap='round'
if(t>.4&&t<.8)for(const[x,y,o]of[[128,70,0],[60,96,.33],[196,96,.66]]){const s=12*max(0,sin(PI*((t-.4)/.4*2+o)%1*1));if(s>1.5){c.lineWidth=4;c.fillStyle='#fff';c.beginPath();c.moveTo(x,y-s);for(const[px,py,qx,qy]of[[s,0,s*.18,-s*.18],[0,s,s*.18,s*.18],[-s,0,-s*.18,s*.18],[0,-s,-s*.18,-s*.18]])c.quadraticCurveTo(x+qx,y+qy,x+px,y+py);c.fill();c.stroke()}}
cloud(c,42,184+3*sin(t*T));cloud(c,214,184+3*sin(t*T+PI))
}
+18
View File
@@ -0,0 +1,18 @@
// smiling star shooting across with a rainbow streak behind it, little sparkles left in its wake
const{sin,cos,PI,max}=Math,T=2*PI
export const frames=24,delay=50
const SY='#ffd43b',TR=['#ff6b6b','#ffd43b','#4dabf7'],BL='#ff8787'
const pos=u=>[-40+u*336,52+u*150]
export default(c,t)=>{
const[x,y]=pos(t),dx=336,dy=150,L=Math.hypot(dx,dy),ux=dx/L,uy=dy/L,nx=-uy,ny=ux
for(let k=1;k<=4;k++){const u=t-k*.07;const[sx,sy]=pos(u),s=8*(1-k/5);if(s>1){c.lineWidth=3;c.fillStyle='#fff';c.beginPath();c.moveTo(sx+nx*16*(k%2?1:-1),sy+ny*16*(k%2?1:-1)-s);const ox=sx+nx*16*(k%2?1:-1),oy=sy+ny*16*(k%2?1:-1);for(const[px,py,qx,qy]of[[s,0,s*.2,-s*.2],[0,s,s*.2,s*.2],[-s,0,-s*.2,s*.2],[0,-s,-s*.2,-s*.2]])c.quadraticCurveTo(ox+qx,oy+qy,ox+px,oy+py);c.fill();c.stroke()}}
TR.forEach((col,k)=>{const o=(k-1)*13,len=110-abs(k-1)*20;for(const[w,s]of[[15,'#111'],[8,col]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(x+nx*o-ux*20,y+ny*o-uy*20),c.lineTo(x+nx*o-ux*len,y+ny*o-uy*len),c.stroke()})
c.strokeStyle='#111';c.lineWidth=7
c.save();c.translate(x,y);c.rotate(t*T)
c.fillStyle=SY;c.beginPath();for(let k=0;k<10;k++){const r=k%2?18:40,a=k*PI/5-PI/2;c.lineTo(cos(a)*r,sin(a)*r)}c.closePath();c.fill();c.stroke()
c.restore()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(x+d*9,y-2,4,0,T),c.fill()
c.lineWidth=4;c.beginPath();c.arc(x,y+4,6,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(x+d*16,y+6,4,2.5,0,0,T),c.fill()
}
const abs=Math.abs
+20
View File
@@ -0,0 +1,20 @@
// round apple tree leaning in the wind, leaves blowing off and tumbling away to the side
const{sin,cos,PI}=Math,T=2*PI
export const frames=24,delay=70
const LF='#51cf66',LD='#2f9e44',TR='#a9744f',AP='#fa5252',GR='#8ce99a'
const leaf=(c,x,y,a,s=1)=>{c.save();c.translate(x,y);c.rotate(a);c.scale(s,s);c.beginPath();c.moveTo(-12,0);c.quadraticCurveTo(0,-10,12,0);c.quadraticCurveTo(0,10,-12,0);c.restore();c.fill();c.stroke()}
export default(c,t)=>{
const w=.07*sin(t*T)+.03
c.fillStyle=GR;c.beginPath();c.ellipse(128,236,90,12,0,0,T);c.fill();c.stroke()
c.fillStyle=TR;c.beginPath();c.moveTo(112,236);c.quadraticCurveTo(118,180,114,140);c.lineTo(142,140);c.quadraticCurveTo(138,180,146,236);c.closePath();c.fill();c.stroke()
c.lineWidth=5;c.beginPath();c.moveTo(124,200);c.quadraticCurveTo(128,186,124,172);c.stroke();c.lineWidth=7
c.save();c.translate(128,150);c.rotate(w);c.translate(-128,-150)
const P=[[128,72,52],[84,102,40],[172,102,40],[104,132,38],[152,132,38],[128,112,46]]
c.lineWidth=14;for(const[x,y,r]of P)c.beginPath(),c.arc(x,y,r,0,T),c.stroke()
c.fillStyle=LF;for(const[x,y,r]of P)c.beginPath(),c.arc(x,y,r,0,T),c.fill()
c.lineWidth=5;c.strokeStyle=LD;for(const[x,y]of[[96,80],[150,66],[176,116],[110,140]])c.beginPath(),c.arc(x,y,12,PI*1.1,PI*1.6),c.stroke()
c.strokeStyle='#111';c.lineWidth=5
c.fillStyle=AP;for(const[x,y]of[[98,104],[150,94],[168,138],[118,62],[130,140]])c.beginPath(),c.arc(x,y,9,0,T),c.fill(),c.stroke()
c.restore();c.lineWidth=5;c.fillStyle=LF
for(const[y0,o,sp]of[[70,0,1],[110,.33,1],[150,.66,1]]){const p=(t*sp+o)%1;leaf(c,150+p*140,y0+30*sin(p*T*1.5)+p*30,p*T*2,.9)}
}
+22
View File
@@ -0,0 +1,22 @@
// volcano rumbles, then blasts lava blobs and smoke puffs out the top, then settles down
const{sin,cos,PI,max,min}=Math,T=2*PI
export const frames=24,delay=70
const MT='#a9744f',MD='#8d6346',LV='#ff6b6b',LO='#ff922b',LY='#ffd43b',SM='#dee2e6'
const BLOBS=[[-70,170,LO,10],[-30,220,LV,12],[10,240,LY,9],[46,200,LO,11],[80,160,LV,9],[-10,190,LV,8]]
export default(c,t,i)=>{
const sh=t<.25?(i%2?3:-3):0,u=(t-.25)/.55
for(let k=0;k<3;k++){const p=(t+k/3)%1,r=10+18*p;c.fillStyle=SM;c.lineWidth=5;c.beginPath();c.arc(128+sin(p*6+k)*16+(k-1)*14,72-p*64,r,0,T);c.fill();c.stroke()}
c.lineWidth=7
if(u>0&&u<1)for(const[vx,vy,col,r]of BLOBS){const x=128+vx*u,y=92-vy*u+340*u*u;if(y<240)c.fillStyle=col,c.beginPath(),c.arc(x,y,r,0,T),c.fill(),c.stroke()}
c.translate(sh,0)
const mtn=()=>{c.beginPath();c.moveTo(20,238);c.quadraticCurveTo(70,150,98,96);c.lineTo(158,96);c.quadraticCurveTo(186,150,236,238);c.closePath()}
mtn();c.fillStyle=MT;c.fill()
c.save();mtn();c.clip();c.fillStyle=MD;c.beginPath();c.moveTo(60,240);c.quadraticCurveTo(80,190,74,150);c.lineTo(90,150);c.quadraticCurveTo(100,200,96,240);c.fill()
c.fillStyle=LV;c.beginPath();c.moveTo(90,96);c.lineTo(166,96);c.lineTo(160,118);c.quadraticCurveTo(152,140,146,118);c.quadraticCurveTo(136,150,126,120);c.quadraticCurveTo(114,134,108,116);c.quadraticCurveTo(100,128,94,110);c.closePath();c.fill();c.lineWidth=5;c.stroke();c.restore()
mtn();c.stroke()
c.fillStyle=LO;c.beginPath();c.ellipse(128,96,32,9,0,0,T);c.fill();c.stroke()
const blast=u>0&&u<.5
c.fillStyle='#111'
for(const d of[-1,1])if(blast)c.beginPath(),c.arc(128+d*20,170,7,0,T),c.fill();else c.lineWidth=5,c.beginPath(),c.arc(128+d*20,168,7,PI*1.15,PI*1.85),c.stroke()
if(blast)c.beginPath(),c.ellipse(128,196,10,12,0,0,T),c.fill();else c.lineWidth=5,c.beginPath(),c.arc(128,190,9,.15*PI,.85*PI),c.stroke()
}
+22
View File
@@ -0,0 +1,22 @@
// round ocean badge: curling waves rolling past under a sun, spray flicking off the crests
const{sin,cos,PI}=Math,T=2*PI
export const frames=24,delay=70
const SKY='#d0ebff',SUN='#ffd43b',W1='#74c0fc',W2='#228be6'
const crest=(c,cx,base,h)=>{
c.moveTo(cx-64,base);c.quadraticCurveTo(cx-30,base-4,cx-10,base-h*.7)
c.quadraticCurveTo(cx+6,base-h*1.05,cx+30,base-h*.9);c.quadraticCurveTo(cx+40,base-h*.7,cx+26,base-h*.55)
c.quadraticCurveTo(cx+18,base-h*.75,cx+10,base-h*.55);c.quadraticCurveTo(cx+24,base-10,cx+64,base)
}
const band=(c,base,h,sh)=>{c.beginPath();c.moveTo(-200,260);for(let k=-2;k<4;k++)crest(c,k*128+sh,base,h);c.lineTo(460,260);c.closePath()}
export default(c,t)=>{
c.save();c.beginPath();c.arc(128,128,112,0,T);c.clip()
c.fillStyle=SKY;c.fillRect(0,0,256,256)
c.fillStyle=SUN;c.beginPath();c.arc(176,82,30,0,T);c.fill();c.stroke()
band(c,170,70,-t*128+64);c.fillStyle=W1;c.fill();c.stroke()
band(c,212,80,t*128*2%128-0);c.fillStyle=W2;c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=5
for(let k=-1;k<3;k++){const cx=k*128+(t*256%128);c.beginPath();c.arc(cx+10,212-48,14,PI*1.1,PI*1.7);c.stroke()}
c.fillStyle='#fff';c.strokeStyle='#111';c.lineWidth=4
for(let k=-1;k<3;k++)for(const[dx,dy,o]of[[38,-78,0],[46,-66,.4],[30,-88,.7]]){const p=(t*2+o)%1,cx=k*128+(t*256%128);c.beginPath();c.arc(cx+dx+p*16,212+dy-p*14+p*p*30,4*(1-p)+1,0,T);c.fill();c.stroke()}
c.restore();c.lineWidth=7;c.beginPath();c.arc(128,128,112,0,T);c.stroke()
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB