Add 150 UI and page state stickers in three pending sections

404s, loaders, success, errors, empty states, confirmation, under
construction, offline and more: 50 monochrome (ui), 50 colored (uicolor)
and 50 with an anime girl (uianime), on /test until approved.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-24 03:10:04 +00:00
co-authored by Claude Opus 5.5
parent c59222f593
commit c00ba79178
450 changed files with 5481 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
// red stop sign on a pole with a big white hand wagging no-no inside it, stern little face on the palm
const{sin,cos,PI}=Math,T=2*PI
export const frames=16,delay=80
const RD='#ff6b6b',PL='#adb5bd',BL='#ffa8a8'
const oct=(c,r)=>{c.beginPath();for(let k=0;k<8;k++){const a=k*PI/4+PI/8;c.lineTo(128+cos(a)*r,104+sin(a)*r)}c.closePath()}
const F=[[-22.5,-128],[-7.5,-136],[7.5,-132],[22.5,-120]]
const parts=[c=>c.roundRect(-30,-82,60,76,20),c=>c.roundRect(-20,-30,40,34,10),...F.map(([x,y])=>c=>c.roundRect(x-7,y,14,-50-y,7)),c=>{c.save();c.translate(-26,-42);c.rotate(-.75);c.roundRect(-7,-44,14,48,7);c.restore()}]
export default(c,t)=>{
const A=.26*sin(t*T*2),v=cos(t*T*2)
c.translate(128,244);c.rotate(.025*sin(t*T*2-.6));c.translate(-128,-244)
c.fillStyle=PL;c.beginPath();c.roundRect(116,176,24,66,6);c.fill();c.stroke()
oct(c,92);c.fillStyle=RD;c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=6;oct(c,79);c.stroke()
if(v*v>.3)for(const r of[132,114]){const a=-PI/2+A-v*.12;for(const[w,s]of[[10,'#111'],[4,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.arc(128,172,r*.88,a-(v>0?.2:-.05),a+(v>0?.05:.2)),c.stroke()}
c.save();c.translate(128,172);c.rotate(A);c.scale(.88,.88)
c.strokeStyle='#111';c.lineWidth=14;for(const p of parts)c.beginPath(),p(c),c.stroke()
c.fillStyle='#fff';for(const p of parts)c.beginPath(),p(c),c.fill()
c.lineWidth=4;c.beginPath();for(const x of[-15,0,15])c.moveTo(x,-82),c.lineTo(x,-70);c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(d*12,-50,5,0,T),c.fill()
c.lineWidth=4.5;for(const d of[-1,1])c.beginPath(),c.moveTo(d*5,-58),c.lineTo(d*20,-64),c.stroke()
c.beginPath();c.arc(0,-24,8,1.2*PI,1.8*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*21,-38,6,3.5,0,0,T),c.fill()
c.restore()
}
+30
View File
@@ -0,0 +1,30 @@
// a shy little ghost rises out of a hole torn in a page, peeks left and right, then sinks back down
const{sin,cos,PI}=Math,T=2*PI
export const frames=24,delay=70
const PG='#e7f5ff',LN='#a5d8ff',HO='#5f3dc4',HD='#3b2a8a',GH='#fff',GS='#e5dbff',BL='#ffa8a8'
const HX=128,HY=170,J=[1,.84,.97,.8,1,.88,.78,1,.86,.95,.8,1,.9,.8,.98,.84]
const hole=(c,s=1)=>{J.forEach((j,k)=>{const a=k/J.length*T;c.lineTo(HX+cos(a)*64*j*s,HY+sin(a)*32*j*s)});c.closePath()}
const ss=x=>x<=0?0:x>=1?1:x*x*(3-2*x)
export default(c,t)=>{
const u=ss(t/.22)-ss((t-.8)/.2),lk=ss((t-.28)/.1)-2*ss((t-.48)/.1)+ss((t-.68)/.1),gy=HY+70-170*u,ln=-.16*lk
c.save();c.translate(128,150);c.rotate(-.05);c.translate(-128,-150)
c.fillStyle=PG;c.beginPath();c.moveTo(42,62);c.lineTo(184,62);c.lineTo(214,92);c.lineTo(214,238);c.lineTo(42,238);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(184,62);c.lineTo(184,92);c.lineTo(214,92);c.closePath();c.fill();c.lineWidth=5;c.stroke()
c.strokeStyle=LN;c.lineWidth=8;for(const[y,a,b]of[[86,62,160],[106,62,190],[126,62,140],[220,70,186]])c.beginPath(),c.moveTo(a,y),c.lineTo(b,y),c.stroke()
c.restore()
c.fillStyle='#fff';c.beginPath();hole(c,1.12);c.fill();c.lineWidth=4;c.strokeStyle='#111';c.stroke()
c.fillStyle=HO;c.beginPath();hole(c);c.fill();c.lineWidth=6;c.stroke()
c.fillStyle=HD;c.beginPath();c.ellipse(HX,HY+6,44,18,0,0,T);c.fill()
c.save();c.beginPath();c.rect(0,0,256,HY);hole(c);c.clip()
c.translate(HX,HY);c.rotate(ln);c.translate(0,gy-HY);c.scale(.92,.84)
const body=()=>{c.beginPath();c.moveTo(-40,0);c.arc(0,0,40,PI,0);c.lineTo(44,124);for(let k=0;k<4;k++){const x0=44-k*22,w=4*sin(T*t*2+k*1.6);c.quadraticCurveTo(x0-11,136+w,x0-22,124)}c.closePath()}
c.fillStyle=GH;body();c.fill();c.save();c.clip();c.fillStyle=GS;c.beginPath();c.ellipse(-12,30,50,120,0,0,T);c.rect(80,-60,-200,240);c.fill('evenodd');c.restore()
body();c.lineWidth=7;c.strokeStyle='#111';c.stroke()
for(const d of[-1,1]){c.fillStyle=GH;c.beginPath();c.ellipse(d*44,44-lk*d*8,10,14,d*.5,0,T);c.fill();c.lineWidth=5;c.stroke()}
const ex=lk*7
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.ellipse(d*14+ex,-2,5.5,7.5,0,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*14+ex-2,-5,2.2,0,T),c.fill()
c.fillStyle='#111';c.beginPath();c.ellipse(ex,14,4,5,0,0,T);c.fill()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*26+ex*.6,10,7,4,0,0,T),c.fill()
c.restore()
}
+31
View File
@@ -0,0 +1,31 @@
// a folded paper map unfolded, a dotted trail marching from a bouncing red pin to a big wobbly "?" where the road runs out
const{sin,PI}=Math,T=2*PI
export const frames=16,delay=80
const P1='#fff4e6',P2='#ffe8cc',WA='#a5d8ff',LA='#c3fae8',TR='#69db7c',PN='#fa5252',Q='#b197fc'
const X=[16,92,166,240],TOP=[60,46,60,46],BOT=[214,228,214,228]
const map=c=>{c.beginPath();X.forEach((x,k)=>c.lineTo(x,TOP[k]));for(let k=3;k>=0;k--)c.lineTo(X[k],BOT[k]);c.closePath()}
const pnl=(c,k)=>{c.beginPath();c.moveTo(X[k],TOP[k]);c.lineTo(X[k+1],TOP[k+1]);c.lineTo(X[k+1],BOT[k+1]);c.lineTo(X[k],BOT[k]);c.closePath()}
export default(c,t)=>{
const ph=(t*2)%1,j=4*ph*(1-ph),py=192-30*j,sq=ph<.1?1-(.1-ph)*2:1
c.fillStyle=P1;map(c);c.fill();c.fillStyle=P2;pnl(c,1);c.fill()
c.save();map(c);c.clip()
c.fillStyle=LA;c.beginPath();c.ellipse(204,214,70,40,0,0,T);c.fill();c.beginPath();c.ellipse(30,64,50,34,0,0,T);c.fill()
c.fillStyle=WA;c.beginPath();c.ellipse(70,92,34,20,-.2,0,T);c.fill()
c.strokeStyle=WA;c.lineWidth=10;c.beginPath();c.moveTo(96,96);c.bezierCurveTo(130,110,110,150,150,160);c.bezierCurveTo(170,166,160,200,190,236);c.stroke()
c.fillStyle='rgba(200,110,20,.1)';pnl(c,1);c.fill()
c.restore()
c.lineWidth=7;c.strokeStyle='#111';map(c);c.stroke()
c.lineWidth=4;for(const k of[1,2])c.beginPath(),c.moveTo(X[k],TOP[k]),c.lineTo(X[k],BOT[k]),c.stroke()
for(const[x,y]of[[110,68],[126,78],[30,168]]){c.fillStyle=TR;c.lineWidth=4;c.beginPath();c.arc(x,y,9,0,T);c.fill();c.stroke()}
c.lineWidth=8;c.setLineDash([.1,14.9]);c.lineDashOffset=-t*30;c.beginPath();c.moveTo(56,196);c.bezierCurveTo(96,206,94,150,128,150);c.bezierCurveTo(156,150,146,198,172,194);c.stroke();c.setLineDash([])
c.save();c.translate(182,192);c.rotate(.14*sin(T*t))
for(const[w,s]of[[30,'#111'],[17,Q]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(-24,-82),c.bezierCurveTo(-24,-116,24,-116,24,-84),c.bezierCurveTo(24,-60,0,-62,0,-34),c.stroke()
c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();c.moveTo(-20,-90);c.quadraticCurveTo(-16,-102,-6,-104);c.stroke()
c.strokeStyle='#111';c.lineWidth=6;c.fillStyle=Q;c.beginPath();c.arc(0,-6,12,0,T);c.fill();c.stroke()
c.restore()
c.fillStyle='rgba(0,0,0,.15)';c.beginPath();c.ellipse(56,196,14*(1-j*.4),5*(1-j*.4),0,0,T);c.fill()
c.save();c.translate(56,py);c.scale(2-sq,sq)
c.fillStyle=PN;c.lineWidth=6;c.beginPath();c.moveTo(0,0);c.bezierCurveTo(-4,-12,-20,-26,-20,-42);c.arc(0,-42,20,PI,0);c.bezierCurveTo(20,-26,4,-12,0,0);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.arc(0,-42,8,0,T);c.fill();c.lineWidth=4;c.stroke()
c.restore()
}
+27
View File
@@ -0,0 +1,27 @@
// "404" adrift in outer space: the 0 is a spinning pink ringed planet with a little smile, the 4s bob gently up and down, stars twinkling all around
const{sin,cos,PI}=Math,T=2*PI
export const frames=16,delay=90
const A='#4dabf7',B='#b197fc',PL='#f783ac',PB='#faa2c1',PD='#e64980',RG='#ffd43b',BL='#ff8787'
const dig=(c,f,col)=>{for(const[w,s]of[[32,'#111'],[19,col]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),f(),c.stroke();c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();c.moveTo(-17,-30);c.lineTo(-19,-14);c.stroke();c.lineWidth=7;c.strokeStyle='#111'}
const four=c=>()=>{c.moveTo(-14,-40);c.lineTo(-20,10);c.lineTo(24,10);c.moveTo(12,-40);c.lineTo(12,40)}
const spark=(c,x,y,s)=>{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()}
export default(c,t)=>{
for(const[x,y,o]of[[26,34,0],[128,24,.5],[226,44,.25],[30,222,.75],[222,224,.4],[128,232,.1]])spark(c,x,y,4+6*(1+sin((t+o)*T))/2)
c.lineWidth=7
const py=128+Math.round(4*sin(T*t+1)),tl=-.26
for(const[x,ph,col]of[[44,0,A],[208,PI,B]]){c.save();c.translate(x,128+Math.round(9*sin(T*t+ph)));dig(c,four(c),col);c.restore()}
const ring=(a,b)=>{c.save();c.translate(128,py);c.rotate(tl);for(const[w,s]of[[22,'#111'],[10,RG]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.ellipse(0,0,66,15,0,a,b),c.stroke();c.restore();c.strokeStyle='#111';c.lineWidth=7}
ring(PI,T)
c.fillStyle=PL;c.beginPath();c.arc(128,py,42,0,T);c.fill()
c.save();c.clip();c.translate(128,py);c.rotate(tl)
c.fillStyle=PB;c.fillRect(-46,-31,92,10);c.fillRect(-46,20,92,8)
for(const[a,y,r]of[[0,-27,5],[2.1,27,5],[4,-26,4],[5.2,24,5],[1,-37,3.5],[3.2,35,3.5]]){const q=a+t*T,x=38*sin(q);if(cos(q)>0){c.fillStyle=PD;c.beginPath();c.ellipse(x,y,r*cos(q),r,0,0,T);c.fill()}}
c.restore()
c.beginPath();c.arc(128,py,42,0,T);c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+d*15,py-2,5.5,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(128+d*15-2,py-4,2,0,T),c.fill()
c.lineWidth=4;c.beginPath();c.arc(128,py+5,7,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*26,py+9,6,3.5,0,0,T),c.fill()
c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();c.arc(128,py,33,PI*1.1,PI*1.35);c.stroke();c.strokeStyle='#111'
ring(0,PI)
}
+32
View File
@@ -0,0 +1,32 @@
// a little ufo hovers over a colorful "404" and beams the 0 up out of it, the 0 dangling and swaying in the tractor beam before it drops back in its slot
const{sin,cos,PI,floor}=Math,T=2*PI
export const frames=16,delay=80
const C4='#ff6b6b',C0='#ffd43b',C4b='#4dabf7',SA='#b197fc',SD='#9775fa',GL='#d0ebff',AL='#8ce99a',BM='#ffec99',LT=['#ff6b6b','#ffd43b','#69db7c']
const dig=(c,f,col)=>{for(const[w,s]of[[32,'#111'],[19,col]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),f(),c.stroke();c.lineWidth=7;c.strokeStyle='#111'}
const four=(c,x,y)=>()=>{c.moveTo(x-14,y-34);c.lineTo(x-20,y+8);c.lineTo(x+24,y+8);c.moveTo(x+12,y-34);c.lineTo(x+12,y+34)}
export default(c,t,i)=>{
const h=(1-cos(T*t))/2,e=h*h*(3-2*h),uy=Math.round(2*sin(T*t)),oy=184-58*e,ox=128+6*sin(2*T*t+1)*e,sw=.2*sin(2*T*t)*e
c.fillStyle=BM;c.beginPath();c.moveTo(106,72);c.lineTo(150,72);c.lineTo(186,226);c.ellipse(128,226,58,12,0,0,PI);c.closePath();c.fill()
c.save();c.clip();c.strokeStyle='#fff';c.lineWidth=6
for(let k=0;k<3;k++){const q=(t*2+k/3)%1,y=226-q*150,w=22+(y-74)/152*36;c.beginPath();c.ellipse(128,y,w,7,0,0,PI);c.stroke()}
c.restore();c.lineWidth=5;c.beginPath();c.moveTo(106,72);c.lineTo(150,72);c.lineTo(186,226);c.ellipse(128,226,58,12,0,0,PI);c.closePath();c.stroke()
c.lineWidth=5;c.setLineDash([9,11]);c.beginPath();c.ellipse(128,184,23,34,0,0,T);c.stroke();c.setLineDash([])
dig(c,four(c,44,184),C4);dig(c,four(c,198,184),C4b)
c.save();c.translate(ox,oy);c.rotate(sw);dig(c,()=>c.ellipse(0,0,23,34,0,0,T),C0)
c.strokeStyle='#fff';c.lineWidth=6;c.beginPath();c.ellipse(0,0,23,34,0,PI*1.12,PI*1.38);c.stroke();c.restore()
c.strokeStyle='#fff';c.lineWidth=6;for(const x of[30,184])c.beginPath(),c.moveTo(x,160),c.lineTo(x-2,170),c.stroke()
c.strokeStyle='#111';c.lineWidth=7
c.save();c.translate(128,uy)
c.fillStyle=GL;c.beginPath();c.arc(0,50,35,PI,0);c.closePath();c.fill()
c.fillStyle=AL;c.beginPath();c.arc(0,34,15,0,T);c.fill();c.lineWidth=4;c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.ellipse(d*6,33,4,5.5,d*.3,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*6-1.5,31,1.6,0,T),c.fill()
c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();c.arc(0,50,26,PI*1.12,PI*1.35);c.stroke();c.strokeStyle='#111'
c.lineWidth=7;c.beginPath();c.arc(0,50,35,PI,0);c.stroke()
c.fillStyle=BM;c.beginPath();c.ellipse(0,75,24,8,0,0,T);c.fill();c.lineWidth=5;c.stroke();c.lineWidth=7
c.fillStyle=SA;c.beginPath();c.ellipse(0,61,74,17,0,0,T);c.fill();c.stroke()
c.fillStyle=SD;c.beginPath();c.ellipse(0,59,72,7,0,0,PI);c.lineTo(-72,64);c.ellipse(0,64,72,12,0,PI,0,true);c.closePath();c.fill()
c.beginPath();c.ellipse(0,61,74,17,0,0,T);c.stroke()
c.lineWidth=4;for(let k=0;k<5;k++){const x=(k-2)*26,y=64+(k==0||k==4?-4:k==2?3:1);c.fillStyle=(k+floor(t*8))%2?'#fff':LT[k%3];c.beginPath();c.arc(x,y,6,0,T);c.fill();c.stroke()}
c.restore()
}
+35
View File
@@ -0,0 +1,35 @@
// panicking server rack on fire, cartoon flames flickering out the top, red lights blinking while an extinguisher puffs foam at it
const{sin,cos,PI,min,max}=Math,T=2*PI
export const frames=16,delay=70
const RK='#495057',SL='#343a40',PN='#a5d8ff',FR=['#ff6b6b','#ff922b','#ffd43b'],EX='#ff6b6b',LED='#ff6b6b',BL='#ffa8a8'
const fl=(c,x,b,w,h,s)=>{c.beginPath();c.moveTo(x-w,b);c.bezierCurveTo(x-w*1.2,b-h*.45,x+s-w*.5,b-h*.62,x+s,b-h);c.bezierCurveTo(x+s+w*.55,b-h*.62,x+w*1.2,b-h*.45,x+w,b);c.closePath()}
export default(c,t,i)=>{
for(const[k,[x,w,h,ph]]of[[54,30,58,1],[122,32,66,3],[88,44,86,0]].entries()){
const hh=h*(1+.1*sin(2*T*t+ph)+.06*sin(4*T*t+ph*2)),s=8*sin(T*t*2+ph+k)
for(const[j,col]of FR.entries()){const f=[1,.68,.38][j];fl(c,x+s*(1-f)*.5,112,w*f,hh*f,s*f);c.fillStyle=col;c.fill();if(!j)c.lineWidth=6,c.stroke()}
}
c.lineWidth=7;c.fillStyle=RK;c.beginPath();c.roundRect(26,100,124,138,12);c.fill();c.stroke()
c.fillStyle=PN;c.lineWidth=5;c.beginPath();c.roundRect(38,112,100,52,8);c.fill();c.stroke()
c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.moveTo(88+d*31,127),c.lineTo(88+d*13,120),c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(88+d*21,136,5,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(88+d*21-1.5,134.5,1.8,0,T),c.fill()
c.fillStyle='#111';c.beginPath();c.ellipse(88,153,7,6+(i%2),0,0,T);c.fill()
c.fillStyle='#4dabf7';c.lineWidth=3;c.beginPath();const sy=118+(i%4);c.moveTo(130,sy);c.quadraticCurveTo(136,sy+10,130,sy+12);c.quadraticCurveTo(124,sy+10,130,sy);c.fill();c.stroke()
for(let k=0;k<3;k++){
const y=172+k*21;c.fillStyle=SL;c.lineWidth=4;c.beginPath();c.roundRect(38,y,100,15,4);c.fill();c.stroke()
c.strokeStyle='#868e96';c.lineWidth=3;c.beginPath();for(let x=50;x<100;x+=9)c.moveTo(x,y+4),c.lineTo(x,y+11);c.stroke();c.strokeStyle='#111'
for(const[j,x]of[112,126].entries()){const on=((i>>1)+k+j)%2;c.fillStyle=on?LED:'#862e2e';c.lineWidth=2.5;c.beginPath();c.arc(x,y+7.5,4.5,0,T);c.fill();c.stroke()}
}
for(let k=0;k<3;k++){
const p=(t+k/3)%1,x=160-60*p,y=110-58*p+10*sin(PI*p),r=(7+17*p)*min(1,(1-p)*4)
if(r>1)c.fillStyle='#fff',c.lineWidth=5,c.beginPath(),c.arc(x,y,r,0,T),c.fill(),c.stroke()
}
for(const[w,s]of[[13,'#111'],[6,SL]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(212,140),c.bezierCurveTo(186,150,178,138,172,124),c.stroke()
c.strokeStyle='#111';c.lineWidth=16;c.beginPath();c.moveTo(174,126);c.lineTo(164,114);c.stroke()
c.lineWidth=7;c.fillStyle='#adb5bd';c.beginPath();c.roundRect(204,128,20,18,3);c.fill();c.stroke()
for(const[w,s]of[[12,'#111'],[5,'#adb5bd']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(206,124),c.lineTo(236,116),c.stroke()
c.strokeStyle='#111';c.lineWidth=7;c.fillStyle=EX;c.beginPath();c.roundRect(190,144,48,94,[22,22,8,8]);c.fill();c.stroke()
c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.roundRect(196,180,36,26,4);c.fill();c.stroke()
c.strokeStyle=EX;c.lineWidth=4;c.beginPath();c.moveTo(204,189);c.lineTo(224,189);c.moveTo(204,197);c.lineTo(218,197);c.stroke()
c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();c.moveTo(198,162);c.lineTo(198,172);c.stroke()
}
+31
View File
@@ -0,0 +1,31 @@
// star badge levels up, a green arrow shoots up from behind it, the badge hops and its happy star flips while sparkles burst
const{sin,cos,PI,min,max}=Math,T=2*PI
export const frames=18,delay=90
const BG='#9775fa',BI='#b197fc',ST='#ffd43b',AR='#51cf66',RB='#ff6b6b',BL='#ffa8a8'
const back=u=>{const s=1.8;return 1+(s+1)*(u-1)**3+s*(u-1)**2},io=u=>u*u*(3-2*u),cl=u=>min(1,max(0,u))
const sp=(c,x,y,s)=>{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()}
export default(c,t)=>{
const o=t<.05?0:t<.35?back((t-.05)/.3):t<.75?1+.03*sin(2*T*(t-.35)/.4):t<.95?1-io((t-.75)/.2):0
const hop=10*sin(PI*cl((t-.08)/.27)),sq=t>.03&&t<.12?1-.08*sin(PI*(t-.03)/.09):1,fl=cos(T*io(cl((t-.32)/.3))),b=(t-.32)/.35
if(b>0&&b<1)for(let k=0;k<6;k++){const a=k*T/6-PI/2+.5,r=78+34*b;sp(c,128+cos(a)*r,146+sin(a)*r*.85,13*sin(PI*b))}
for(const[x,y,ph]of[[34,40,0],[222,64,.5]]){const s=10*max(0,sin(PI*((t*2+ph)%1)));if(s>1.5)sp(c,x,y,s)}
c.lineWidth=7;c.strokeStyle='#111'
const ay=146-116*o
c.save();c.beginPath();c.rect(0,0,256,146-hop);c.clip();c.translate(128,ay);c.fillStyle=AR;c.beginPath()
for(const[x,y]of[[0,0],[40,40],[17,40],[17,110],[-17,110],[-17,40],[-40,40]])c.lineTo(x,y)
c.closePath();c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();c.moveTo(-8,48);c.lineTo(-8,64);c.moveTo(-6,14);c.lineTo(-20,28);c.stroke();c.restore()
c.strokeStyle='#111';c.lineWidth=7
c.translate(128,146-hop);c.scale(.92*(2-sq),.92*sq)
c.fillStyle=RB;for(const d of[-1,1])c.beginPath(),c.moveTo(d*10,40),c.lineTo(d*42,30),c.lineTo(d*54,98),c.lineTo(d*40,88),c.lineTo(d*26,102),c.closePath(),c.fill(),c.stroke()
c.fillStyle=BG;c.beginPath();for(let k=0;k<128;k++){const a=k*T/128,r=62+4.5*cos(16*a);c.lineTo(cos(a)*r,sin(a)*r)}c.closePath();c.fill();c.stroke()
c.fillStyle=BI;c.lineWidth=5;c.beginPath();c.arc(0,0,49,0,T);c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();c.arc(0,0,42,PI*1.12,PI*1.38);c.stroke();c.strokeStyle='#111'
c.save();c.scale(fl,1);c.fillStyle=ST;c.lineWidth=5;c.beginPath();for(let k=0;k<10;k++){const r=k%2?19:43,a=k*PI/5-PI/2;c.lineTo(cos(a)*r,3+sin(a)*r)}c.closePath();c.fill();c.stroke()
if(fl>.3){
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(d*9,4,3.8,0,T),c.fill()
c.lineWidth=3.5;c.beginPath();c.arc(0,9,5,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*16,11,4,2.5,0,0,T),c.fill()
}
c.restore()
}
+24
View File
@@ -0,0 +1,24 @@
// red battery nearly drained, its last little bar blinking, wobbling tiredly with a worried sweaty face and drops sliding down
const{sin,PI,floor}=Math,T=2*PI
export const frames=16,delay=90
const R='#ff6b6b',RD='#fa5252',CAP='#ced4da',DR='#a5d8ff',BL='#ffa8a8'
const drop=(c,x,y,s)=>{c.fillStyle=DR;c.lineWidth=4;c.beginPath();c.moveTo(x,y-11*s);c.quadraticCurveTo(x+9*s,y+2*s,x,y+5*s);c.quadraticCurveTo(x-9*s,y+2*s,x,y-11*s);c.fill();c.stroke();c.fillStyle='#fff';c.beginPath();c.arc(x-2*s,y,1.8*s,0,T);c.fill()}
export default(c,t,i)=>{
const on=floor(t*4)%2==0,r=.05*sin(T*t),sq=1+.025*sin(2*T*t)
c.save();c.translate(128,236);c.rotate(r);c.scale(2-sq,sq);c.translate(-128,-236)
c.fillStyle=CAP;c.beginPath();c.roundRect(102,18,52,26,8);c.fill();c.stroke()
c.fillStyle=on?R:'#ffa8a8';c.beginPath();c.roundRect(62,38,132,198,28);c.fill();c.stroke()
c.fillStyle='#fff';c.lineWidth=6;c.beginPath();c.roundRect(80,56,96,162,16);c.fill();c.stroke()
if(on){c.fillStyle=RD;c.lineWidth=5;c.beginPath();c.roundRect(90,190,76,18,7);c.fill();c.stroke()}
else{c.strokeStyle='#ffa8a8';c.lineWidth=4;c.setLineDash([6,6]);c.beginPath();c.roundRect(90,190,76,18,7);c.stroke();c.setLineDash([]);c.strokeStyle='#111'}
c.fillStyle='#fff';c.beginPath();c.ellipse(76,74,4,12,0,0,T);c.fill()
c.lineWidth=4.5;for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*12,100),c.lineTo(128+d*29,107),c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*20,124,6,8,0,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(128+d*20-2,120,2.6,0,T),c.fill()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*32,144,8,4.5,0,0,T),c.fill()
c.lineWidth=4.5;c.beginPath();c.moveTo(114,158);for(let k=1;k<=7;k++)c.lineTo(114+k*4,158+(k%2?-4:0)+(i%2?1:0));c.stroke()
for(const[x,o,z]of[[170,0,1.3],[88,.5,1]]){const p=(t*2+o)%1;drop(c,x,84+p*34,z*(.8+.3*p))}
c.restore()
for(const d of[-1,1])for(const[w,s]of[[9,'#111'],[4,'#fff']]){c.lineWidth=w;c.strokeStyle=s;const x=128+d*(86+(i%2)*3);c.beginPath();c.moveTo(x,96);c.lineTo(x+d*8,104);c.moveTo(x+2*d,118);c.lineTo(x+d*12,120);c.stroke()}
c.strokeStyle='#111'
}
+34
View File
@@ -0,0 +1,34 @@
// empty shopping cart rolling back and forth with a sad face and a tear, one lonely crumb sliding around the bottom of its basket
const{sin,cos,PI}=Math,T=2*PI
export const frames=20,delay=80
const BK='#d0ebff',GR='#74c0fc',MT='#ced4da',HD='#ff6b6b',CR='#e0a96d',CH='#8b5a3c',BL='#ffa8a8',TR='#74c0fc'
const bas=c=>{c.beginPath();c.moveTo(56,80);c.lineTo(222,80);c.lineTo(200,168);c.lineTo(78,168);c.closePath()}
export default(c,t)=>{
const dx=10*sin(t*T),cx=140-38*sin(t*T-.9)
c.translate(dx,0)
for(const[w,s]of[[14,'#111'],[6,MT]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(60,84),c.lineTo(36,62),c.moveTo(84,166),c.lineTo(92,196),c.lineTo(192,196),c.lineTo(198,166),c.stroke()
c.strokeStyle='#111';c.lineWidth=6
c.save();c.translate(34,60);c.rotate(.74);c.fillStyle=HD;c.beginPath();c.roundRect(-14,-9,24,18,9);c.fill();c.stroke();c.restore()
for(const x of[100,184]){
c.save();c.translate(x,214);c.rotate(dx/16);c.fillStyle='#495057';c.lineWidth=6;c.beginPath();c.arc(0,0,17,0,T);c.fill();c.stroke()
c.fillStyle=MT;c.lineWidth=4;c.beginPath();c.arc(0,0,7,0,T);c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=4;c.beginPath();c.arc(0,0,12,-.6,.6);c.stroke();c.restore()
}
c.strokeStyle='#111';c.lineWidth=7;bas(c);c.fillStyle=BK;c.fill()
c.save();bas(c);c.clip();c.strokeStyle=GR;c.lineWidth=4;c.beginPath()
for(const y of[102,124,146])c.moveTo(40,y),c.lineTo(230,y)
for(let k=0;k<7;k++)c.moveTo(78+k*22,80),c.lineTo(86+k*19,168)
c.stroke();c.restore()
c.strokeStyle='#111';c.lineWidth=7;bas(c);c.stroke()
for(const[w,s]of[[14,'#111'],[6,MT]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(50,80),c.lineTo(228,80),c.stroke()
c.strokeStyle='#111'
c.save();c.translate(cx,159);c.rotate((cx-140)/8);c.fillStyle=CR;c.lineWidth=3.5;c.beginPath();for(let k=0;k<6;k++){const a=k*T/6,r=k%2?7:9.5;c.lineTo(cos(a)*r,sin(a)*r)}c.closePath();c.fill();c.stroke()
c.fillStyle=CH;c.beginPath();c.arc(2,-1,2.5,0,T);c.fill();c.restore()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(139+d*22,112,6.5,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(137+d*22,110,2.2,0,T),c.fill()
c.lineWidth=4.5;for(const d of[-1,1])c.beginPath(),c.moveTo(139+d*12,96),c.lineTo(139+d*30,101),c.stroke()
c.lineWidth=5;c.beginPath();c.arc(139,146,11,1.15*PI,1.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(139+d*38,126,8,5,0,0,T),c.fill()
const p=(t*2)%1,ty=118+p*34
if(p<.85){c.fillStyle=TR;c.lineWidth=3;c.beginPath();c.moveTo(117,ty);c.quadraticCurveTo(124,ty+10,117,ty+12);c.quadraticCurveTo(110,ty+10,117,ty);c.fill();c.stroke()}
}
+35
View File
@@ -0,0 +1,35 @@
// mint oven baking a happy little cake that puffs up behind the glowing window while the timer dial ticks round
const{sin,cos,PI,floor}=Math,T=2*PI
export const frames=24,delay=90
const O='#63e6be',OD='#38d9a9',PN='#c3fae8',IN='#ffc078',CK='#fff3bf',CR='#ffd8a8',BL='#ffa8a8',HN='#dee2e6',RD='#ff6b6b',PAN='#adb5bd'
export default(c,t,i)=>{
const s=.5-.5*cos(T*t),h=34+22*s,tk=floor(t*12),tick=i%2==0,hot=.5+.5*sin(4*T*t)
c.fillStyle='#495057';for(const x of[46,184])c.beginPath(),c.roundRect(x,222,26,18,6),c.fill(),c.stroke()
c.fillStyle=O;c.beginPath();c.roundRect(22,22,212,206,26);c.fill();c.stroke()
c.fillStyle=PN;c.lineWidth=5;c.beginPath();c.roundRect(36,34,184,52,16);c.fill();c.stroke()
for(const[x,a]of[[66,-.8],[104,.6]]){c.fillStyle='#fff';c.beginPath();c.arc(x,60,14,0,T);c.fill();c.stroke();c.lineWidth=4;c.beginPath();c.moveTo(x,60);c.lineTo(x+cos(a-PI/2)*9,60+sin(a-PI/2)*9);c.stroke();c.lineWidth=5}
c.save();c.translate(182,60);if(tick)c.rotate(.08*(tk%2?1:-1))
c.fillStyle='#fff3bf';c.beginPath();c.arc(0,0,20,0,T);c.fill();c.stroke()
c.lineWidth=3;for(let k=0;k<4;k++){const a=k*PI/2;c.beginPath();c.moveTo(cos(a)*13,sin(a)*13);c.lineTo(cos(a)*16,sin(a)*16);c.stroke()}
const ha=-PI/2+tk*T/12;c.strokeStyle=RD;c.lineWidth=4;c.beginPath();c.moveTo(0,0);c.lineTo(cos(ha)*13,sin(ha)*13);c.stroke()
c.fillStyle='#111';c.beginPath();c.arc(0,0,3,0,T);c.fill();c.restore()
if(tick)for(const a of[-.5,0,.5].map(v=>v-PI/4))for(const[w,st]of[[8,'#111'],[3,'#fff']])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.moveTo(182+cos(a)*27,60+sin(a)*27),c.lineTo(182+cos(a)*35,60+sin(a)*35),c.stroke()
c.strokeStyle='#111';c.lineWidth=7
c.fillStyle=OD;c.beginPath();c.roundRect(36,98,184,118,18);c.fill();c.stroke()
c.fillStyle=HN;c.lineWidth=5;c.beginPath();c.roundRect(72,104,112,12,6);c.fill();c.stroke()
const win=()=>{c.beginPath();c.roundRect(54,124,148,84,12)}
c.fillStyle=IN;win();c.fill();c.save();win();c.clip()
c.fillStyle='#ffe8cc';c.beginPath();c.ellipse(128,210,74+6*hot,36+4*hot,0,0,T);c.fill()
for(const[w,st]of[[8,'#111'],[4,hot>.5?RD:'#ff8787']]){c.lineWidth=w;c.strokeStyle=st;c.beginPath();for(let x=66;x<=190;x+=12)c.lineTo(x,(x-66)%24?140:134);c.stroke()}
c.strokeStyle='#111';c.lineWidth=4;c.beginPath();c.moveTo(54,202);c.lineTo(202,202);c.stroke()
c.lineWidth=5;c.fillStyle=PAN;c.beginPath();c.moveTo(74,188);c.lineTo(182,188);c.lineTo(176,202);c.lineTo(80,202);c.closePath();c.fill();c.stroke()
const cake=()=>{c.beginPath();c.moveTo(84,190);c.lineTo(84,190-h*.5);c.bezierCurveTo(84,184-h,172,184-h,172,190-h*.5);c.lineTo(172,190);c.closePath()}
c.fillStyle=CK;cake();c.fill();c.save();cake();c.clip();c.fillStyle=CR;c.fillRect(70,180-h,120,h*.4);c.restore();cake();c.stroke()
const ey=198-h*.6
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*14,ey,4.5,6,0,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(128+d*14-1.5,ey-2.5,2,0,T),c.fill()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*26,ey+8,7,4,0,0,T),c.fill()
c.lineWidth=4;c.beginPath();c.arc(128,ey+4,7,.15*PI,.85*PI);c.stroke()
c.strokeStyle='#fff';c.lineWidth=6;c.beginPath();c.moveTo(170,132);c.lineTo(150,152);c.moveTo(186,134);c.lineTo(178,142);c.stroke()
c.restore();c.strokeStyle='#111';c.lineWidth=5;win();c.stroke()
}
+35
View File
@@ -0,0 +1,35 @@
// orange and white striped road barrier, its two warning lamps flashing in turn, the lit lamp wide awake and beaming while the other dozes
const{sin,cos,PI,floor,max}=Math,T=2*PI
export const frames=16,delay=90
const OR='#ff922b',ON='#ffd43b',OFF='#c8962e',HS='#495057',PO='#dee2e6',BL='#ffa8a8'
const board=(c,y,h)=>{
const r=()=>{c.beginPath();c.roundRect(14,y,228,h,10)}
c.save();r();c.fillStyle='#fff';c.fill();c.clip();c.fillStyle=OR
for(let s=-60;s<250;s+=44)c.beginPath(),c.moveTo(s,y+h),c.lineTo(s+22,y+h),c.lineTo(s+22+h,y),c.lineTo(s+h,y),c.fill()
c.restore();r();c.stroke()
}
export default(c,t)=>{
const k=floor(t*4)%2,p=(t*4)%1,pop=1+.1*max(0,1-p*3)
c.fillStyle=PO
for(const x of[64,192])c.beginPath(),c.roundRect(x-9,70,18,156,6),c.fill(),c.stroke(),c.beginPath(),c.roundRect(x-38,222,76,16,8),c.fill(),c.stroke()
board(c,90,48);board(c,158,38)
for(const[j,x]of[[0,64],[1,192]]){
const on=j==k
c.save();c.translate(x,54);if(on)c.scale(pop,pop)
if(on)for(let r=0;r<7;r++){const a=PI+r*PI/6;for(const[w,s]of[[9,'#111'],[4,ON]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(cos(a)*35,sin(a)*35),c.lineTo(cos(a)*44,sin(a)*44),c.stroke()}
c.strokeStyle='#111';c.lineWidth=7
c.fillStyle=HS;c.beginPath();c.arc(0,0,30,0,T);c.fill();c.stroke()
c.fillStyle=on?ON:OFF;c.lineWidth=5;c.beginPath();c.arc(0,0,22,0,T);c.fill();c.stroke()
c.fillStyle='#111';c.lineWidth=3.5
if(on){
c.fillStyle='#fff';c.beginPath();c.ellipse(-10,-11,5,3,-.6,0,T);c.fill()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.ellipse(d*8,-2,3.5,4.5,0,0,T),c.fill()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*14,6,4,2.5,0,0,T),c.fill()
c.beginPath();c.arc(0,4,6,.15*PI,.85*PI);c.stroke()
}else{
for(const d of[-1,1])c.beginPath(),c.arc(d*8,-4,4,.2*PI,.8*PI),c.stroke()
c.beginPath();c.moveTo(-3,9);c.lineTo(3,9);c.stroke()
}
c.restore()
}
}
+48
View File
@@ -0,0 +1,48 @@
// yellow excavator digging into a dirt pile, lifting a full bucket and dumping it back, exhaust puffing, smiling as it works
const{sin,cos,PI,round}=Math,T=2*PI
export const frames=20,delay=90
const Y='#ffd43b',YD='#fab005',TR='#495057',WH='#ced4da',GL='#a5d8ff',DI='#c08552',DD='#8d6346',BL='#ffa8a8',EX='#868e96'
const arm=(c,a,b,w,col)=>{for(const[lw,s]of[[w,'#111'],[w-10,col]])c.lineWidth=lw,c.strokeStyle=s,c.beginPath(),c.moveTo(...a),c.lineTo(...b),c.stroke();c.strokeStyle='#111';c.lineWidth=7}
const pin=(c,[x,y])=>{c.fillStyle=WH;c.lineWidth=4;c.beginPath();c.arc(x,y,6,0,T);c.fill();c.stroke();c.lineWidth=7}
const pose=t=>{
const s=.5-.5*cos(T*t),a1=-.15-.75*s,a2=1.5-.6*s,th=a2-PI/2+.5+.9*sin(T*t)
const E=[128+80*cos(a1),128+80*sin(a1)],B=[E[0]+64*cos(a2),E[1]+64*sin(a2)]
return{E,B,th,at:(x,y)=>[B[0]+x*cos(th)-y*sin(th),B[1]+x*sin(th)+y*cos(th)]}
}
const mound=c=>{c.beginPath();c.moveTo(146,240);c.bezierCurveTo(160,178,234,172,248,240);c.closePath()}
export default(c,t)=>{
const{E,B,th}=pose(t),by=round(2*sin(2*T*t)),full=t>.03&&t<.5
for(let k=0;k<3;k++){const p=(t*3+k/3)%1,r=4+8*sin(PI*p);c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.arc(34-8*p+4*sin(T*p),76-50*p+by,r,0,T);c.fill();c.stroke()}
c.lineWidth=7
c.fillStyle=TR;c.beginPath();c.roundRect(10,192,132,44,22);c.fill();c.stroke()
for(const x of[32,76,120]){c.fillStyle=WH;c.lineWidth=5;c.beginPath();c.arc(x,214,11,0,T);c.fill();c.stroke();c.fillStyle='#111';c.beginPath();c.arc(x,214,3,0,T);c.fill()}
c.lineWidth=7;c.translate(0,by)
c.fillStyle='#343a40';c.beginPath();c.rect(34,180,92,14);c.fill();c.stroke()
c.fillStyle=EX;c.beginPath();c.roundRect(28,80,12,40,4);c.fill();c.stroke()
c.fillStyle=Y;c.beginPath();c.roundRect(56,50,72,76,14);c.fill();c.stroke()
c.fillStyle=GL;c.lineWidth=5;c.beginPath();c.roundRect(68,62,48,40,8);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.ellipse(80,72,4,8,.5,0,T);c.fill()
c.lineWidth=7
const body=()=>{c.beginPath();c.roundRect(14,114,124,70,14)}
c.fillStyle=Y;body();c.fill();c.save();body();c.clip();c.fillStyle=YD;c.fillRect(0,114,34,80);c.restore();body();c.stroke()
c.fillStyle='#111';for(const x of[66,100])c.beginPath(),c.ellipse(x,146,5,7,0,0,T),c.fill()
c.fillStyle='#fff';for(const x of[64,98])c.beginPath(),c.arc(x,143,2.2,0,T),c.fill()
c.fillStyle=BL;for(const x of[52,114])c.beginPath(),c.ellipse(x,160,8,4.5,0,0,T),c.fill()
c.lineWidth=5;c.beginPath();c.arc(83,152,8,.15*PI,.85*PI);c.stroke()
arm(c,[128,128],E,26,Y);arm(c,E,B,22,YD)
c.save();c.translate(...B);c.rotate(th)
if(full){c.fillStyle=DI;c.lineWidth=5;for(const[x,y,r]of[[-16,2,11],[-24,18,12],[-26,34,9],[-12,22,10]])c.beginPath(),c.arc(x,y,r,0,T),c.fill(),c.stroke()}
c.fillStyle=EX;c.lineWidth=6;c.beginPath();c.moveTo(-10,-8);c.lineTo(16,-6);c.quadraticCurveTo(32,32,-2,44);c.lineTo(-28,42);c.quadraticCurveTo(-8,30,-10,-8);c.closePath();c.fill();c.stroke()
c.fillStyle=WH;c.lineWidth=4;c.beginPath();c.moveTo(-28,42);c.lineTo(-36,46);c.lineTo(-24,48);c.lineTo(-30,52);c.lineTo(-14,48);c.closePath();c.fill();c.stroke()
c.restore();pin(c,[128,128]);pin(c,E);pin(c,B)
c.translate(0,-by);c.lineWidth=7
c.fillStyle=DI;mound(c);c.fill();c.stroke()
c.fillStyle=DD;for(const[x,y]of[[180,214],[206,200],[222,222],[194,230]])c.beginPath(),c.ellipse(x,y,5,3,0,0,T),c.fill()
for(let k=0;k<4;k++){
const t0=.44+k*.035,u=(t-t0)/.2
if(u<0||u>1)continue
const P=pose(t0),[x,y]=P.at(-20,20),yy=y+by+u*u*80,xx=x+(k-1.5)*7*u
if(yy>204)continue
c.fillStyle=DI;c.lineWidth=4;c.beginPath();c.arc(xx,yy,6-k%2,0,T);c.fill();c.stroke()
}
}
+29
View File
@@ -0,0 +1,29 @@
// smiling clipboard whose sheet peels off a twin copy that slides out beside it, gets a green check and sparkles, then poofs away
const{sin,cos,PI,max,min}=Math,T=2*PI
export const frames=24,delay=80
const WD='#a9744f',CL='#ced4da',LN='#a5d8ff',CK='#51cf66',BL='#ffa8a8',SP='#ffd43b'
const ease=u=>u<0?0:u>1?1:u*u*(3-2*u)
const sheet=c=>{
c.fillStyle='#fff';c.lineWidth=6;c.beginPath();c.roundRect(-48,-76,96,152,8);c.fill();c.stroke()
c.strokeStyle=LN;c.lineWidth=7;c.beginPath();for(const[y,w]of[[-46,60],[-28,60],[-10,40]])c.moveTo(-30,y),c.lineTo(-30+w,y);c.stroke();c.strokeStyle='#111'
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.ellipse(d*16,26,5,6.5,0,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*16-2,23,2.2,0,T),c.fill()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*28,38,7,4,0,0,T),c.fill()
c.lineWidth=4.5;c.beginPath();c.arc(0,33,7,.15*PI,.85*PI);c.stroke()
}
const star=(c,x,y,s)=>{c.fillStyle=SP;c.lineWidth=3.5;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()}
export default(c,t)=>{
const m=ease((t-.06)/.34),dx=88*m,dy=10*m,r=.14*m,sc=t<.82?1:1-ease((t-.82)/.14),ck=t<.42?0:t<.5?1.15*ease((t-.42)/.08):t<.56?1.15-.15*ease((t-.5)/.06):1
const lift=t<.06?0:min(1,(t-.06)/.06)*(t<.4?1:0)
c.fillStyle=WD;c.beginPath();c.roundRect(14,30,136,206,16);c.fill();c.stroke()
c.save();c.translate(80,138);sheet(c);c.restore()
c.fillStyle=CL;c.lineWidth=6;c.beginPath();c.roundRect(50,18,60,30,8);c.fill();c.stroke()
c.fillStyle=WD;c.beginPath();c.arc(80,26,5,0,T);c.fill();c.stroke()
if(sc>.02&&t>.06){
c.save();c.translate(80+dx,138+dy-6*lift);c.rotate(r);c.scale(sc,sc);sheet(c)
if(ck>0){c.save();c.translate(36,-62);c.scale(ck,ck);c.fillStyle=CK;c.lineWidth=6;c.beginPath();c.arc(0,0,20,0,T);c.fill();c.stroke();c.strokeStyle='#fff';c.lineWidth=7;c.beginPath();c.moveTo(-10,0);c.lineTo(-3,8);c.lineTo(11,-8);c.stroke();c.restore()}
c.restore()
}
if(t>.48&&t<.82){const p=(t-.48)/.34,s=sin(PI*p)*9;for(const[x,y,o]of[[238,128,0],[152,44,.5],[236,212,.25]])star(c,x,y,max(0,s*(1-.3*o)))}
if(t>.82&&t<.98){const p=(t-.82)/.16;c.fillStyle='#fff';c.lineWidth=4;for(let k=0;k<6;k++){const a=k*PI/3+.3,d=20+46*p,s=8*(1-p)+1;c.beginPath();c.arc(168+cos(a)*d,148+sin(a)*d,s,0,T);c.fill();c.stroke()}}
}
+23
View File
@@ -0,0 +1,23 @@
// red-handled scissors snipping their way down the dashed line of a yellow percent-off coupon, the dashes marching into the blades
const{sin,cos,PI,abs}=Math,T=2*PI
export const frames=24,delay=70
const CP='#ffd43b',CPD='#fab005',HD='#ff6b6b',BLD='#dee2e6',X=178
const tk=c=>{c.beginPath();c.moveTo(34,110);c.lineTo(222,110);c.arcTo(238,110,238,126,16);c.arc(238,170,15,-PI/2,PI/2,true);c.arcTo(238,232,222,232,16);c.lineTo(34,232);c.arcTo(18,232,18,216,16);c.arc(18,170,15,PI/2,-PI/2,true);c.arcTo(18,110,34,110,16);c.closePath()}
export default(c,t)=>{
const sn=abs(sin(4*PI*t)),h=.04+.3*sn,dy=4*(1-sn)
tk(c);c.fillStyle=CP;c.fill()
c.save();tk(c);c.clip();c.fillStyle=CPD;c.fillRect(18,216,220,20);c.restore()
tk(c);c.stroke()
for(const[w,s]of[[26,'#111'],[13,'#fff']]){c.lineWidth=w;c.strokeStyle=s;c.beginPath();c.moveTo(130,138);c.lineTo(76,204);c.moveTo(94,145);c.arc(82,145,12,0,T);c.moveTo(134,198);c.arc(122,198,12,0,T);c.stroke()}
c.strokeStyle='#111';c.fillStyle='#fff';c.lineWidth=5;c.beginPath();for(let k=0;k<10;k++){const r=k%2?8:19,a=k*PI/5-PI/2;c.lineTo(209+cos(a)*r,172+sin(a)*r)}c.closePath();c.fill();c.stroke()
c.setLineDash([12,10]);c.lineDashOffset=t*66;c.lineWidth=5;c.beginPath();c.moveTo(X,116);c.lineTo(X,228);c.stroke();c.setLineDash([])
c.translate(X,80+dy)
for(const s of[1,-1]){
c.save();c.rotate(s*h)
for(const[w,st]of[[18,'#111'],[9,HD]])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.moveTo(0,0),c.lineTo(s*14,-30),c.moveTo(s*20+15,-48),c.arc(s*20,-48,15,0,T),c.stroke()
c.strokeStyle='#111';c.fillStyle=BLD;c.lineWidth=5;c.beginPath();c.moveTo(-s*1,-8);c.quadraticCurveTo(-s*10,28,0,62);c.quadraticCurveTo(s*9,26,s*6,-6);c.closePath();c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=3;c.beginPath();c.moveTo(-s*2,6);c.quadraticCurveTo(-s*4,26,-s*1,40);c.stroke()
c.restore()
}
c.strokeStyle='#111';c.fillStyle='#ffd43b';c.lineWidth=4;c.beginPath();c.arc(0,0,6,0,T);c.fill();c.stroke()
}
+29
View File
@@ -0,0 +1,29 @@
// smiling cardboard box drifting down under a striped parachute, swaying gently as little clouds float up past it
const{sin,PI,round}=Math,T=2*PI
export const frames=12,delay=110
const P=['#4dabf7','#fff','#ff6b6b','#fff','#4dabf7'],BX='#e0a96d',BXD='#c08552',TP='#ffd8a8',BL='#ff8787'
const cloud=(c,x,y,s)=>{const b=[[-14*s,3*s,10*s],[2*s,-4*s,13*s],[17*s,3*s,9*s]];c.lineWidth=13;for(const[a,d,r]of b)c.beginPath(),c.arc(x+a,y+d,r,0,T),c.stroke();c.fillStyle='#fff';for(const[a,d,r]of b)c.beginPath(),c.arc(x+a,y+d,r,0,T),c.fill();c.lineWidth=7}
const can=c=>{c.beginPath();c.moveTo(-98,0);c.bezierCurveTo(-98,-74,98,-74,98,0);for(let k=0;k<5;k++){const x=98-k*39.2;c.quadraticCurveTo(x-19.6,16,x-39.2,0)}c.closePath()}
export default(c,t)=>{
const a=.13*sin(T*t),b=round(4*sin(2*T*t))
for(const[x,o]of[[32,0],[222,.5]]){const p=(t+o)%1,s=sin(PI*p);if(s>.08)cloud(c,x,226-p*190,.8*s)}
c.strokeStyle='#111'
c.save();c.translate(128,24+b);c.rotate(a);c.translate(0,48)
const L=[[-96,2],[-20,14],[20,14],[96,2]],K=[[-30,104],[-14,104],[14,104],[30,104]]
for(const[lw,s]of[[7,'#111'],[3,'#fff']]){c.lineWidth=lw;c.strokeStyle=s;c.beginPath();L.forEach(([x,y],k)=>{c.moveTo(x,y);c.lineTo(...K[k])});c.stroke()}
c.strokeStyle='#111';c.lineWidth=7
c.save();can(c);c.clip()
const gx=k=>(-98+k*39.2)*1.3
for(let k=0;k<5;k++){c.fillStyle=P[k];c.beginPath();c.moveTo(0,-110);c.lineTo(gx(k),30);c.lineTo(gx(k+1),30);c.closePath();c.fill()}
c.lineWidth=4;c.beginPath();for(let k=1;k<5;k++)c.moveTo(0,-110),c.lineTo(gx(k),30);c.stroke()
c.restore();c.lineWidth=7;can(c);c.stroke()
c.fillStyle='#fff';c.beginPath();c.ellipse(-50,-36,12,5,-.6,0,T);c.fill()
c.fillStyle=BXD;c.beginPath();c.moveTo(-40,108);c.lineTo(-30,98);c.lineTo(30,98);c.lineTo(40,108);c.closePath();c.fill();c.stroke()
c.fillStyle=BX;c.beginPath();c.roundRect(-44,104,88,60,8);c.fill();c.stroke()
c.fillStyle=TP;c.lineWidth=5;c.beginPath();c.rect(-10,104,20,22);c.fill();c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.ellipse(d*17,134,5,6.5,0,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*17-2,131,2.2,0,T),c.fill()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*28,146,7,4,0,0,T),c.fill()
c.lineWidth=4.5;c.beginPath();c.arc(0,141,7,.15*PI,.85*PI);c.stroke()
c.restore()
}
+27
View File
@@ -0,0 +1,27 @@
// grumpy gray storm cloud with an anger mark, blue rain pouring down and a yellow lightning bolt cracking out as it shudders
const{sin,cos,PI,min}=Math,T=2*PI
export const frames=16,delay=80
const CL='#ced4da',CD='#adb5bd',RN='#4dabf7',BT='#ffd43b',AN='#ff6b6b'
const PF=[[-64,8,34],[-30,-18,42],[18,-30,46],[60,-4,38],[-20,16,40],[28,14,40]]
export default(c,t,i)=>{
const z=i==5||i==6||i==12,sh=z?(i%2?4:-4):0,y=98+3*sin(t*T)
for(let k=0;k<7;k++){
const p=(t*2+k*.43)%1,x=56+k*24+(k%2)*4,yy=y+30+p*112,s=min(1,(1-p)*5)
if(s<=0)continue
c.save();c.translate(x-p*8,yy);c.rotate(.1);c.scale(s,s);c.fillStyle=RN;c.lineWidth=4;c.beginPath();c.moveTo(0,-14);c.quadraticCurveTo(10,3,0,8);c.quadraticCurveTo(-10,3,0,-14);c.fill();c.stroke();c.restore()
}
if(z){
c.fillStyle=BT;c.lineWidth=5;c.beginPath();for(const[x,yy]of[[134,120],[108,180],[128,180],[108,240],[160,166],[138,166],[156,120]])c.lineTo(x+sh,yy);c.closePath();c.fill();c.stroke()
for(const[a,r]of[[-2.6,0],[-.5,1],[2.2,2]]){const x=118+cos(a)*40+sh,yy=206+sin(a)*24;for(const[w,s]of[[10,'#111'],[4,BT]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(x,yy),c.lineTo(x+cos(a)*14,yy+sin(a)*10),c.stroke()}
c.strokeStyle='#111'
}
c.translate(128+sh,y)
c.lineWidth=14;for(const[a,d,r]of PF)c.beginPath(),c.arc(a,d,r,0,T),c.stroke()
c.fillStyle=CL;for(const[a,d,r]of PF)c.beginPath(),c.arc(a,d,r,0,T),c.fill()
c.save();c.beginPath();for(const[a,d,r]of PF)c.moveTo(a+r,d),c.arc(a,d,r,0,T);c.clip();c.fillStyle=CD;c.beginPath();c.ellipse(0,64,120,34,0,0,T);c.fill();c.restore()
c.strokeStyle='#fff';c.lineWidth=6;c.beginPath();c.arc(18,-30,36,PI*1.15,PI*1.45);c.stroke();c.strokeStyle='#111'
c.lineWidth=6;for(const d of[-1,1])c.beginPath(),c.moveTo(d*36,-14),c.lineTo(d*14,-4),c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(d*24,6,z?4:6,0,T),c.fill()
c.lineWidth=5;c.beginPath();c.arc(0,34,12,PI*1.15,PI*1.85);c.stroke()
c.save();c.translate(58,-34);c.rotate(.2*sin(2*T*t));for(const[w,s]of[[11,'#111'],[5,AN]]){c.lineWidth=w;c.strokeStyle=s;c.beginPath();for(const r of[0,1,2,3]){const a=r*PI/2+PI/4;c.moveTo(cos(a)*7+cos(a+PI/4)*10,sin(a)*7+sin(a+PI/4)*10);c.quadraticCurveTo(cos(a)*7,sin(a)*7,cos(a)*7+cos(a-PI/4)*10,sin(a)*7+sin(a-PI/4)*10)}c.stroke()}c.restore()
}
+38
View File
@@ -0,0 +1,38 @@
// sad chocolate chip cookie trembles, a crack zigzags down it, it splits in two crying while crumbs tumble off, then it pulls itself back together
const{sin,cos,PI,min,max}=Math,T=2*PI
export const frames=24,delay=80
const CK='#e0a96d',CKD='#c98c4f',CH='#5c3d2e',BL='#ffa8a8',TR='#74c0fc'
const C=[[0,-76],[-9,-56],[8,-36],[-7,-14],[9,10],[-7,34],[8,56],[0,76]]
const CH0=[[-42,-34],[30,-46],[50,6],[-52,18],[-24,50],[26,50],[-8,-60],[40,-22]]
const io=u=>u*u*(3-2*u),cl=u=>min(1,max(0,u))
const body=c=>{c.beginPath();for(let a=0;a<=T+.01;a+=.12){const r=76+3*sin(a*7);c.lineTo(cos(a)*r,sin(a)*r)}c.closePath()}
const crack=c=>{c.beginPath();for(const[x,y]of C)c.lineTo(x,y)}
export default(c,t,i)=>{
const tr=t>.04&&t<.32?(i%2?2:-2):0,cp=t<.3?cl((t-.1)/.2):cl(1-(t-.9)/.1),sp=t<.32?0:t<.46?1-(1-(t-.32)/.14)**3:t<.78?1:t<.9?1-io((t-.78)/.12):0
for(const d of[-1,1]){
c.save();c.translate(128+tr+d*14*sp,126+5*sp);c.translate(0,84);c.rotate(d*.2*sp);c.translate(0,-84)
if(sp>0){c.beginPath();for(const[x,y]of[[0,-110],...C,[0,110],[d*200,110],[d*200,-110]])c.lineTo(x,y);c.clip()}
else if(d>0){c.restore();continue}
body(c);c.fillStyle=CK;c.fill()
c.save();body(c);c.clip();c.fillStyle=CKD;c.beginPath();c.arc(0,0,82,0,T);c.arc(-10,-12,78,0,T,true);c.fill();c.restore()
c.lineWidth=7;body(c);c.stroke()
c.fillStyle=CH;for(const[x,y]of CH0)c.beginPath(),c.ellipse(x,y,7,6,x,0,T),c.fill()
c.lineWidth=4.5;for(const e of[-1,1])c.beginPath(),c.moveTo(e*38,-20),c.lineTo(e*17,-27),c.stroke()
c.fillStyle='#111';for(const e of[-1,1])c.beginPath(),c.arc(e*26,-6,6,0,T),c.fill()
c.fillStyle='#fff';for(const e of[-1,1])c.beginPath(),c.arc(e*26-2,-8,2.2,0,T),c.fill()
c.lineWidth=5;c.beginPath();c.arc(0,36,13,PI*1.2,PI*1.8);c.stroke()
c.fillStyle=BL;for(const e of[-1,1])c.beginPath(),c.ellipse(e*44,12,8,4.5,0,0,T),c.fill()
if(sp>.5)for(const o of[0,.5]){const p=(t*4+o)%1,yy=2+p*36;c.fillStyle=TR;c.lineWidth=3;c.beginPath();c.moveTo(d*30,yy-8);c.quadraticCurveTo(d*30+6,yy+3,d*30,yy+5);c.quadraticCurveTo(d*30-6,yy+3,d*30,yy-8);c.fill();c.stroke()}
if(sp>0){c.lineWidth=6;crack(c);c.stroke()}
c.restore()
}
if(sp==0&&cp>0){
const L=C.reduce((s,[x,y],k)=>k?s+Math.hypot(x-C[k-1][0],y-C[k-1][1]):0,0)
c.save();c.translate(128+tr,126);c.lineWidth=6;c.setLineDash([L*cp,999]);c.lineDashOffset=t<.5?0:-L*(1-cp);crack(c);c.stroke();c.restore()
}
const u=(t-.33)/.5
if(u>0&&u<1)for(let k=1;k<7;k++){
const[cx,cy]=C[k],d=k%2?1:-1,x=128+cx+d*(18+k*7)*u*1.4,y=126+cy-(34+k*5%17)*u*1.2+280*u*u,r=(4+k%3*1.5)*min(1,(1-u)*5)
if(y<230&&r>.5){c.fillStyle=k%2?CK:CKD;c.lineWidth=3;c.beginPath();c.moveTo(x-r,y);c.lineTo(x-r*.3,y-r);c.lineTo(x+r,y-r*.4);c.lineTo(x+r*.6,y+r);c.closePath();c.fill();c.stroke()}
}
}
+36
View File
@@ -0,0 +1,36 @@
// computer monitor glitching out, RGB bars tearing across it and slices jumping sideways, spiral dizzy eyes and little stars circling overhead
const{sin,cos,PI,abs}=Math,T=2*PI
export const frames=16,delay=80
const CS='#b197fc',SC='#e7f5ff',G=['#ff6b6b','#51cf66','#4dabf7','#ffd43b','#f783ac','#3bc9db'],BL='#ffa8a8',GS='0011010000111010'
const R=n=>abs(sin(n*127.1+311.7)*43758.5)%1
const star=(c,x,y,s)=>{c.fillStyle='#ffd43b';c.lineWidth=4;c.beginPath();for(let k=0;k<10;k++){const r=k%2?s*.45:s,a=k*PI/5-PI/2;c.lineTo(x+cos(a)*r,y+sin(a)*r)}c.closePath();c.fill();c.stroke()}
const face=(c,t,col,o)=>{
c.strokeStyle=col;c.lineWidth=5
for(const d of[-1,1]){c.beginPath();for(let a=0;a<4.4*PI;a+=.3){const r=1+a*1.15,b=(a+t*T*2)*d;c.lineTo(128+d*32+o+cos(b)*r,118+sin(b)*r)}c.stroke()}
c.beginPath();for(let x=-22;x<=22;x+=2)c.lineTo(128+x+o,154+4*sin(x/6+t*T*2));c.stroke()
}
const M=(c,t,i,g)=>{
c.strokeStyle='#111';c.lineWidth=7
c.fillStyle='#868e96';c.beginPath();c.roundRect(110,194,36,26,4);c.fill();c.stroke()
c.fillStyle=CS;c.beginPath();c.roundRect(70,214,116,22,11);c.fill();c.stroke()
c.beginPath();c.roundRect(22,52,212,148,24);c.fill();c.stroke()
c.fillStyle=g?'#ff6b6b':'#51cf66';c.lineWidth=4;c.beginPath();c.arc(210,190,4.5,0,T);c.fill();c.stroke()
c.save();c.beginPath();c.roundRect(40,70,176,112,12);c.clip()
c.fillStyle=SC;c.fillRect(0,60,256,130)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*58,140,9,5,0,0,T),c.fill()
if(g)face(c,t,'#ff6b6b',-5),face(c,t,'#4dabf7',5)
face(c,t,'#111',0)
if(g)for(let n=0;n<5;n++)c.fillStyle=G[(i+n)%6],c.fillRect(40+R(i+n*13)*90,72+R(i*9+n)*104,30+R(i*7+n)*110,4+R(i*3+n*7)*10)
c.restore()
c.strokeStyle='#111';c.lineWidth=5;c.beginPath();c.roundRect(40,70,176,112,12);c.stroke()
c.strokeStyle='#fff';c.lineWidth=6;c.beginPath();c.moveTo(54,96);c.lineTo(54,84);c.lineTo(66,84);c.stroke()
}
export default(c,t,i)=>{
const g=GS[i]>0
const st=b=>{for(let k=0;k<3;k++){const a=t*T+k*T/3,z=sin(a);if(z<0==b)star(c,128+cos(a)*76,30+z*10,14+3*z)}}
st(1)
if(!g)M(c,t,i,0)
else{const Y=[0,64,92,118,140,166,196,256];for(let k=0;k<7;k++){const dx=R(i*5+k)>.45?(R(i*11+k)-.5)*40:0;c.save();c.beginPath();c.rect(0,Y[k],256,Y[k+1]-Y[k]);c.clip();c.translate(dx,0);M(c,t,i,1);c.restore()}}
c.strokeStyle='#111'
st(0)
}
+35
View File
@@ -0,0 +1,35 @@
// spoiled milk carton swaying woozily with spinning spiral eyes and a wobbly mouth, green stink lines wafting up and a fly buzzing round
const{sin,cos,PI}=Math,T=2*PI
export const frames=16,delay=90
const BU='#74c0fc',BUD='#4dabf7',GR='#a9e34b',SB='#c0eb75',FLY='#495057',DR='#a5d8ff'
const spiral=(c,x,y,a)=>{c.beginPath();for(let k=0;k<=34;k++){const u=k*.32,r=1+u*1.15;c.lineTo(x+cos(u+a)*r,y+sin(u+a)*r)}c.stroke()}
export default(c,t,i)=>{
const r=.07*sin(T*t),sk=.05*sin(2*T*t+1)
for(const[x,o,h]of[[36,0,70],[220,.5,70]]){
const p=(t+o)%1,y0=150-36*p,L=h*(1-.3*p)
c.save();c.beginPath();c.rect(0,0,256,160);c.clip()
for(const[w,s]of[[12,'#111'],[5,GR]]){c.lineWidth=w;c.strokeStyle=s;c.beginPath();for(let k=0;k<=12;k++){const y=y0-k/12*L;c.lineTo(x+7*sin(y*.12+T*t*2),y)}c.stroke()}
c.restore()
}
c.strokeStyle='#111';c.lineWidth=7
c.save();c.translate(128,238);c.rotate(r);c.transform(1,0,sk,1,0,0);c.translate(-128,-238)
c.fillStyle=BU;c.beginPath();c.roundRect(90,66,76,20,6);c.fill();c.stroke()
c.beginPath();c.moveTo(64,124);c.lineTo(88,84);c.lineTo(168,84);c.lineTo(192,124);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.roundRect(64,122,128,114,10);c.fill();c.stroke()
c.save();c.beginPath();c.roundRect(64,122,128,114,10);c.clip()
c.fillStyle=BUD;c.beginPath();c.moveTo(60,240);c.lineTo(60,210);for(let x=60;x<=196;x+=4)c.lineTo(x,210+5*sin(x*.09+T*t));c.lineTo(196,240);c.closePath();c.fill();c.lineWidth=5;c.stroke()
c.restore();c.lineWidth=7;c.beginPath();c.roundRect(64,122,128,114,10);c.stroke()
c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.ellipse(128,104,10,8,0,0,T);c.fill();c.stroke()
c.lineWidth=4;for(const[x,d]of[[104,1],[152,-1]])spiral(c,x,152,d*T*t*2)
c.fillStyle=SB;for(const x of[88,168])c.beginPath(),c.ellipse(x,174,9,5,0,0,T),c.fill()
c.lineWidth=4.5;c.beginPath();for(let k=0;k<=8;k++){const x=110+k*4.5;c.lineTo(x,184+(k%2?-3:3)*(i%2?1:-1))}c.stroke()
c.fillStyle=SB;c.lineWidth=3.5;c.beginPath();c.moveTo(130,185);c.quadraticCurveTo(132,200,140,198);c.quadraticCurveTo(146,194,140,184);c.fill();c.stroke()
c.fillStyle=DR;c.lineWidth=3.5;const dy=(t*2%1)*14;c.beginPath();c.moveTo(178,128+dy);c.quadraticCurveTo(186,140+dy,178,144+dy);c.quadraticCurveTo(170,140+dy,178,128+dy);c.fill();c.stroke()
c.restore()
const fa=T*t,fx=128+84*cos(fa),fy=42+14*sin(2*fa),fl=-sin(fa)>0?1:-1
c.save();c.translate(fx,fy);c.scale(fl,1)
c.fillStyle='#fff';c.lineWidth=3;for(const d of[-1,1])c.beginPath(),c.ellipse(d*3-1,-8,5,9,d*.5+(i%2?.3:-.3)*d,0,T),c.fill(),c.stroke()
c.fillStyle=FLY;c.lineWidth=3;c.beginPath();c.ellipse(0,0,9,6,0,0,T);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.arc(6,-1,2.5,0,T);c.fill()
c.restore()
}
+37
View File
@@ -0,0 +1,37 @@
// happy red balloon bobbing, panics, pops into a burst of rubber bits, the sad scrap and its droopy string flop to the ground, then it puffs back up
const{sin,cos,PI,min}=Math,T=2*PI
export const frames=24,delay=80
const RD='#ff6b6b',BL='#ffa8a8',BY='#ffd43b',TR='#74c0fc'
const E=u=>u<0?0:u>1?1:u*u*(3-2*u)
const two=(c,w,col,f)=>{for(const[l,s]of[[w,'#111'],[w-6,col]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),f(),c.stroke();c.strokeStyle='#111'}
export default(c,t,i)=>{
let x=128,y=96,rx=58,ry=68,b=0,m=0,f=0,ph=0
if(i<9){y=96+4*sin(i/9*T);ph=i/9*T;if(i>6)m=1,x+=i%2?5:-5,rx+=5,ry+=4}
else if(i<19){const q=min(1,((i-9)/4)**2);x=128-24*q;y=100+88*q;rx=52;ry=32;b=.13;m=i<11?1:2;f=q;if(i==13)rx=60,ry=24;if(i==14)rx=49,ry=35}
else{const u=E((i-18)/6);x=104+24*u;y=188-92*u;rx=52+6*u;ry=32+36*u;b=.13*(1-u);m=u<.5?2:0;f=1-u}
const k=rx/58,K=y+ry
if(i==9){c.save();c.translate(128,96);c.beginPath();for(let n=0;n<24;n++){const r=n%2?50:82,a=n*PI/12;c.lineTo(cos(a)*r,sin(a)*r)}c.closePath();c.fillStyle=BY;c.fill();c.stroke();c.restore()}
if(i==10)for(let n=0;n<12;n++){const a=n*T/12+.2;two(c,12,BY,()=>{c.moveTo(128+cos(a)*62,96+sin(a)*62);c.lineTo(128+cos(a)*84,96+sin(a)*84)})}
if(i>6&&i<9)for(const d of[-1,1])two(c,10,'#fff',()=>{for(const o of[-16,16])c.moveTo(x+d*(rx+14),y+o),c.lineTo(x+d*(rx+26),y+o)})
two(c,9,'#fff',()=>{for(let n=0;n<=14;n++){const u=n/14,ax=x+9*sin(u*5+ph)*u,ay=K+8+u*60,gx=x+8+u*100,gy=K+8+3*sin(u*16)*u;c.lineTo(ax+(gx-ax)*f,ay+(gy-ay)*f)}})
c.lineWidth=7;c.fillStyle=RD;c.beginPath()
for(let a=0;a<T;a+=.1){const r=1+b*sin(a*7+1)*(.7+.3*sin(a*3));c.lineTo(x+cos(a)*rx*r*(1-.1*Math.max(0,sin(a))),y+sin(a)*ry*r)}
c.closePath();c.fill();c.stroke()
c.lineWidth=4;c.beginPath();c.moveTo(x-7*k,K+9);c.lineTo(x+7*k,K+9);c.lineTo(x,K-3);c.closePath();c.fill();c.stroke()
if(b<.08){c.fillStyle='#fff';c.beginPath();c.ellipse(x-rx*.45,y-ry*.45,rx*.14,ry*.2,-.5,0,T);c.fill()}
c.save();c.translate(x,y+(m==2?-2:0));c.scale(k,k);c.fillStyle='#111';c.strokeStyle='#111'
if(m==1){
c.lineWidth=4;c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*18,-8,10,0,T),c.fill(),c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(d*18,-7,4,0,T),c.fill()
c.beginPath();c.ellipse(0,18,7,9,0,0,T);c.fill()
}else{
for(const d of[-1,1])c.beginPath(),c.arc(d*18,-6,6.5,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*18-2,-8,2.2,0,T),c.fill()
c.lineWidth=5;c.beginPath();m?c.arc(0,20,10,1.15*PI,1.85*PI):c.arc(0,6,11,.15*PI,.85*PI);c.stroke()
if(m==2){c.lineWidth=4.5;for(const d of[-1,1])c.beginPath(),c.moveTo(d*9,-22),c.lineTo(d*27,-16),c.stroke()}
}
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*34,8,8,5,0,0,T),c.fill()
if(i>14&&i<19){c.fillStyle=TR;c.lineWidth=3/k;const ty=-2+(i-15)*7;c.beginPath();c.moveTo(-18,ty);c.quadraticCurveTo(-11,ty+10,-18,ty+12);c.quadraticCurveTo(-25,ty+10,-18,ty);c.fill();c.stroke()}
c.restore()
if(i>8&&i<13)for(let n=0;n<6;n++){const a=n*T/6+.4,d=60+(i-9)*26;c.save();c.translate(128+cos(a)*d,96+sin(a)*d+(i-9)**2*5);c.rotate(a+i);two(c,10,RD,()=>{c.moveTo(-9,0);c.quadraticCurveTo(-4,-8,1,0);c.quadraticCurveTo(5,7,10,-1)});c.restore()}
}
+13
View File
@@ -0,0 +1,13 @@
// empty dashed star outline waiting to be filled, its dashes marching round as it breathes, sparkles twinkling on and off around it
const{sin,cos,PI,max,hypot}=Math,T=2*PI
export const frames=16,delay=80
const SY='#ffd43b',R=104,r=46,P=10*hypot(R-r*cos(PI/5),r*sin(PI/5))/20
const sp=(c,x,y,s)=>{if(s<1.5)return;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()}
export default(c,t)=>{
for(const[x,y,o,s]of[[46,50,0,16],[210,48,.35,14],[30,196,.6,12],[226,196,.15,13],[128,232,.8,11],[128,146,.45,15]])sp(c,x,y,s*max(0,sin(PI*((t*2+o)%1))))
c.save();c.translate(128,138);const k=1+.04*sin(t*T*2);c.scale(k,k);c.rotate(.04*sin(t*T))
c.beginPath();for(let n=0;n<10;n++){const q=n%2?r:R,a=n*PI/5-PI/2;c.lineTo(cos(a)*q,sin(a)*q)}c.closePath()
c.setLineDash([P*.55,P*.45]);c.lineDashOffset=-t*P*2
for(const[w,s]of[[17,'#111'],[8,SY]])c.lineWidth=w,c.strokeStyle=s,c.stroke()
c.restore()
}
+38
View File
@@ -0,0 +1,38 @@
// fridge door swings open to show nothing but one lonely shivering egg, the light inside flickering, then it shuts again
const{sin,cos,PI}=Math,T=2*PI
export const frames=24,delay=90
const BD='#99e9f2',LN='#e3fafc',LIT='#fff3bf',DIM='#5c6670',SH='#d0ebff',BY='#ffd43b',BL='#ffa8a8',FL='000101110110101111010000'
const E=u=>u<0?0:u>1?1:u*u*(3-2*u)
export default(c,t,i)=>{
const th=PI*.68*(E((t-.04)/.16)-E((t-.76)/.14)),k=cos(th),op=th>.05,on=op&&FL[i]>0,X=90,W=112
c.fillStyle='#495057';for(const x of[100,176])c.beginPath(),c.roundRect(x,226,18,16,4),c.fill(),c.stroke()
c.fillStyle=BD;c.beginPath();c.roundRect(X,14,W,220,16);c.fill();c.stroke()
if(op){
c.fillStyle=on?LIT:DIM;c.beginPath();c.roundRect(96,84,100,142,8);c.fill();c.lineWidth=5;c.stroke()
if(on){c.lineWidth=4;c.fillStyle=BY;c.beginPath();c.arc(146,88,9,0,PI);c.fill();c.stroke()
for(const a of[.5,1.1,PI/2,PI-1.1,PI-.5])for(const[w,s]of[[8,'#111'],[3,BY]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(146+cos(a)*16,88+sin(a)*16),c.lineTo(146+cos(a)*24,88+sin(a)*24),c.stroke()
c.strokeStyle='#111'}
c.lineWidth=4;c.fillStyle=SH;for(const y of[132,192])c.beginPath(),c.roundRect(96,y,100,8,3),c.fill(),c.stroke()
const j=i%2?1.5:-1.5
c.lineWidth=5;c.fillStyle='#fff';c.beginPath();c.ellipse(146+j,170,18,23,0,0,T);c.fill();c.stroke()
c.fillStyle='#fff';c.globalAlpha=.8;c.beginPath();c.ellipse(139+j,160,4,6,-.4,0,T);c.fill();c.globalAlpha=1
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(146+j+d*7,170,2.8,0,T),c.fill()
c.lineWidth=3;c.beginPath();c.arc(146+j,182,4.5,1.2*PI,1.8*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(146+j+d*12,177,3.5,2,0,0,T),c.fill()
}
c.lineWidth=7;c.strokeStyle='#111'
const fx=X+W*k,dy=6*sin(th)
c.fillStyle=k>0?BD:LN;c.beginPath();c.moveTo(X,80);c.lineTo(fx,80-dy);c.lineTo(fx,232+dy);c.lineTo(X,232);c.closePath();c.fill();c.stroke()
if(k>.25)for(const[w,s]of[[13,'#111'],[5,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(X+(W-16)*k,100),c.lineTo(X+(W-16)*k,144),c.stroke()
if(k<-.2){c.lineWidth=4;c.strokeStyle='#111';c.fillStyle=SH;for(const y of[118,176])c.beginPath(),c.moveTo(X,y),c.lineTo(fx+6,y+(y>150?3:-3)*sin(th)),c.lineTo(fx+6,y+20),c.lineTo(X,y+20),c.closePath(),c.fill(),c.stroke()}
c.strokeStyle='#111';c.lineWidth=7;c.beginPath();c.moveTo(X,78);c.lineTo(X+W,78);c.stroke()
for(const[w,s]of[[13,'#111'],[5,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(186,30),c.lineTo(186,62),c.stroke()
c.strokeStyle='#111';c.fillStyle='#111'
const ly=op?4:0
for(const d of[-1,1])c.beginPath(),c.arc(146+d*20,44+ly,6,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(144+d*20,42+ly,2,0,T),c.fill()
c.lineWidth=4.5;for(const d of[-1,1])c.beginPath(),c.moveTo(146+d*11,30),c.lineTo(146+d*27,34),c.stroke()
c.lineWidth=5;c.beginPath();op?c.ellipse(146,62,5,4,0,0,T):c.arc(146,66,8,1.2*PI,1.8*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(146+d*36,56,7,4,0,0,T),c.fill()
if(op){c.fillStyle='#a5d8ff';c.lineWidth=3;c.beginPath();c.moveTo(106,32);c.quadraticCurveTo(113,43,106,45);c.quadraticCurveTo(99,43,106,32);c.fill();c.stroke()}
}
+29
View File
@@ -0,0 +1,29 @@
// inbox tray at zero turned into a tiny island: palm tree swaying, a cool sun in shades, the tray smiling with relaxed closed eyes
const{sin,PI}=Math,T=2*PI
export const frames=16,delay=100
const TY='#b197fc',TD='#7950f2',WA='#74c0fc',SA='#ffe066',TK='#c08457',LF='#51cf66',CO='#8b5a3c',SU='#ffd43b',SR='#ffa94d',BL='#ffa8a8'
export default(c,t)=>{
c.save();c.translate(204,52+3*sin(t*T));c.save();c.rotate(t*T/8)
c.fillStyle=SR;c.lineWidth=4;for(let k=0;k<8;k++)c.save(),c.rotate(k*PI/4),c.beginPath(),c.roundRect(30,-5,13,10,5),c.fill(),c.stroke(),c.restore()
c.restore();c.fillStyle=SU;c.lineWidth=6;c.beginPath();c.arc(0,0,25,0,T);c.fill();c.stroke()
c.fillStyle='#343a40';c.lineWidth=3;for(const d of[-1,1])c.beginPath(),c.roundRect(d>0?2:-17,-8,15,10,4),c.fill(),c.stroke()
c.beginPath();c.moveTo(-2,-5);c.lineTo(2,-5);c.stroke()
c.lineWidth=3.5;c.beginPath();c.arc(0,6,7,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*15,8,4,2.5,0,0,T),c.fill()
c.restore()
c.lineWidth=7;c.fillStyle=TD;c.beginPath();c.moveTo(54,140);c.lineTo(202,140);c.lineTo(226,172);c.lineTo(30,172);c.closePath();c.fill();c.stroke()
c.fillStyle=WA;c.beginPath();c.moveTo(62,148);c.lineTo(194,148);c.lineTo(212,172);c.lineTo(44,172);c.closePath();c.fill()
c.strokeStyle='#fff';c.lineWidth=4;for(const[x,o]of[[70,0],[184,.5]]){const w=3*sin(t*T*2+o*T);c.beginPath();c.arc(x+w,166,6,PI*1.1,PI*1.9);c.arc(x+12+w,166,6,PI*1.1,PI*1.9);c.stroke()}
c.strokeStyle='#111';c.lineWidth=6;c.fillStyle=SA;c.beginPath();c.ellipse(128,170,50,20,0,PI,T);c.fill();c.stroke()
c.save();c.translate(132,160);c.rotate(.05*sin(t*T))
for(const[w,s]of[[20,'#111'],[11,TK]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(0,0),c.quadraticCurveTo(8,-44,-22,-76),c.stroke()
c.strokeStyle='#111';c.lineWidth=3;c.beginPath();for(const[x,y]of[[1,-16],[2,-34],[-4,-52]])c.moveTo(x-6,y+1),c.lineTo(x+5,y-1);c.stroke()
c.translate(-22,-78)
;[-2.75,-2.15,-1.35,-.65,-.05].forEach((a,k)=>{c.save();c.rotate(a+.09*sin(t*T*2+k));c.fillStyle=LF;c.lineWidth=5;c.beginPath();c.moveTo(0,0);c.quadraticCurveTo(28,-20,58,4);c.quadraticCurveTo(44,0,40,10);c.quadraticCurveTo(34,0,26,6);c.quadraticCurveTo(14,-4,0,0);c.fill();c.stroke();c.restore()})
c.fillStyle=CO;c.lineWidth=4;for(const[x,y]of[[-6,8],[7,9]])c.beginPath(),c.arc(x,y,7,0,T),c.fill(),c.stroke()
c.restore()
c.lineWidth=7;c.fillStyle=TY;c.beginPath();c.moveTo(30,172);c.lineTo(82,172);c.lineTo(94,190);c.lineTo(162,190);c.lineTo(174,172);c.lineTo(226,172);c.lineTo(212,232);c.lineTo(44,232);c.closePath();c.fill();c.stroke()
c.lineWidth=5;for(const d of[-1,1])c.beginPath(),c.arc(128+d*24,212,7,1.15*PI,1.85*PI),c.stroke()
c.beginPath();c.arc(128,214,8,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,218,8,5,0,0,T),c.fill()
}
+26
View File
@@ -0,0 +1,26 @@
// glass cookie jar with nothing but crumbs at the bottom, its lid rattling and hopping, the jar peering down sadly
const{sin,cos,PI,abs}=Math,T=2*PI
export const frames=16,delay=70
const GL='#e7f5ff',GS='#a5d8ff',LD='#ff8787',LK='#ffd43b',CR='#e0a96d',CH='#8b5a3c',BL='#ffa8a8'
const CB=[[84,224,8],[104,229,6],[122,225,9],[146,229,6],[164,224,8],[182,229,5],[134,231,4],[94,231,4]]
const body=c=>{c.beginPath();c.moveTo(74,96);c.quadraticCurveTo(48,100,48,132);c.lineTo(48,208);c.quadraticCurveTo(48,236,76,236);c.lineTo(180,236);c.quadraticCurveTo(208,236,208,208);c.lineTo(208,132);c.quadraticCurveTo(208,100,182,96);c.closePath()}
export default(c,t,i)=>{
const h=abs(sin(t*T*2)),ly=-14*h,lr=.13*sin(t*T*6)*h,sh=(i%2?1.5:-1.5)*h
c.translate(sh,0)
body(c);c.fillStyle=GL;c.fill()
CB.forEach(([x,y,r],k)=>{const dy=-4*h*abs(sin(k*1.7+t*T*4));c.save();c.translate(x,y+dy);c.rotate(k+dy/4);c.fillStyle=CR;c.lineWidth=3;c.beginPath();for(let n=0;n<6;n++){const a=n*T/6,q=r*(n%2?.75:1);c.lineTo(cos(a)*q,sin(a)*q)}c.closePath();c.fill();c.stroke();if(r>6)c.fillStyle=CH,c.beginPath(),c.arc(1,-1,2,0,T),c.fill();c.restore()})
c.lineWidth=7;body(c);c.stroke()
c.strokeStyle='#fff';c.lineWidth=8;c.beginPath();c.moveTo(66,128);c.lineTo(66,196);c.stroke();c.lineWidth=6;c.beginPath();c.moveTo(66,210);c.lineTo(66,214);c.stroke()
c.strokeStyle='#111';c.fillStyle=GS;c.lineWidth=6;c.beginPath();c.roundRect(68,78,120,22,8);c.fill();c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+d*24,146,6.5,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(126+d*24,148,2.2,0,T),c.fill()
c.lineWidth=4.5;for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*14,128),c.lineTo(128+d*32,133),c.stroke()
c.lineWidth=5;c.beginPath();c.arc(128,176,11,1.2*PI,1.8*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,162,8,5,0,0,T),c.fill()
c.save();c.translate(128,70+ly);c.rotate(lr)
c.fillStyle=LD;c.lineWidth=7;c.beginPath();c.roundRect(-16,-38,32,22,10);c.fill();c.stroke()
c.beginPath();c.roundRect(-70,-22,140,30,13);c.fill();c.stroke()
c.fillStyle=LK;c.lineWidth=4;c.beginPath();c.arc(0,-28,4.5,0,T);c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();c.moveTo(-54,-12);c.lineTo(-30,-12);c.stroke();c.restore()
if(h>.5)for(const d of[-1,1])for(const[w,s]of[[10,'#111'],[4,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(128+d*82,56+ly),c.lineTo(128+d*96,48+ly),c.moveTo(128+d*84,70+ly),c.lineTo(128+d*100,70+ly),c.stroke()
}
+31
View File
@@ -0,0 +1,31 @@
// a wrapped candy as a progress bar: peppermint stripes scroll in and fill it up, a shine sweeps across when it's full, then it drains and starts again
const{sin,PI,min,max}=Math,T=2*PI
export const frames=24,delay=70
const ST='#f06595',TK='#ffdeeb',WR='#ffd43b',WD='#fab005'
const L=58,R=198,Y=128,H=42
const pill=c=>{c.beginPath();c.roundRect(L,Y-H,R-L,H*2,H)}
const spark=(c,x,y,s)=>{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()}
const ss=x=>x<=0?0:x>=1?1:x*x*(3-2*x)
export default(c,t)=>{
const f=ss(t/.66),d=ss((t-.86)/.14),x0=L+(R-L)*d,x1=L+(R-L)*f,sh=(t-.68)/.14
for(const s of[-1,1]){
c.save();c.translate(128,Y);c.scale(s,1);c.translate(-128,-Y)
const w=3*sin(T*t*2),P=[[16,Y-46],[28,Y-30],[12,Y-14],[26,Y],[12,Y+14],[28,Y+30],[16,Y+46]].map(([x,y])=>[x-w,y])
c.fillStyle=WR;c.beginPath();c.moveTo(L-6,Y-12);P.forEach(([x,y])=>c.lineTo(x,y));c.lineTo(L-6,Y+12);c.closePath();c.fill();c.stroke()
c.strokeStyle=WD;c.lineWidth=4;for(const k of[0,2,4,6])c.beginPath(),c.moveTo(L-14,Y+(k-3)*3),c.lineTo(P[k][0]+8,P[k][1]+(3-k)*1.5),c.stroke()
c.strokeStyle='#111';c.fillStyle=WD;c.lineWidth=6;c.beginPath();c.roundRect(L-16,Y-15,22,30,9);c.fill();c.stroke()
c.restore();c.lineWidth=7
}
c.fillStyle=TK;pill(c);c.fill()
c.save();pill(c);c.clip()
if(x1>x0+.5){
c.beginPath();c.rect(x0,0,x1-x0,256);c.clip();c.fillStyle='#fff';c.fillRect(0,0,256,256)
c.fillStyle=ST;const o=t*2*40;for(let x=L-80+o%40;x<R+50;x+=40)c.beginPath(),c.moveTo(x,Y-H),c.lineTo(x+20,Y-H),c.lineTo(x-16,Y+H),c.lineTo(x-36,Y+H),c.closePath(),c.fill()
c.lineWidth=5;c.beginPath();c.moveTo(x1,Y-H);c.lineTo(x1,Y+H);c.stroke()
}
if(sh>0&&sh<1){const gx=L-30+(R-L+60)*sh;c.fillStyle='#fff';c.beginPath();c.moveTo(gx,Y-H);c.lineTo(gx+22,Y-H);c.lineTo(gx-2,Y+H);c.lineTo(gx-24,Y+H);c.closePath();c.fill()}
c.restore()
c.strokeStyle='#fff';c.lineWidth=7;c.beginPath();c.moveTo(L+28,Y-26);c.lineTo(R-34,Y-26);c.stroke()
c.strokeStyle='#111';c.lineWidth=7;pill(c);c.stroke()
if(t>.66&&t<.88)for(const[x,y,o]of[[84,56,0],[178,54,.4],[124,206,.2],[206,198,.6]]){const s=12*sin(PI*min(1,max(0,(t-.66)/.22*1.4-o*.4)));if(s>1.5)spark(c,x,y,s)}
}
+26
View File
@@ -0,0 +1,26 @@
// orange tabby curled in a ring chasing its own tail round and round like a spinner, paws scrabbling, eyes locked on the tail tip
const{sin,cos,PI,atan2}=Math,T=2*PI
export const frames=16,delay=60
const OR='#ffa94d',OD='#f08c00',PK='#ffc9c9',BL='#ff8787',X=128,Y=134,R=58
const at=(a,r=R)=>[X+cos(a)*r,Y+sin(a)*r]
export default(c,t,i)=>{
const h=t*T,tail=[];for(let s=0;s<=1.001;s+=.1){const a=h-3.3-s*1.9,r=R+8*sin(s*PI)+6*s*sin(T*t*4+s*3);tail.push(at(a,r))}
const line=(pts,w,col)=>{c.lineWidth=w;c.strokeStyle=col;c.beginPath();pts.forEach(([x,y])=>c.lineTo(x,y));c.stroke()}
const tp=tail.at(-1)
line(tail,34,'#111');line(tail,20,OR);line(tail.slice(-3),20,'#fff')
for(const[a,ph]of[[h-.75,0],[h-3.1,PI]])for(const s of[-1,1]){const q=a+.22*sin(T*t*4+ph+(s>0?0:PI)),[x,y]=at(q,R+s*26);c.fillStyle='#fff';c.lineWidth=5;c.strokeStyle='#111';c.beginPath();c.ellipse(x,y,11,8,q,0,T);c.fill();c.stroke()}
c.strokeStyle='#111';c.lineWidth=54;c.beginPath();c.arc(X,Y,R,h-3.3,h-.2);c.stroke()
c.lineWidth=40;c.strokeStyle=OR;c.beginPath();c.arc(X,Y,R,h-3.3,h-.2);c.stroke()
c.lineWidth=6;c.strokeStyle=OD;for(let k=0;k<4;k++){const a=h-1.3-k*.52;c.beginPath();c.moveTo(...at(a-.08,R-14));c.lineTo(...at(a,R+14));c.stroke()}
const[hx,hy]=at(h,R+2),d=atan2(tp[1]-hy,tp[0]-hx),ex=4*cos(d),ey=4*sin(d)
c.strokeStyle='#111';c.lineWidth=7
for(const s of[-1,1]){c.fillStyle=OR;c.beginPath();c.moveTo(hx+s*28,hy-6);c.lineTo(hx+s*24,hy-44);c.lineTo(hx+s*4,hy-26);c.closePath();c.fill();c.stroke();c.fillStyle=PK;c.beginPath();c.moveTo(hx+s*22,hy-14);c.lineTo(hx+s*22,hy-34);c.lineTo(hx+s*12,hy-24);c.closePath();c.fill()}
c.fillStyle=OR;c.beginPath();c.ellipse(hx,hy,34,29,0,0,T);c.fill();c.stroke()
c.lineWidth=4;c.strokeStyle=OD;for(const s of[-1,0,1])c.beginPath(),c.moveTo(hx+s*9,hy-27),c.lineTo(hx+s*7,hy-17),c.stroke()
c.fillStyle='#fff';c.beginPath();c.ellipse(hx,hy+12,14,10,0,0,T);c.fill()
c.fillStyle='#111';for(const s of[-1,1])c.beginPath(),c.arc(hx+s*14+ex,hy-1+ey,5.5,0,T),c.fill()
c.fillStyle='#fff';for(const s of[-1,1])c.beginPath(),c.arc(hx+s*14+ex-2,hy-3+ey,2,0,T),c.fill()
c.fillStyle='#ff8fab';c.beginPath();c.moveTo(hx-4,hy+6);c.lineTo(hx+4,hy+6);c.lineTo(hx,hy+10);c.closePath();c.fill()
c.strokeStyle='#111';c.lineWidth=3;c.beginPath();c.moveTo(hx-7,hy+13);c.quadraticCurveTo(hx-3.5,hy+17,hx,hy+12);c.quadraticCurveTo(hx+3.5,hy+17,hx+7,hy+13);c.stroke()
c.fillStyle=BL;for(const s of[-1,1])c.beginPath(),c.ellipse(hx+s*24,hy+9,6,3.5,0,0,T),c.fill()
}
+33
View File
@@ -0,0 +1,33 @@
// smiling coffee machine drips coffee into a glass mug that fills up bit by bit, steams when full, then empties to brew again
const{sin,PI,min}=Math,T=2*PI
export const frames=24,delay=80
const BO='#ff8787',BD='#fa5252',RC='#495057',GL='#d0ebff',CO='#a9744f',CR='#e8b27a',BL='#ffc9c9',ME='#ced4da'
const ss=x=>x<=0?0:x>=1?1:x*x*(3-2*x)
export default(c,t)=>{
const f=ss(t/.74)-ss((t-.88)/.12),lv=204-8-62*f,brew=t<.76
c.fillStyle=BO;c.beginPath();c.roundRect(34,14,188,226,24);c.fill();c.stroke()
c.fillStyle=RC;c.beginPath();c.roundRect(56,88,144,124,[10,10,4,4]);c.fill();c.lineWidth=5;c.stroke()
c.fillStyle=ME;c.beginPath();c.moveTo(112,86);c.lineTo(144,86);c.lineTo(136,104);c.lineTo(120,104);c.closePath();c.fill();c.stroke()
c.fillStyle=ME;c.beginPath();c.roundRect(48,208,160,16,6);c.fill();c.stroke()
c.lineWidth=3;for(let x=64;x<200;x+=16)c.beginPath(),c.moveTo(x,212),c.lineTo(x,220),c.stroke()
c.lineWidth=7
for(const[w,s]of[[22,'#111'],[10,GL]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(166,146),c.bezierCurveTo(194,144,194,190,164,188),c.stroke()
c.strokeStyle='#111';c.lineWidth=7
const mug=()=>{c.beginPath();c.roundRect(86,128,82,78,[4,4,16,16])}
c.fillStyle=GL;mug();c.fill()
c.save();mug();c.clip()
if(f>.01){c.fillStyle=CO;c.fillRect(80,lv,96,90);c.fillStyle=CR;c.beginPath();c.ellipse(127,lv,46,4+2*sin(T*t*4),0,0,T);c.fill()}
c.strokeStyle='#fff';c.lineWidth=7;c.beginPath();c.moveTo(100,142);c.lineTo(100,174);c.stroke()
c.restore();mug();c.stroke()
if(brew)for(let k=0;k<4;k++){const p=(t*8+k/4)%1,y=106+p*(lv-106);if(y<lv-6){c.fillStyle=CO;c.lineWidth=3;c.beginPath();c.moveTo(128,y-10);c.quadraticCurveTo(135,y,128,y+6);c.quadraticCurveTo(121,y,128,y-10);c.fill();c.stroke()}}
c.lineWidth=7
const happy=t>.76&&t<.92
if(t>.7&&t<.94)for(let k=0;k<2;k++){const a=min(1,(t-.7)/.08)*min(1,(.94-t)/.06),pts=[];for(let s=0;s<=1;s+=.125)pts.push([116+k*24+5*sin(T*(s-t*2)+k*2),122-26*s*a]);c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();pts.forEach(([x,y])=>c.lineTo(x,y));c.stroke()}
c.strokeStyle='#111'
if(happy){c.lineWidth=5;for(const d of[-1,1])c.beginPath(),c.arc(128+d*26,54,7,PI*1.15,PI*1.85),c.stroke()}
else{c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+d*26,50,6.5,0,T),c.fill();c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(128+d*26-2,48,2.3,0,T),c.fill()}
c.lineWidth=5;c.beginPath();c.arc(128,58,happy?11:8,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*48,62,9,5,0,0,T),c.fill()
c.lineWidth=4;c.fillStyle=brew&&Math.floor(t*12)%2?'#ffd43b':'#69db7c';c.beginPath();c.arc(196,36,7,0,T);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.arc(60,36,7,0,T);c.fill();c.stroke()
}
+24
View File
@@ -0,0 +1,24 @@
// three gummy bears, red, yellow and green, hopping one after another in a wave like a loading dots row
const{sin,PI,max}=Math,T=2*PI
export const frames=16,delay=70
const B=[['#ff6b6b','#ffa8a8'],['#ffd43b','#fff3bf'],['#69db7c','#b2f2bb']],BL='#ff8787'
const shapes=c=>[()=>c.ellipse(-14,-12,12,13,0,0,T),()=>c.ellipse(14,-12,12,13,0,0,T),()=>c.ellipse(-25,-44,10,14,.5,0,T),()=>c.ellipse(25,-44,10,14,-.5,0,T),()=>c.ellipse(0,-36,26,29,0,0,T),()=>c.arc(-18,-96,10,0,T),()=>c.arc(18,-96,10,0,T),()=>c.arc(0,-76,25,0,T)]
export default(c,t)=>{
B.forEach(([col,lt],k)=>{
const h=max(0,sin(T*(t-k*.16))),y=-50*h**.8,sq=h<.15?1-(.15-h)*.8:1+.06*h*(1-h)*4
c.save();c.translate(48+k*80,214);c.scale(2-sq,sq);c.translate(0,y/sq);c.scale(1.04,1.04)
const S=shapes(c)
c.fillStyle='#111';for(const f of S)c.beginPath(),f(),c.lineWidth=14,c.strokeStyle='#111',c.stroke()
c.fillStyle=col;for(const f of S)c.beginPath(),f(),c.fill()
c.fillStyle=lt;c.beginPath();c.ellipse(0,-32,15,17,0,0,T);c.fill();c.beginPath();c.ellipse(0,-68,12,8,0,0,T);c.fill()
for(const d of[-1,1])c.beginPath(),c.arc(d*18,-96,4.5,0,T),c.fill()
c.strokeStyle='#111';c.lineWidth=3;c.beginPath();c.moveTo(-6,-22);c.quadraticCurveTo(-8,-12,-14,-6);c.moveTo(6,-22);c.quadraticCurveTo(8,-12,14,-6);c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(d*10,-80,4,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*10-1.5,-81.5,1.5,0,T),c.fill()
c.fillStyle='#111';c.beginPath();c.ellipse(0,-71,4,3,0,0,T);c.fill()
c.lineWidth=3;c.beginPath();c.moveTo(-5,-65);c.quadraticCurveTo(-2.5,-62,0,-66);c.quadraticCurveTo(2.5,-62,5,-65);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*17,-70,4.5,2.8,0,0,T),c.fill()
c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();c.arc(0,-76,18,PI*1.15,PI*1.4);c.stroke();c.beginPath();c.arc(0,-36,20,PI*1.05,PI*1.3);c.stroke()
c.restore()
})
}
+39
View File
@@ -0,0 +1,39 @@
// mint microwave humming away: light on inside, a smiling soup bowl turning round on the spinning plate, the green timer glowing and counting down
const{sin,cos,PI,floor}=Math,T=2*PI
export const frames=20,delay=90
const BO='#63e6be',BD='#20c997',IN='#fff3bf',BW='#ff8787',SO='#ffd43b',DS='#343a40',GG='#2f9e44',GB='#b2f2bb',BL='#ffa8a8'
const SEG=[63,6,91,79,102,109,125,7,127,111]
const digit=(c,n,x,y,w=11,h=20)=>{const P=[[0,0,w,0],[w,0,w,h/2],[w,h/2,w,h],[0,h,w,h],[0,h/2,0,h],[0,0,0,h/2],[0,h/2,w,h/2]];c.beginPath();P.forEach(([a,b,e,f],k)=>{if(SEG[n]>>k&1)c.moveTo(x+a,y+b),c.lineTo(x+e,y+f)})}
export default(c,t,i)=>{
const th=t*T,PX=98,PY=162
c.fillStyle=BD;for(const x of[44,196])c.beginPath(),c.roundRect(x-14,200,28,22,8),c.fill(),c.stroke()
c.fillStyle=BO;c.beginPath();c.roundRect(14,44,228,166,24);c.fill();c.stroke()
c.fillStyle=BD;c.beginPath();c.roundRect(28,58,144,138,16);c.fill();c.lineWidth=5;c.stroke()
const win=()=>{c.beginPath();c.roundRect(40,70,118,114,10)}
c.fillStyle=IN;win();c.fill()
c.save();win();c.clip()
c.fillStyle='#ffe066';c.beginPath();c.ellipse(99,70,44,16,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.ellipse(PX,PY,46,12,0,0,T);c.fill();c.lineWidth=5;c.stroke()
c.fillStyle='#dee2e6';for(let k=0;k<6;k++){const a=th+k*T/6;if(sin(a)>0)continue;c.beginPath();c.arc(PX+cos(a)*36,PY+sin(a)*8,2.6,0,T);c.fill()}
const by=PY-6
c.fillStyle=BW;c.lineWidth=6;c.beginPath();c.ellipse(PX,by-32,32,8,0,0,PI,true);c.ellipse(PX,by-32,32,34,0,0,PI);c.fill();c.stroke()
c.save();c.beginPath();c.ellipse(PX,by-32,32,34,0,0,PI);c.clip()
for(const[o,face]of[[0,1],[PI,0]]){const a=th+o,cx=PX+22*sin(a),k=cos(a);if(k<.05)continue
c.save();c.translate(cx,by-11);c.scale(k,1)
if(face){c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(d*9,-4,3.5,0,T),c.fill();c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*9-1.2,-5.2,1.3,0,T),c.fill();c.strokeStyle='#111';c.lineWidth=3;c.beginPath();c.arc(0,0,4.5,.15*PI,.85*PI);c.stroke();c.fillStyle='#ffc9c9';for(const d of[-1,1])c.beginPath(),c.ellipse(d*16,1,4,2.5,0,0,T),c.fill()}
else{c.fillStyle='#fff';c.beginPath();c.moveTo(0,6);c.bezierCurveTo(-12,-2,-7,-11,0,-5);c.bezierCurveTo(7,-11,12,-2,0,6);c.fill()}
c.restore()}
c.restore()
c.fillStyle=SO;c.beginPath();c.ellipse(PX,by-32,27,6,0,0,T);c.fill();c.lineWidth=4;c.stroke()
c.lineWidth=6;c.beginPath();c.ellipse(PX,by-32,32,8,0,0,T);c.stroke()
for(let k=0;k<2;k++){const pts=[];for(let s=0;s<=1;s+=.125)pts.push([PX-10+k*20+4*sin(T*(s-t*2)+k*2),by-46-30*s]);for(const[w,st]of[[9,'#111'],[4,'#fff']]){c.lineWidth=w;c.strokeStyle=st;c.beginPath();pts.forEach(([x,y])=>c.lineTo(x,y));c.stroke()}}
c.strokeStyle='#fff';c.lineWidth=7;c.beginPath();c.moveTo(52,92);c.lineTo(62,82);c.moveTo(52,108);c.lineTo(76,84);c.stroke()
c.restore();c.strokeStyle='#111';c.lineWidth=6;win();c.stroke()
c.lineWidth=7;c.fillStyle=DS;c.beginPath();c.roundRect(180,64,50,34,8);c.fill();c.stroke()
const n=20-i;for(const[w,col]of[[7,GG],[3.5,GB]]){c.lineWidth=w;c.strokeStyle=col;digit(c,floor(n/10),189,71);c.stroke();digit(c,n%10,210,71);c.stroke()}
c.strokeStyle='#111';c.lineWidth=4
for(let r=0;r<2;r++)for(let q=0;q<3;q++){c.fillStyle=['#fff','#ffd43b','#ff8787'][q];c.beginPath();c.roundRect(182+q*16,110+r*18,12,12,4);c.fill();c.stroke()}
c.lineWidth=6;c.fillStyle='#fff';c.beginPath();c.arc(205,170,16,0,T);c.fill();c.stroke()
c.save();c.translate(205,170);c.rotate(-th);c.lineWidth=5;c.beginPath();c.moveTo(0,0);c.lineTo(0,-10);c.stroke();c.restore()
c.fillStyle='#fff';c.lineWidth=5;c.beginPath();c.roundRect(160,84,10,90,5);c.fill();c.stroke()
}
+21
View File
@@ -0,0 +1,21 @@
// four-color paper pinwheel whirling round on its stick in the breeze, little wind swooshes blowing past
const{sin,cos,PI}=Math,T=2*PI
export const frames=16,delay=60
const C=['#ff6b6b','#ffd43b','#4dabf7','#69db7c'],L=['#ffa8a8','#fff3bf','#a5d8ff','#b2f2bb'],X=128,Y=106,R=88,BL='#ffa8a8'
const p=(a,r)=>[cos(a)*r,sin(a)*r]
export default(c,t)=>{
for(const[y,o,w]of[[178,0,50],[206,.5,58]]){const q=(t+o)%1,x=16+q*40,a=sin(PI*q)
if(a>.15)for(const[lw,st]of[[11,'#111'],[5,'#fff']]){c.lineWidth=lw;c.strokeStyle=st;c.beginPath();c.moveTo(x,y);c.quadraticCurveTo(x+w*a*.5,y-6*a,x+w*a,y);c.stroke()}}
c.strokeStyle='#111'
for(const[w,s]of[[22,'#111'],[10,'#e8a15a']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(X,Y),c.lineTo(X,240),c.stroke()
c.strokeStyle='#111';c.lineWidth=7
c.save();c.translate(X,Y);const rot=-t*T
for(let k=0;k<4;k++){const a=rot+k*PI/2
c.fillStyle=C[k];c.beginPath();c.moveTo(0,0);c.lineTo(...p(a,R));c.quadraticCurveTo(...p(a+1.2,R*1.02),...p(a+PI/2,R*.4));c.closePath();c.fill();c.stroke()
c.fillStyle=L[k];c.lineWidth=5;c.beginPath();c.moveTo(0,0);c.lineTo(...p(a,R-6));c.quadraticCurveTo(...p(a+.55,R*.62),...p(a+.85,R*.26));c.closePath();c.fill();c.stroke();c.lineWidth=7}
c.restore()
c.fillStyle='#fff';c.beginPath();c.arc(X,Y,20,0,T);c.fill();c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(X+d*7,Y-2,3.5,0,T),c.fill()
c.lineWidth=3.5;c.beginPath();c.arc(X,Y+3,4.5,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(X+d*12,Y+5,3.5,2.2,0,0,T),c.fill()
}
+29
View File
@@ -0,0 +1,29 @@
// pizza progress circle: slices pop onto the plate one by one clockwise until the pie is whole and smiling with sparkles, then all the slices shrink away to load again
const{sin,cos,PI,min,max}=Math,T=2*PI
export const frames=24,delay=80
const CR='#e8a15a',CH='#ffd43b',PP='#fa5252',PR='#a5d8ff',X=128,Y=128,R=92
const ss=x=>x<=0?0:x>=1?1:x*x*(3-2*x)
const back=p=>p<=0?0:p>=1?1:1+2.7*(p-1)**3+1.7*(p-1)**2
export default(c,t)=>{
const out=1-ss((t-.86)/.1)
c.fillStyle=PR;c.beginPath();c.arc(X,Y,112,0,T);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.arc(X,Y,100,0,T);c.fill();c.lineWidth=4;c.stroke()
c.strokeStyle='#ced4da';c.lineWidth=4;c.setLineDash([6,8]);for(let k=0;k<8;k++){const a=-PI/2+k*PI/4;c.beginPath();c.moveTo(X+cos(a)*14,Y+sin(a)*14);c.lineTo(X+cos(a)*R,Y+sin(a)*R);c.stroke()}
c.beginPath();c.arc(X,Y,R-2,0,T);c.stroke();c.setLineDash([]);c.strokeStyle='#111'
for(let k=0;k<8;k++){
const s=back((t-k/12)/.08)*out;if(s<.02)continue
const a0=-PI/2+k*PI/4,a1=a0+PI/4,m=(a0+a1)/2,cx=X+cos(m)*(48+3),cy=Y+sin(m)*(48+3)
c.save();c.translate(cx,cy);c.scale(s,s);c.translate(-cx,-cy);c.translate(cos(m)*3,sin(m)*3)
c.lineWidth=6;c.fillStyle=CR;c.beginPath();c.moveTo(X,Y);c.arc(X,Y,R,a0,a1);c.closePath();c.fill();c.stroke()
c.fillStyle=CH;c.beginPath();c.moveTo(X,Y);c.arc(X,Y,R-16,a0+.03,a1-.03);c.closePath();c.fill()
c.lineWidth=4;c.fillStyle=PP;for(const[r,o]of[[62,-.13],[40,.12]]){const a=m+o;c.beginPath();c.arc(X+cos(a)*r,Y+sin(a)*r,8,0,T);c.fill();c.stroke()}
c.restore()
}
const f=t>.72&&t<.86
if(f){c.fillStyle=CH;c.beginPath();c.arc(X,Y,27,0,T);c.fill()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(X+d*11,Y-4,5,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(X+d*11-1.6,Y-5.6,1.8,0,T),c.fill()
c.lineWidth=4;c.beginPath();c.arc(X,Y+3,7,.15*PI,.85*PI);c.stroke()
c.fillStyle='#ff8787';for(const d of[-1,1])c.beginPath(),c.ellipse(X+d*19,Y+5,5,3,0,0,T),c.fill()}
if(t>.68&&t<.9)for(const[x,y,o]of[[26,30,0],[230,30,.3],[22,66,.45],[234,66,.15]]){const q=(t-.68)/.22*1.5-o,z=12*sin(PI*min(1,max(0,q)));if(z>1.5){c.lineWidth=4;c.fillStyle='#fff';c.beginPath();c.moveTo(x,y-z);for(const[px,py,qx,qy]of[[z,0,z*.2,-z*.2],[0,z,z*.2,z*.2],[-z,0,-z*.2,z*.2],[0,-z,-z*.2,-z*.2]])c.quadraticCurveTo(x+qx,y+qy,x+px,y+py);c.fill();c.stroke()}}
}
+25
View File
@@ -0,0 +1,25 @@
// rainbow loader between two smiling clouds: the empty arch fills in band by band from red to violet, sparkles when complete, then wipes clear to start over
const{sin,PI,min,max}=Math,T=2*PI
export const frames=24,delay=80
const C=['#ff6b6b','#ffa94d','#ffd43b','#69db7c','#4dabf7','#b197fc'],X=128,Y=182,RO=114,RI=42,BW=(RO-RI)/6
const cloud=(c,x,y)=>{
const P=[[x-20,y+2,16],[x+2,y-10,21],[x+22,y+2,15]],base=()=>c.roundRect(x-36,y,72,24,12)
c.lineWidth=14;c.strokeStyle='#111';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+2+d*9,y+6,3,0,T),c.fill()
c.lineWidth=3;c.beginPath();c.arc(x+2,y+10,4.5,.15*PI,.85*PI);c.stroke()
c.fillStyle='#ffc9c9';for(const d of[-1,1])c.beginPath(),c.ellipse(x+2+d*18,y+11,4,2.5,0,0,T),c.fill();c.lineWidth=7
}
const spark=(c,x,y,s)=>{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()}
export default(c,t)=>{
const q=max(0,min(1,(t-.8)/.14))
c.fillStyle='#fff';c.beginPath();c.arc(X,Y,RO,PI,0);c.arc(X,Y,RI,0,PI,true);c.closePath();c.fill()
c.lineCap='butt'
C.forEach((col,k)=>{const p=max(0,min(1,(t-k*.1)/.12)),a0=PI+PI*q,a1=PI+PI*p;if(a1>a0+.01){c.strokeStyle=col;c.lineWidth=BW+.8;c.beginPath();c.arc(X,Y,RO-BW*(k+.5),a0,a1);c.stroke()}})
c.lineCap='round';c.strokeStyle='#111';c.lineWidth=7
c.beginPath();c.arc(X,Y,RO,PI,0);c.arc(X,Y,RI,0,PI,true);c.closePath();c.stroke()
const h0=PI*max(1.1,1+q),h1=PI*min(1.3,1+min(1,t/.12));c.strokeStyle='#fff';c.lineWidth=5;if(h1>h0+.05)c.beginPath(),c.arc(X,Y,RO-7,h0,h1),c.stroke()
c.strokeStyle='#111'
if(t>.68&&t<.84)for(const[x,y,o]of[[128,40,0],[40,72,.33],[216,72,.66]]){const s=13*sin(PI*((t-.68)/.16));if(s>1.5)spark(c,x,y,s*1.2*(1-o*.3))}
cloud(c,X-(RO+RI)/2,Y+4+Math.round(2*sin(T*t)));cloud(c,X+(RO+RI)/2,Y+4+Math.round(2*sin(T*t+PI)))
}
+39
View File
@@ -0,0 +1,39 @@
// a snail slowly crawls along a progress bar dragging the slimy fill along behind it, at the end it ducks into its shell and rolls back to the start
const{sin,cos,PI,min,max}=Math,T=2*PI
export const frames=24,delay=90
const SH='#b197fc',SD='#7950f2',BD='#ffd8a8',FL='#63e6be',BL='#ff8787'
const GY=170,L=14,R=242,K=1.34,XA=L+56*K,XB=R-66*K
const ss=x=>x<=0?0:x>=1?1:x*x*(3-2*x)
const bar=c=>{c.beginPath();c.roundRect(L,GY,R-L,36,18)}
export default(c,t)=>{
const u=min(1,t/.66),rb=ss((t-.74)/.18),e=t<.66?1:1-ss((t-.66)/.07)+ss((t-.92)/.08),x=t<.74?XA+(XB-XA)*u:XB-(XB-XA)*rb
const F=t<.74?L+(R-L)*u:t<.92?L+(R-L)*(x-XA)/(XB-XA):L,st=t<.66?4*sin(T*t*6):0,rot=-T*rb
c.fillStyle='#fff';bar(c);c.fill()
c.save();bar(c);c.clip();if(F>L+1){c.fillStyle=FL;c.fillRect(L,GY,F-L,40);c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();c.moveTo(L+14,GY+9);c.lineTo(max(L+14,F-12),GY+9);c.stroke()}c.restore()
c.strokeStyle='#111';c.lineWidth=7;bar(c);c.stroke()
c.save();c.translate(x,GY);c.scale(K,K)
if(e>.02){
c.save();c.translate(0,-30);c.scale(e,e);c.translate(0,30)
const hx=44+st,hy=-36+st*.3,parts=(o,f)=>{
c.lineWidth=8+o;c.beginPath();c.moveTo(hx-8,hy-12);c.lineTo(hx-16,hy-36);c.moveTo(hx+6,hy-14);c.lineTo(hx+10,hy-38);c.stroke()
c.beginPath();c.arc(hx-16,hy-36,5+o/2,0,T);c.arc(hx+10,hy-38,5+o/2,0,T);f()
c.beginPath();c.roundRect(-50-o/2,-20-o/2,90+st+o,20+o,10+o/2);f()
c.lineWidth=26+o;c.beginPath();c.moveTo(hx-16,-10);c.lineTo(hx-2,hy+6);c.stroke()
c.beginPath();c.arc(hx,hy,19+o/2,0,T);f()}
c.strokeStyle=c.fillStyle='#111';parts(12,()=>c.fill())
c.strokeStyle=c.fillStyle=BD;parts(0,()=>c.fill())
c.strokeStyle='#111'
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(hx+2+d*8,hy-3,3.8,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(hx+.8+d*8,hy-4.5,1.4,0,T),c.fill()
c.lineWidth=3.5;c.beginPath();c.arc(hx+2,hy+3,5,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(hx+2+d*13,hy+5,4,2.5,0,0,T),c.fill()
c.restore()
}
const sy=-34-10*e
c.save();c.translate(-4,sy);c.rotate(rot+.04*st)
c.fillStyle=SH;c.lineWidth=7;c.beginPath();c.arc(0,0,34,0,T);c.fill();c.stroke()
c.strokeStyle=SD;c.lineWidth=6;c.beginPath();for(let a=0;a<4.4*PI;a+=.2){const r=3+a*1.75;c.lineTo(cos(a)*r,sin(a)*r)}c.stroke()
c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();c.arc(0,0,26,PI*1.1,PI*1.4);c.stroke()
c.restore()
c.restore()
}
+41
View File
@@ -0,0 +1,41 @@
// blue vault with its gold wheel spun hard by a straining face, then jammed and rattling, locked tight as a padlock badge pops up
const{sin,cos,PI}=Math,T=2*PI
export const frames=16,delay=85
const BX='#4dabf7',DR='#ced4da',DRD='#adb5bd',G='#ffd43b',GD='#fab005',BL='#ffa8a8',SH='#868e96'
const ease=u=>u*u*(3-2*u)
export default(c,t)=>{
const sp=t<.5,u=sp?ease(t/.5):1,rt=(t-.5)*2,rat=sp?0:.14*sin(T*rt*4)*(1-rt),ang=u*T/3+rat,sh=sp?0:2.5*sin(T*rt*8)*(1-rt)
const pop=t<.5?0:t<.6?ease((t-.5)/.1)*1.2:t<.68?1.2-.2*ease((t-.6)/.08):t<.9?1:1-ease((t-.9)/.1)
c.fillStyle=SH;for(const x of[38,182])c.beginPath(),c.roundRect(x,220,36,18,6),c.fill(),c.stroke()
c.fillStyle=BX;c.beginPath();c.roundRect(16,16,224,208,28);c.fill();c.stroke()
c.fillStyle=SH;for(const y of[64,170])c.beginPath(),c.roundRect(28,y-14,20,28,6),c.fill(),c.stroke()
c.translate(sh,0)
c.fillStyle=DRD;for(const a of[-.35,.35])c.beginPath(),c.roundRect(200,118+a*90-7,30,14,5),c.fill(),c.stroke()
c.fillStyle=DR;c.beginPath();c.arc(128,120,90,0,T);c.fill();c.stroke()
c.lineWidth=5;c.fillStyle=DRD;c.beginPath();c.arc(128,120,72,0,T);c.fill();c.stroke()
c.fillStyle=DR;for(let k=0;k<8;k++){const a=k*PI/4+PI/8;c.beginPath();c.arc(128+cos(a)*81,120+sin(a)*81,4.5,0,T);c.fill();c.lineWidth=3;c.stroke()}
c.save();c.translate(128,120);c.rotate(ang)
for(const[w,s]of[[14,'#111'],[6,GD]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.arc(0,0,46,0,T),c.stroke()
for(let k=0;k<6;k++){c.rotate(PI/3);for(const[w,s]of[[13,'#111'],[5,GD]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(24,0),c.lineTo(58,0),c.stroke();c.strokeStyle='#111';c.lineWidth=5;c.fillStyle=G;c.beginPath();c.arc(62,0,9,0,T);c.fill();c.stroke()}
c.restore()
c.lineWidth=6;c.fillStyle=G;c.beginPath();c.arc(128,120,28,0,T);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.ellipse(116,108,5,3,-.6,0,T);c.fill()
c.lineWidth=3.5;c.fillStyle='#111'
if(sp){
for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*15,114),c.lineTo(128+d*7,118),c.lineTo(128+d*15,122),c.stroke()
c.beginPath();c.moveTo(119,130);for(let k=1;k<=6;k++)c.lineTo(119+k*3,130+(k%2?-2.5:0));c.stroke()
}else{
for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*10,117,3.5,4.5,0,0,T),c.fill()
c.lineWidth=3.5;for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*15,108),c.lineTo(128+d*5,111),c.stroke()
c.beginPath();c.moveTo(120,128);c.quadraticCurveTo(128,132,137,125);c.stroke()
}
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*17,127,4.5,2.5,0,0,T),c.fill()
c.translate(-sh,0)
if(pop>.02){
c.save();c.translate(206,52);c.scale(pop,pop);c.rotate(.15*sin(T*rt*2))
for(const[w,s]of[[16,'#111'],[7,DR]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.arc(0,-8,14,PI,0),c.lineTo(14,4),c.moveTo(-14,4),c.lineTo(-14,-8),c.stroke()
c.strokeStyle='#111';c.lineWidth=6;c.fillStyle=G;c.beginPath();c.roundRect(-24,-2,48,38,9);c.fill();c.stroke()
c.fillStyle='#111';c.beginPath();c.arc(0,12,5,0,T);c.fill();c.beginPath();c.moveTo(-3,13);c.lineTo(3,13);c.lineTo(4,26);c.lineTo(-4,26);c.closePath();c.fill()
c.restore()
}
}
+44
View File
@@ -0,0 +1,44 @@
// mailbox with its flag down, the door drops open with a puff of dust and a lonely moth flutters out, loops around and leaves, then the door shuts
const{sin,cos,PI,max,min,abs,floor}=Math,T=2*PI
export const frames=24,delay=80
const MB='#4dabf7',DR='#74c0fc',DI='#d0ebff',IN='#343a40',FL='#ff6b6b',PO='#a9744f',MW='#ffe8cc',MS='#e0a96d',MG='#ced4da',BL='#ffa8a8',DU='#e9ecef'
const E=u=>u<0?0:u>1?1:u*u*(3-2*u)
const KP=[[66,118],[66,118],[46,64],[100,34],[164,58],[200,30],[250,-70],[250,-70]]
const cr=u=>{const s=min(4.999,max(0,u)*5),k=floor(s),f=s-k,[a,b,d,e]=KP.slice(k,k+4);return[0,1].map(j=>.5*(2*b[j]+(d[j]-a[j])*f+(2*a[j]-5*b[j]+4*d[j]-e[j])*f*f+(3*b[j]-a[j]-3*d[j]+e[j])*f**3))}
const arch=(c,x,k)=>{c.beginPath();c.moveTo(x-32,148);for(let a=PI;a<=T+.01;a+=PI/16)c.lineTo(x+32*cos(a),148-(40-32*sin(a))*k);c.lineTo(x+32,148);c.closePath()}
const moth=(c,x,y,s,f,r)=>{
c.save();c.translate(x,y);c.rotate(r);c.scale(s,s);c.strokeStyle='#111'
for(const d of[-1,1]){c.save();c.scale(d*f,1);c.fillStyle=MW;c.lineWidth=5
c.beginPath();c.moveTo(0,4);c.bezierCurveTo(24,4,34,22,24,32);c.bezierCurveTo(14,40,4,26,0,10);c.fill();c.stroke()
c.beginPath();c.moveTo(0,-4);c.bezierCurveTo(18,-32,50,-30,46,-8);c.bezierCurveTo(44,8,16,10,0,4);c.fill();c.stroke()
c.fillStyle=MS;c.beginPath();c.arc(30,-10,6,0,T);c.fill();c.beginPath();c.arc(16,20,4,0,T);c.fill();c.restore()}
for(const d of[-1,1])for(const[w,st]of[[7,'#111'],[3,MW]])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.moveTo(d*3,-16),c.quadraticCurveTo(d*6,-30,d*16,-34),c.stroke()
c.strokeStyle='#111';c.lineWidth=4.5;c.fillStyle=MG;c.beginPath();c.ellipse(0,8,8,20,0,0,T);c.fill();c.stroke()
c.beginPath();c.arc(0,-13,9,0,T);c.fill();c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(d*3.5,-14,2,0,T),c.fill()
c.restore()
}
export default(c,t)=>{
const th=PI*.66*(E((t-.06)/.12)-E((t-.82)/.12)),k=cos(th),op=th>.05,u=(t-.2)/.66,[mx,my]=cr(u),mv=u>0&&u<1
c.save();c.translate(128,120);c.scale(1.12,1.12);c.translate(-128,-120)
c.fillStyle=PO;c.beginPath();c.roundRect(126,140,26,88,4);c.fill();c.stroke()
c.fillStyle=MB;c.beginPath();c.moveTo(72,76);c.lineTo(192,76);c.arc(192,108,32,-PI/2,0);c.lineTo(224,148);c.lineTo(72,148);c.closePath();c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=6;c.beginPath();c.moveTo(110,88);c.lineTo(176,88);c.stroke();c.strokeStyle='#111'
arch(c,72,1);c.fillStyle=op?IN:DR;c.fill();c.lineWidth=7;c.stroke()
if(op){arch(c,72,k);c.fillStyle=k>0?DR:DI;c.fill();c.stroke()}
c.fillStyle=MG;c.lineWidth=4;c.beginPath();c.roundRect(64,op?148-(k>0?66:60)*k-4:78,16,8,4);c.fill();c.stroke()
c.save();c.translate(204,104);c.rotate(.06*sin(t*T*2))
for(const[w,s]of[[11,'#111'],[5,FL]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(0,0),c.lineTo(-34,0),c.stroke()
c.strokeStyle='#111';c.lineWidth=5;c.fillStyle=FL;c.beginPath();c.roundRect(-44,-4,18,30,4);c.fill();c.stroke()
c.fillStyle=MG;c.beginPath();c.arc(0,0,6,0,T);c.fill();c.stroke();c.restore()
const lx=mv?max(-3,min(3,(mx-136)/14)):0,ly=mv?max(-3,min(2,(my-116)/14)):2
c.fillStyle='#111';for(const x of[118,146])c.beginPath(),c.arc(x+lx,106+ly,6,0,T),c.fill()
c.fillStyle='#fff';for(const x of[118,146])c.beginPath(),c.arc(x+lx-2,104+ly,2,0,T),c.fill()
c.lineWidth=4.5;c.beginPath();c.moveTo(110,92);c.lineTo(124,88);c.moveTo(154,92);c.lineTo(140,88);c.stroke()
c.lineWidth=5;c.beginPath();c.arc(132,132,8,1.2*PI,1.8*PI);c.stroke()
c.fillStyle=BL;for(const x of[106,158])c.beginPath(),c.ellipse(x,120,7,4,0,0,T),c.fill()
c.restore()
const p=(t-.14)/.3
if(p>0&&p<1)for(const[a,o]of[[-2.4,0],[-1.9,.15],[-2.9,.1]]){const q=min(1,max(0,p-o)/.8),r=13*sin(PI*q);if(r>1)c.fillStyle=DU,c.lineWidth=4,c.beginPath(),c.arc(66+cos(a)*(30+40*q),118+sin(a)*(20+40*q),r,0,T),c.fill(),c.stroke()}
if(mv)moth(c,mx,my,.4+.75*E(u*5),.25+.75*abs(cos(6*PI*t)),.3*sin(u*T*2))
}
+43
View File
@@ -0,0 +1,43 @@
// little robot cranking a bolt on its own chest with a big wrench, tongue out in concentration, sparks popping, gears turning on its head
const{sin,cos,PI}=Math,T=2*PI
export const frames=16,delay=90
const M='#ced4da',MD='#adb5bd',SC='#e7f5ff',G='#ffd43b',G2='#ffa94d',WR='#868e96',BL='#ffa8a8',RD='#ff6b6b',GN='#51cf66'
const gear=(c,x,y,r,n,a,col)=>{
c.fillStyle=col;c.lineWidth=5;c.beginPath()
for(let k=0;k<n;k++){const b=a+k*T/n,w=T/n/4;for(const[d,R]of[[-2*w,r],[-w*.8,r+8],[w*.8,r+8],[2*w,r]])c.lineTo(x+cos(b+d)*R,y+sin(b+d)*R)}
c.closePath();c.fill();c.stroke();c.fillStyle=M;c.beginPath();c.arc(x,y,r*.42,0,T);c.fill();c.stroke()
}
const star=(c,x,y,s)=>{c.fillStyle=G;c.lineWidth=3.5;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()}
export default(c,t,i)=>{
const ph=(t*2)%1,q=ph<.6?ph/.6:1-(ph-.6)/.4,th=.15+.7*(q*q*(3-2*q)),ga=t*T/2,bx=156,by=184
const hx=bx+68*cos(th),hy=by+68*sin(th)
c.fillStyle=MD;c.beginPath();c.roundRect(122,48,12,20,4);c.fill();c.stroke()
gear(c,128,38,17,10,ga,G);gear(c,165,22,10,6,-ga*10/6+.3,G2)
c.lineWidth=7;c.fillStyle=M
for(const x of[100,140]){c.beginPath();c.roundRect(x,206,18,26,6);c.fill();c.stroke()}
for(const x of[90,134]){c.beginPath();c.roundRect(x,226,34,14,7);c.fill();c.stroke()}
for(const[lw,s]of[[20,'#111'],[10,M]])c.lineWidth=lw,c.strokeStyle=s,c.beginPath(),c.moveTo(84,166),c.quadraticCurveTo(56,176,62,204),c.stroke()
c.strokeStyle='#111';c.lineWidth=6;c.fillStyle=M;c.beginPath();c.arc(62,206,11,0,T);c.fill();c.stroke()
c.lineWidth=7;c.fillStyle=M;c.beginPath();c.roundRect(78,150,100,64,16);c.fill();c.stroke()
c.fillStyle=MD;c.lineWidth=5;c.beginPath();c.roundRect(90,162,40,40,8);c.fill();c.stroke()
for(const[x,y,col,on]of[[102,174,RD,i%4<2],[118,174,GN,i%4>=2],[102,190,G,i%8<4],[118,190,'#4dabf7',i%8>=4]]){c.fillStyle=on?col:'#868e96';c.lineWidth=3;c.beginPath();c.arc(x,y,5,0,T);c.fill();c.stroke()}
c.lineWidth=7;c.fillStyle=MD;c.beginPath();c.rect(114,140,28,14);c.fill();c.stroke()
c.fillStyle=M;for(const x of[58,198]){c.beginPath();c.roundRect(x-8,88,16,30,6);c.fill();c.stroke()}
c.beginPath();c.roundRect(62,62,132,82,22);c.fill();c.stroke()
c.fillStyle=SC;c.lineWidth=5;c.beginPath();c.roundRect(78,76,100,56,14);c.fill();c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(144,100,5,7,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(142,97,2.2,0,T);c.fill()
c.lineWidth=4;c.beginPath();c.moveTo(105,94);c.lineTo(115,101);c.lineTo(105,108);c.stroke()
c.fillStyle=BL;for(const x of[96,160])c.beginPath(),c.ellipse(x,116,7,4,0,0,T),c.fill()
c.beginPath();c.moveTo(118,116);c.quadraticCurveTo(128,121,140,114);c.stroke()
c.fillStyle='#ff8787';c.lineWidth=3.5;c.beginPath();c.ellipse(136,121,5,6,-.4,0,PI);c.fill();c.stroke()
c.save();c.translate(bx,by);c.rotate(th)
c.fillStyle=WR;c.lineWidth=6;c.beginPath();c.roundRect(10,-8,62,16,8);c.fill();c.stroke();c.fillStyle=RD;c.beginPath();c.roundRect(34,-9,40,18,9);c.fill();c.stroke();c.fillStyle=WR
c.beginPath();c.arc(0,0,17,0,T);c.fill();c.stroke()
c.fillStyle=G;c.lineWidth=4;c.beginPath();for(let k=0;k<6;k++)c.lineTo(cos(k*PI/3)*9,sin(k*PI/3)*9);c.closePath();c.fill();c.stroke()
c.restore()
for(const[lw,s]of[[20,'#111'],[10,M]])c.lineWidth=lw,c.strokeStyle=s,c.beginPath(),c.moveTo(174,166),c.quadraticCurveTo(212,160,hx,hy),c.stroke()
c.strokeStyle='#111';c.lineWidth=6;c.fillStyle=M;c.beginPath();c.arc(hx,hy,12,0,T);c.fill();c.stroke()
const sp=ph>.6?(ph-.6)/.4:ph<.1?1+ph/.1:0
if(sp>0&&sp<2){const s=sp<1?sp:2-sp;for(const[a,d]of[[-2.4,30],[-1.6,34],[-.8,28]])star(c,bx+cos(a)*d,by-6+sin(a)*d,3+6*s)}
}
+31
View File
@@ -0,0 +1,31 @@
// worried satellite dish sweeping back and forth hunting for a signal, its little signal waves breaking up into dots and fizzling out
const{sin,cos,PI,max}=Math,T=2*PI
export const frames=16,delay=100
const DS='#74c0fc',DI='#e7f5ff',ST='#adb5bd',BA='#868e96',FE='#ff6b6b',WV='#ffd43b',BL='#ffa8a8'
export default(c,t)=>{
const a=.42*sin(T*t),lk=3.5*cos(T*t)
c.fillStyle=BA;c.beginPath();c.roundRect(68,214,120,26,10);c.fill();c.stroke()
c.fillStyle=ST;c.beginPath();c.roundRect(116,176,24,42,6);c.fill();c.stroke()
c.save();c.translate(128,190);c.rotate(a)
for(let k=0;k<3;k++){
const p=(t*3+k/3)%1,r=18+40*p,d=max(1,14-15*p)
c.setLineDash([d,6+20*p*p])
for(const[w,s]of[[13,'#111'],[6,WV]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.arc(0,-122,r,-PI/2-.62,-PI/2+.62),c.stroke()
}
c.setLineDash([]);c.strokeStyle='#111'
c.fillStyle=ST;c.lineWidth=7;c.beginPath();c.roundRect(-16,-20,32,22,6);c.fill();c.stroke()
for(const[w,s]of[[12,'#111'],[5,ST]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(-74,-74),c.lineTo(0,-118),c.lineTo(74,-74),c.stroke()
c.strokeStyle='#111';c.lineWidth=7
c.fillStyle=DS;c.beginPath();c.ellipse(0,-60,92,58,0,0,PI);c.ellipse(0,-60,92,34,0,PI,0,true);c.fill();c.stroke()
c.fillStyle=DI;c.beginPath();c.ellipse(0,-60,92,34,0,0,T);c.fill();c.stroke()
for(const[w,s]of[[12,'#111'],[5,ST]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(-74,-74),c.lineTo(-60,-82),c.moveTo(74,-74),c.lineTo(60,-82),c.stroke()
c.strokeStyle='#111';c.lineWidth=6;c.fillStyle=FE;c.beginPath();c.arc(0,-122,11,0,T);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.arc(-3,-125,3,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.ellipse(-56,-30,10,4,.3,0,T);c.fill()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.ellipse(d*22+lk,-60,6,7.5,0,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*22+lk-2,-63,2.4,0,T),c.fill()
c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.moveTo(d*14+lk,-76),c.lineTo(d*30+lk,-71),c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*42,-50,8,4.5,0,0,T),c.fill()
c.beginPath();c.moveTo(-10+lk,-45);c.quadraticCurveTo(-5+lk,-50,0+lk,-45);c.quadraticCurveTo(5+lk,-40,10+lk,-45);c.stroke()
c.restore()
}
+41
View File
@@ -0,0 +1,41 @@
// delivery truck driving along with a smiling parcel hopping on its flatbed, wheels turning, road dashes and speed lines rushing past
const{sin,cos,PI,abs,round,max}=Math,T=2*PI
export const frames=16,delay=60
const CAB='#4dabf7',CABD='#339af0',WIN='#e7f5ff',TIRE='#343a40',HUB='#ced4da',BED='#868e96',BX='#f0b878',BXD='#d99a5a',TAPE='#ffe8cc',BL='#ffa8a8'
export default(c,t)=>{
const b=-round(3*abs(sin(2*T*t))),h=-round(7*max(0,sin(2*T*t-.8))),tl=.05*max(0,sin(2*T*t-.8)),rot=t*T
c.fillStyle='#868e96';c.beginPath();c.roundRect(8,214,240,22,11);c.fill();c.stroke()
c.save();c.beginPath();c.rect(14,214,228,22);c.clip()
for(let k=-1;k<5;k++){const x=k*64-((t*128)%64)+20;c.fillStyle='#fff';c.beginPath();c.roundRect(x,222,30,6,3);c.fill()}
c.restore()
for(const[y,o,l]of[[92,0,30],[122,.5,22],[150,.25,28]]){const p=(t*2+o)%1,x=40-p*28;if(p<.85)for(const[w,s]of[[9,'#111'],[4,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(x,y),c.lineTo(x-l*(1-p),y),c.stroke()}
c.strokeStyle='#111';c.lineWidth=7
c.translate(0,b)
c.fillStyle=BED;c.beginPath();c.roundRect(34,166,136,22,6);c.fill();c.stroke()
c.save();c.translate(104,166+h);c.rotate(-tl)
c.fillStyle=BX;c.beginPath();c.roundRect(-58,-92,116,92,6);c.fill()
c.fillStyle=BXD;c.fillRect(-58,-92,116,14)
c.fillStyle=TAPE;c.fillRect(-14,-92,28,36)
c.lineWidth=4;c.beginPath();c.moveTo(-14,-92);c.lineTo(-14,-56);c.lineTo(14,-56);c.lineTo(14,-92);c.moveTo(-58,-78);c.lineTo(-14,-78);c.moveTo(14,-78);c.lineTo(58,-78);c.stroke()
c.lineWidth=7;c.beginPath();c.roundRect(-58,-92,116,92,6);c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(d*20,-36,5,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*20-2,-38,1.8,0,T),c.fill()
c.lineWidth=4;c.beginPath();c.arc(0,-30,8,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*36,-24,7,4,0,0,T),c.fill()
c.restore()
c.lineWidth=7;c.fillStyle=CAB;c.beginPath();c.moveTo(164,188);c.lineTo(164,98);c.quadraticCurveTo(164,88,174,88);c.lineTo(202,88);c.quadraticCurveTo(212,88,218,98);c.lineTo(232,130);c.lineTo(232,188);c.closePath();c.fill();c.stroke()
c.fillStyle=WIN;c.lineWidth=5;c.beginPath();c.moveTo(178,100);c.lineTo(204,100);c.lineTo(218,128);c.lineTo(178,128);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.ellipse(188,110,3,7,.4,0,T);c.fill()
c.fillStyle=CABD;c.beginPath();c.rect(164,160,68,10);c.fill();c.beginPath();c.moveTo(164,160);c.lineTo(232,160);c.moveTo(164,170);c.lineTo(232,170);c.stroke()
c.lineWidth=4;c.beginPath();c.moveTo(184,140);c.lineTo(196,140);c.stroke()
c.fillStyle='#ffd43b';c.lineWidth=5;c.beginPath();c.roundRect(222,134,14,14,4);c.fill();c.stroke()
c.fillStyle='#111';c.beginPath();c.arc(210,144,4,0,T);c.fill()
c.fillStyle=BL;c.beginPath();c.ellipse(202,178,6,3.5,0,0,T);c.fill()
c.lineWidth=4;c.beginPath();c.arc(216,174,6,.2*PI,.8*PI);c.stroke()
c.translate(0,-b)
for(const x of[78,196]){
c.lineWidth=7;c.fillStyle=TIRE;c.beginPath();c.arc(x,194,22,0,T);c.fill();c.stroke()
c.fillStyle=HUB;c.beginPath();c.arc(x,194,10,0,T);c.fill();c.lineWidth=4;c.stroke()
for(let k=0;k<4;k++){const a=rot+k*PI/2;c.beginPath();c.moveTo(x+cos(a)*4,194+sin(a)*4);c.lineTo(x+cos(a)*9,194+sin(a)*9);c.stroke()}
}
}
+33
View File
@@ -0,0 +1,33 @@
// spinning gold coins dropping one after another into a happy purple wallet that gulps and bounces with each one
const{sin,cos,PI,abs,max,min}=Math,T=2*PI
export const frames=24,delay=60
const G='#ffd43b',GD='#f59f00',WF='#b197fc',WB='#7950f2',WT='#9775fa',BILL='#8ce99a',BL='#ffa8a8'
const C=[[100,0],[148,1/3],[122,2/3]]
const sp=(c,x,y,s)=>{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()}
export default(c,t)=>{
let bump=0
for(const[x,o]of C){const p=(t+o)%1,q=(p-.42)/.2;if(q>0&&q<1)bump=max(bump,sin(PI*q))}
c.translate(128,234);c.scale(1+.05*bump,1-.07*bump);c.translate(-128,-234)
c.fillStyle=WB;c.beginPath();c.roundRect(42,104,172,122,18);c.fill();c.stroke()
c.save();c.translate(150,96);c.rotate(.12);c.fillStyle=BILL;c.beginPath();c.roundRect(-34,-26,68,60,4);c.fill();c.stroke()
c.lineWidth=4;c.beginPath();c.arc(0,-2,9,0,T);c.stroke();c.restore();c.lineWidth=7
for(const[x,o]of C){
const p=(t+o)%1;if(p>.44)continue
const u=p/.44,y=34+114*u*u,w=max(6,28*abs(cos(u*PI*1.5))),xx=x+8*sin(u*PI)
c.save();c.translate(xx,y);c.scale(min(1,u*5),min(1,u*5))
c.fillStyle=GD;c.lineWidth=5;c.beginPath();c.ellipse(0,0,w,28,0,0,T);c.fill();c.stroke()
c.fillStyle=G;c.beginPath();c.ellipse(0,0,w*.78,22,0,0,T);c.fill()
if(w>12){c.scale(w/28,1);c.lineWidth=4.5/(w/28);c.beginPath();c.moveTo(7,-8);c.bezierCurveTo(4,-14,-10,-13,-9,-5);c.bezierCurveTo(-8,2,9,-1,9,6);c.bezierCurveTo(9,14,-6,15,-9,8);c.moveTo(0,-17);c.lineTo(0,17);c.stroke()}
c.restore()
}
c.lineWidth=7;c.fillStyle=WF;c.beginPath();c.roundRect(32,128,192,104,20);c.fill();c.stroke()
c.fillStyle=WT;c.beginPath();c.roundRect(176,150,56,46,12);c.fill();c.stroke()
c.fillStyle=G;c.lineWidth=5;c.beginPath();c.arc(214,173,8,0,T);c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=6;c.beginPath();c.moveTo(48,148);c.lineTo(48,168);c.stroke();c.strokeStyle='#111'
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(110+d*26,170-3*bump,6,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(108+d*26,167-3*bump,2.2,0,T),c.fill()
c.fillStyle='#111';c.beginPath();c.arc(110,184,10+3*bump,0,PI);c.closePath();c.fill()
c.fillStyle='#ff8787';c.beginPath();c.ellipse(110,190+2*bump,5,3,0,0,T);c.fill()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(110+d*44,186,8,4.5,0,0,T),c.fill()
for(const[x,o]of C){const p=(t+o)%1,q=(p-.42)/.2;if(q>0&&q<1)sp(c,x+(x<128?-34:34),112,14*sin(PI*q))}
}
+24
View File
@@ -0,0 +1,24 @@
// sad magnifying glass swaying side to side, big eyes peeking left and right for results, a little question mark bobbing beside it
const{sin,PI}=Math,T=2*PI
export const frames=14,delay=100
const RG='#9775fa',LN='#d0ebff',HN='#ffa94d',BL='#ffa8a8',QM='#ffd43b',SW='#74c0fc'
export default(c,t)=>{
const a=.14*sin(t*T),x=112+10*sin(t*T),y=100+3*sin(2*T*t),lk=sin(t*T+.7),qs=1+.08*sin(2*T*t)
c.save();c.translate(210,56+5*sin(2*T*t+1));c.scale(qs,qs);c.rotate(.15*sin(t*T))
for(const[w,s]of[[17,'#111'],[8,QM]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.arc(0,-14,13,PI*1.05,PI*2.45),c.lineTo(0,6),c.stroke()
c.strokeStyle='#111';c.fillStyle=QM;c.lineWidth=4;c.beginPath();c.arc(0,22,6.5,0,T);c.fill();c.stroke();c.restore()
c.save();c.translate(x,y);c.rotate(a)
c.save();c.rotate(PI/4);c.fillStyle=HN;c.beginPath();c.roundRect(76,-15,68,30,15);c.fill();c.stroke()
c.fillStyle=RG;c.beginPath();c.roundRect(66,-19,22,38,6);c.fill();c.stroke();c.restore()
c.fillStyle=RG;c.beginPath();c.arc(0,0,72,0,T);c.fill();c.stroke()
c.fillStyle=LN;c.beginPath();c.arc(0,0,56,0,T);c.fill();c.lineWidth=5;c.stroke()
c.strokeStyle='#fff';c.lineWidth=7;c.beginPath();c.arc(0,0,44,PI*1.08,PI*1.38);c.stroke();c.strokeStyle='#111'
c.lineWidth=4;c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*21,-4,13,0,T),c.fill(),c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(d*21+lk*5,-2,6.5,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*21+lk*5-2,-4,2,0,T),c.fill()
c.lineWidth=4.5;for(const d of[-1,1])c.beginPath(),c.moveTo(d*10,-26),c.lineTo(d*30,-21),c.stroke()
c.lineWidth=5;c.beginPath();c.arc(0,32,10,1.2*PI,1.8*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*36,16,7,4,0,0,T),c.fill()
c.fillStyle=SW;c.lineWidth=3;c.beginPath();c.moveTo(40,-34);c.quadraticCurveTo(47,-23,40,-21);c.quadraticCurveTo(33,-23,40,-34);c.fill();c.stroke()
c.restore()
}
+21
View File
@@ -0,0 +1,21 @@
// blue envelope with a heart seal flapping its little white wings as it flies off, a trail of puffs streaming out behind it
const{sin,cos,PI,min}=Math,T=2*PI
export const frames=18,delay=70
const EN='#a5d8ff',FL='#74c0fc',HT='#ff6b6b',BL='#ffa8a8'
const wing=c=>{c.beginPath();c.moveTo(-6,8);c.quadraticCurveTo(8,-40,54,-46);c.quadraticCurveTo(60,-30,44,-27);c.quadraticCurveTo(48,-13,30,-12);c.quadraticCurveTo(30,1,12,0);c.quadraticCurveTo(8,10,-6,8);c.fill();c.stroke()}
export default(c,t)=>{
const f=sin(3*T*t),y=126+5*f,B=(u,p,q,r,v)=>(1-u)**3*p+3*(1-u)**2*u*q+3*(1-u)*u*u*r+u**3*v
c.fillStyle='#fff';c.lineWidth=4
for(let k=0;k<8;k++){const u=((k+t*2)%8)/8,x=B(u,132,66,86,16),yy=B(u,y,y+10,214,226),r=10*(1-u)+2.5;c.beginPath();c.arc(x,yy,r,0,T);c.fill();c.stroke()}
c.translate(136,y);c.rotate(-.16+.04*sin(t*T))
c.lineWidth=6;c.fillStyle='#fff'
for(const d of[-1,1]){c.save();c.translate(d*50,-24);c.scale(d,1);c.rotate(.45*f-.15);wing(c);c.lineWidth=4;c.beginPath();c.moveTo(8,-14);c.quadraticCurveTo(24,-28,40,-34);c.stroke();c.restore()}
c.lineWidth=7;c.fillStyle=EN;c.beginPath();c.roundRect(-58,-40,116,80,10);c.fill();c.stroke()
c.fillStyle=FL;c.lineWidth=5;c.beginPath();c.moveTo(-55,-37);c.lineTo(0,4);c.lineTo(55,-37);c.closePath();c.fill();c.stroke()
c.fillStyle=HT;c.beginPath();c.moveTo(0,16);c.bezierCurveTo(-16,6,-12,-8,0,-1);c.bezierCurveTo(12,-8,16,6,0,16);c.fill();c.lineWidth=4;c.stroke()
c.fillStyle='#fff';c.beginPath();c.ellipse(-5,2,2.5,1.6,-.6,0,T);c.fill()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(d*30,14,5.5,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*30-2,12,2,0,T),c.fill()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*40,25,7,4,0,0,T),c.fill()
c.lineWidth=4;c.beginPath();c.arc(0,22,6,.2*PI,.8*PI);c.stroke()
}
+31
View File
@@ -0,0 +1,31 @@
// bunch of smiling balloons bobbing up on wavy strings tied with a bow, confetti fluttering down around them
const{sin,cos,PI,min}=Math,T=2*PI
export const frames=14,delay=100
const B=[[128,74,'#ffd43b',.2,36],[70,108,'#ff6b6b',0,33],[186,108,'#4dabf7',.55,33]],BL='#ffa8a8'
const CF=['#ff6b6b','#ffd43b','#4dabf7','#69db7c','#b197fc','#f783ac','#ffa94d']
export default(c,t)=>{
for(let k=0;k<9;k++){
const p=(t*(1+k%2)+k*.37)%1,x=(k*71+20)%200+28+10*sin(p*T*2+k),y=6+p*236,s=min(1,4*sin(PI*p))
if(s<.1)continue
c.save();c.translate(x,y);c.rotate(p*T*(1+k%3));c.scale(s,s);c.fillStyle=CF[k%7];c.lineWidth=3;c.beginPath()
if(k%3==0)c.rect(-7,-4,14,8);else if(k%3==1)c.arc(0,0,5,0,T);else c.moveTo(0,-7),c.lineTo(6,5),c.lineTo(-6,5),c.closePath()
c.fill();c.stroke();c.restore()
}
const b=-6*sin(t*T),K=[128,222+b*.4],P=B.map(([x,y,,o,r])=>[x+6*sin(t*T+o*T),y+b+4*sin(2*T*t+o*T),r])
for(const[w,st]of[[7,'#111'],[3,'#fff']]){c.lineWidth=w;c.strokeStyle=st;c.beginPath();for(const[x,y,r]of P){const w2=10*sin(2*T*t+x);c.moveTo(x,y+r*1.2+8);c.quadraticCurveTo((x+K[0])/2+w2,(y+K[1])/2+20,K[0],K[1])}c.stroke()}
c.strokeStyle='#111'
for(const[k,[x,y,r]]of P.entries()){
const col=B[k][2]
c.save();c.translate(x,y);c.rotate((x-128)/500)
c.lineWidth=5;c.fillStyle=col;c.beginPath();c.moveTo(0,r*1.12);c.lineTo(-7,r*1.2+9);c.lineTo(7,r*1.2+9);c.closePath();c.fill();c.stroke()
c.lineWidth=7;c.beginPath();c.ellipse(0,0,r,r*1.18,0,0,T);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.ellipse(-r*.45,-r*.5,r*.14,r*.26,.5,0,T);c.fill();c.beginPath();c.arc(-r*.2,-r*.82,r*.07,0,T);c.fill()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(d*r*.3,r*.06,4.5,0,T),c.fill()
c.lineWidth=4;c.beginPath();c.arc(0,r*.2,r*.2,.15*PI,.85*PI);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*r*.56,r*.3,6,3.5,0,0,T),c.fill()
c.restore()
}
c.save();c.translate(...K);c.fillStyle='#f783ac';c.lineWidth=4
for(const d of[-1,1])c.beginPath(),c.moveTo(0,0),c.lineTo(d*16,-9),c.lineTo(d*16,9),c.closePath(),c.fill(),c.stroke()
c.beginPath();c.arc(0,0,5,0,T);c.fill();c.stroke();c.restore()
}
+25
View File
@@ -0,0 +1,25 @@
// green badge pops in, a white check mark draws itself, a burst of colorful rays and sparkles goes off, then it shrinks away
const{sin,cos,PI,min,max,hypot}=Math,T=2*PI
export const frames=24,delay=60
const GR='#51cf66',GD='#37b24d',CF=['#ffd43b','#ff6b6b','#4dabf7','#f783ac']
const back=u=>{const s=2;return 1+(s+1)*(u-1)**3+s*(u-1)**2}
const P=[[90,132],[116,158],[168,100]],L=hypot(26,26)+hypot(52,58)
const sp=(c,x,y,s)=>{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()}
export default(c,t)=>{
const s=t<.15?back(t/.15):t>.85?1-((t-.85)/.15)**2:1,p=min(1,max(0,(t-.15)/.25)),b=(t-.38)/.32
if(b>0&&b<1){
for(let k=0;k<8;k++){
const a=k*T/8+PI/8,r1=88+30*b,r2=r1+22*(1-b)
for(const[w,st]of[[13,'#111'],[6,CF[k%4]]])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.moveTo(128+cos(a)*r1,128+sin(a)*r1),c.lineTo(128+cos(a)*r2,128+sin(a)*r2),c.stroke()
}
c.strokeStyle='#111'
for(let k=0;k<4;k++){const a=k*T/4-PI/2,r=92+16*b;sp(c,128+cos(a)*r,128+sin(a)*r,14*sin(PI*b))}
}
c.strokeStyle='#111'
if(s<=.01)return
c.translate(128,128);c.scale(s,s);c.translate(-128,-128);c.lineWidth=7/s
c.fillStyle=GR;c.beginPath();c.arc(128,128,76,0,T);c.fill();c.stroke()
c.strokeStyle=GD;c.lineWidth=6;c.beginPath();c.arc(128,128,62,0,T);c.stroke()
c.strokeStyle='#fff';c.beginPath();c.arc(128,128,66,PI*1.1,PI*1.38);c.stroke()
if(p>0)for(const[w,st]of[[28,'#111'],[16,'#fff']]){c.lineWidth=w;c.strokeStyle=st;c.setLineDash([L*p,999]);c.beginPath();for(const[x,y]of P)c.lineTo(x,y);c.stroke()}
}
+27
View File
@@ -0,0 +1,27 @@
// gold medal with a star swinging on its red and blue ribbon, a glint sliding across it and sparkles popping around
const{sin,cos,PI,max}=Math,T=2*PI
export const frames=14,delay=90
const G='#ffd43b',GD='#fab005',GE='#f59f00',RB=['#ff6b6b','#4dabf7']
const sp=(c,x,y,s)=>{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()}
const disc=(c,r)=>{c.beginPath();c.arc(0,170,r,0,T)}
export default(c,t)=>{
const a=.13*sin(t*T)
for(const[x,y,o]of[[38,120,0],[220,104,.33],[214,216,.66],[46,224,.5]]){const s=12*max(0,sin(PI*((t*2+o)%1)));if(s>1.5)sp(c,x,y,s)}
c.lineWidth=7;c.translate(128,20);c.rotate(a);c.scale(.94,.94)
for(const[k,d]of[[0,1],[1,-1]]){
const q=()=>{c.beginPath();c.moveTo(d*58,0);c.lineTo(d*22,0);c.lineTo(-d*16,112);c.lineTo(d*18,112);c.closePath()}
q();c.fillStyle=RB[k];c.fill()
c.save();q();c.clip();c.strokeStyle='#fff';c.lineWidth=9;c.beginPath();c.moveTo(d*40,0);c.lineTo(d*1,112);c.stroke();c.restore()
q();c.stroke()
}
c.fillStyle=GD;c.beginPath();c.roundRect(-20,100,40,22,7);c.fill();c.stroke()
disc(c,62);c.fillStyle=GD;c.fill();c.stroke()
disc(c,48);c.fillStyle=G;c.fill()
c.save();disc(c,48);c.clip()
c.fillStyle=GD;c.beginPath();c.arc(0,170,48,0,T);c.arc(-12,157,48,0,T,true);c.fill()
const g=t*360-120;c.strokeStyle='#fff';c.lineWidth=14;c.beginPath();c.moveTo(g-40,240);c.lineTo(g+30,100);c.stroke();c.lineWidth=5;c.beginPath();c.moveTo(g-16,240);c.lineTo(g+54,100);c.stroke()
c.restore()
c.lineWidth=5;disc(c,48);c.stroke()
c.fillStyle=GE;c.beginPath();for(let k=0;k<10;k++){const r=k%2?14:31,b=k*PI/5-PI/2;c.lineTo(cos(b)*r,172+sin(b)*r)}c.closePath();c.fill();c.lineWidth=4;c.stroke()
c.strokeStyle='#fff';c.lineWidth=6;c.beginPath();c.arc(0,170,54,PI*1.12,PI*1.36);c.stroke()
}
+37
View File
@@ -0,0 +1,37 @@
// two smiling phones tossing a file back and forth in a high arc, each one hopping as it catches, sync arrows spinning between them
const{sin,cos,PI,max}=Math,T=2*PI
export const frames=20,delay=80
const PL='#9775fa',PR='#ff8787',SC='#e7f5ff',FL='#fff',FC='#ffd43b',AR='#51cf66',BL='#ffa8a8'
const ease=u=>u*u*(3-2*u)
const phone=(c,x,col,tilt,hop,open)=>{
c.save();c.translate(x,236-hop);c.rotate(tilt)
c.fillStyle=col;c.beginPath();c.roundRect(-38,-148,76,148,18);c.fill();c.stroke()
c.fillStyle=SC;c.lineWidth=5;c.beginPath();c.roundRect(-28,-132,56,116,9);c.fill();c.stroke()
c.fillStyle='#111';c.beginPath();c.roundRect(-10,-144,20,5,2.5);c.fill()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.ellipse(d*12,-50,4.5,6,0,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*12-1.5,-52.5,1.8,0,T),c.fill()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*20,-38,5.5,3.5,0,0,T),c.fill()
c.lineWidth=4;c.beginPath()
if(open)c.fillStyle='#ff8787',c.moveTo(-6,-40),c.quadraticCurveTo(0,-26,6,-40),c.closePath(),c.fill()
else c.arc(0,-42,6,.15*PI,.85*PI)
c.stroke();c.restore();c.lineWidth=7
}
const file=(c,x,y,r)=>{
c.save();c.translate(x,y);c.rotate(r);c.lineWidth=5
c.fillStyle=FL;c.beginPath();c.moveTo(-18,-24);c.lineTo(8,-24);c.lineTo(18,-14);c.lineTo(18,24);c.lineTo(-18,24);c.closePath();c.fill();c.stroke()
c.fillStyle=FC;c.beginPath();c.moveTo(8,-24);c.lineTo(8,-14);c.lineTo(18,-14);c.closePath();c.fill();c.stroke()
c.strokeStyle='#4dabf7';c.lineWidth=4;c.beginPath();for(const y of[-8,2,12])c.moveTo(-9,y),c.lineTo(9,y);c.stroke()
c.restore();c.strokeStyle='#111';c.lineWidth=7
}
export default(c,t)=>{
const h=t<.5?0:1,u=((t*2)%1),fly=u<.72,f=fly?ease(u/.72):1,dir=h?-1:1
const x0=h?198:58,x1=h?58:198,fx=x0+(x1-x0)*f,fy=148-110*sin(PI*f),land=fly?0:(u-.72)/.28
const ca=fly?0:sin(PI*land)
phone(c,58,PL,-.1,h?ca*10:0,h&&!fly)
phone(c,198,PR,.1,h?0:ca*10,!h&&!fly)
c.save();c.translate(128,186);c.rotate(-T*t*2)
for(let k=0;k<2;k++){c.rotate(PI);for(const[w,s]of[[12,'#111'],[5,AR]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.arc(0,0,20,.25,PI-.5),c.stroke();c.strokeStyle='#111';c.lineWidth=4;c.fillStyle=AR;c.beginPath();const ex=cos(PI-.5)*20,ey=sin(PI-.5)*20;c.moveTo(ex-9,ey-4);c.lineTo(ex+3,ey-9);c.lineTo(ex+3,ey+5);c.closePath();c.fill();c.stroke()}
c.restore();c.lineWidth=7
if(fly&&f>.06&&f<.94)for(let k=1;k<=3;k++){const g=max(0,f-k*.07),gx=x0+(x1-x0)*g,gy=148-110*sin(PI*g);c.fillStyle='#fff';c.lineWidth=3;c.beginPath();c.arc(gx,gy,5-k,0,T);c.fill();c.stroke()}
file(c,fx+(fly?0:dir*ca*1),fy-ca*10,dir*.5*sin(PI*f)*(fly?1:0))
}
+30
View File
@@ -0,0 +1,30 @@
// clean empty trash bin flipping its lid open and shut with a big grin, sparkles popping out of it and twinkling all around
const{sin,PI,max}=Math,T=2*PI
export const frames=20,delay=80
const BN='#63e6be',BD='#20c997',RM='#38d9a9',IN='#c3fae8',BL='#ffa8a8',TG='#ff8787'
const E=u=>u<0?0:u>1?1:u*u*(3-2*u)
const sp=(c,x,y,s)=>{if(s<1.5)return;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()}
const bod=c=>{c.beginPath();c.moveTo(70,112);c.lineTo(186,112);c.lineTo(176,236);c.lineTo(80,236);c.closePath()}
export default(c,t)=>{
const o=E((t-.08)/.14)-E((t-.56)/.08),b=t>.64&&t<.76?sin(PI*(t-.64)/.12):0,th=.55*o+.12*b,q=t>.62&&t<.8?sin(PI*(t-.62)/.18):0
for(const[x,y,f,s]of[[34,150,0,13],[222,140,.3,12],[28,222,.55,11],[228,214,.8,14]])sp(c,x,y,s*max(0,sin(PI*((t*2+f)%1))))
c.save();c.translate(128,236);c.scale(1+.04*q,1-.06*q);c.translate(-128,-236)
c.fillStyle=BN;bod(c);c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=7;c.beginPath();c.moveTo(86,128);c.lineTo(91,184);c.stroke()
c.strokeStyle=BD;c.lineWidth=6;c.beginPath();for(const x of[104,128,152])c.moveTo(x,198),c.lineTo(x+(x-128)*.06,222);c.stroke()
c.strokeStyle='#111';c.fillStyle='#111'
if(th>.15)c.lineWidth=5,[-1,1].forEach(d=>{c.beginPath();c.arc(128+d*20,156,7,1.15*PI,1.85*PI);c.stroke()})
else[-1,1].forEach(d=>{c.beginPath();c.arc(128+d*20,152,6.5,0,T);c.fill()}),c.fillStyle='#fff',[-1,1].forEach(d=>{c.beginPath();c.arc(126+d*20,150,2.2,0,T);c.fill()})
c.fillStyle='#111';c.lineWidth=4;c.beginPath();c.moveTo(112,170);c.quadraticCurveTo(128,196,144,170);c.closePath();c.fill();c.stroke()
c.fillStyle=TG;c.beginPath();c.ellipse(128,184,7,4,0,0,T);c.fill()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*38,172,8,5,0,0,T),c.fill()
c.lineWidth=7;c.fillStyle=RM;c.beginPath();c.roundRect(62,104,132,16,8);c.fill();c.stroke()
if(th>.05){c.fillStyle=IN;c.lineWidth=5;c.beginPath();c.ellipse(128,108,56,7,0,0,T);c.fill();c.stroke()}
c.restore()
const u=(t-.18)/.42
if(u>0&&u<1)for(const[x,f,s]of[[104,0,13],[150,.2,11],[126,.4,15]]){const v=(u-f)/.6;if(v>0&&v<1)sp(c,x+8*sin(v*T),104-80*v,s*sin(PI*v))}
c.save();c.translate(198,104-4*q);c.rotate(th);c.fillStyle=RM;c.lineWidth=7
c.beginPath();c.roundRect(-92,-28,32,16,7);c.fill();c.stroke()
c.beginPath();c.roundRect(-150,-18,156,20,9);c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();c.moveTo(-136,-10);c.lineTo(-112,-10);c.stroke();c.restore()
}
+35
View File
@@ -0,0 +1,35 @@
// happy rocket blasting up and away with a file strapped to its nose, flame flickering, speed streaks and little clouds rushing past
const{sin,PI,round}=Math,T=2*PI
export const frames=16,delay=70
const RD='#ff6b6b',NZ='#adb5bd',FO='#ff922b',FY='#ffd43b',AR='#4dabf7',LN='#d0ebff',BL='#ffa8a8'
const cloud=(c,x,y,s)=>{const b=[[-14*s,3*s,10*s],[2*s,-4*s,13*s],[17*s,3*s,9*s]];c.lineWidth=13;for(const[a,d,r]of b)c.beginPath(),c.arc(x+a,y+d,r,0,T),c.stroke();c.fillStyle='#fff';for(const[a,d,r]of b)c.beginPath(),c.arc(x+a,y+d,r,0,T),c.fill();c.lineWidth=7}
export default(c,t,i)=>{
const b=round(4*sin(T*t)),w=.04*sin(2*T*t),fh=26+(i%2?10:0)+4*sin(4*T*t)
c.translate(128,128);c.rotate(.6)
for(const[x,o,L]of[[-56,0,40],[58,.5,40],[-70,.3,30],[72,.8,30]]){
const p=(t*2+o)%1,y=-50+p*120,l=L*sin(PI*p)
for(const[lw,s]of[[11,'#111'],[5,'#fff']])c.lineWidth=lw,c.strokeStyle=s,c.beginPath(),c.moveTo(x,y-l/2),c.lineTo(x,y+l/2),c.stroke()
}
c.strokeStyle='#111'
for(const[x,o]of[[-88,.1],[90,.6]]){const p=(t+o)%1,s=sin(PI*p);if(s>.15)cloud(c,x,-46+p*92,.85*s)}
c.translate(0,8+b);c.rotate(w);c.scale(.94,.94)
c.fillStyle=FO;c.lineWidth=5;c.beginPath();c.moveTo(-18,66);c.quadraticCurveTo(-20,66+fh*.6,0,66+fh);c.quadraticCurveTo(20,66+fh*.6,18,66);c.closePath();c.fill();c.stroke()
c.fillStyle=FY;c.beginPath();c.moveTo(-10,66);c.quadraticCurveTo(-10,66+fh*.45,0,66+fh*.7);c.quadraticCurveTo(10,66+fh*.45,10,66);c.closePath();c.fill()
c.lineWidth=7;c.fillStyle=NZ;c.beginPath();c.roundRect(-20,54,40,16,5);c.fill();c.stroke()
c.fillStyle=RD;for(const d of[-1,1]){c.beginPath();c.moveTo(d*24,18);c.quadraticCurveTo(d*50,30,d*50,64);c.lineTo(d*24,52);c.closePath();c.fill();c.stroke()}
const bd=()=>{c.beginPath();c.moveTo(0,-56);c.bezierCurveTo(34,-40,34,0,30,58);c.lineTo(-30,58);c.bezierCurveTo(-34,0,-34,-40,0,-56);c.closePath()}
c.fillStyle='#fff';bd();c.fill();c.save();bd();c.clip();c.fillStyle=RD;c.fillRect(-40,-70,80,34);c.fillRect(-40,44,80,20);c.restore();bd();c.stroke()
c.lineWidth=4;c.beginPath();c.moveTo(-31,-36);c.lineTo(31,-36);c.moveTo(-31,44);c.lineTo(31,44);c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.ellipse(d*12,2,5,7,0,0,T),c.fill()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(d*12-2,-1,2.2,0,T),c.fill()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*20,15,6,3.5,0,0,T),c.fill()
c.lineWidth=4.5;c.fillStyle='#ff8787';c.beginPath();c.moveTo(-7,11);c.quadraticCurveTo(0,23,7,11);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.ellipse(-20,-14,3.5,9,.15,0,T);c.fill()
c.save();c.translate(0,-86);c.rotate(-1.4*w)
for(const[lw,s]of[[9,'#111'],[4,'#ffd8a8']])c.lineWidth=lw,c.strokeStyle=s,c.beginPath(),c.moveTo(-20,28),c.lineTo(-4,36),c.moveTo(20,28),c.lineTo(4,36),c.stroke()
c.strokeStyle='#111';c.lineWidth=6;c.fillStyle='#fff'
c.beginPath();c.moveTo(-26,-38);c.lineTo(12,-38);c.lineTo(26,-24);c.lineTo(26,30);c.lineTo(-26,30);c.closePath();c.fill();c.stroke()
c.fillStyle=LN;c.lineWidth=5;c.beginPath();c.moveTo(12,-38);c.lineTo(12,-24);c.lineTo(26,-24);c.closePath();c.fill();c.stroke()
for(const[lw,s]of[[13,'#111'],[6,AR]])c.lineWidth=lw,c.strokeStyle=s,c.beginPath(),c.moveTo(0,16),c.lineTo(0,-18),c.moveTo(-12,-6),c.lineTo(0,-20),c.lineTo(12,-6),c.stroke()
c.restore()
}
+36
View File
@@ -0,0 +1,36 @@
// open wallet with nothing in it, a dusty moth flutters up out of the money pocket while the wallet sweats nervously
const{sin,cos,PI,abs,min}=Math,T=2*PI
export const frames=24,delay=80
const WB='#c08457',WF='#e0a96d',WI='#5c3d2e',ST='#ffe8cc',MW='#ffe8cc',MS='#e0a96d',MB='#ced4da',BL='#ffa8a8',DU='#e9ecef',SW='#74c0fc'
const moth=(c,x,y,s,f,r)=>{
c.save();c.translate(x,y);c.rotate(r);c.scale(s,s);c.strokeStyle='#111'
for(const d of[-1,1]){c.save();c.scale(d*f,1);c.fillStyle=MW;c.lineWidth=5
c.beginPath();c.moveTo(0,4);c.bezierCurveTo(24,4,34,22,24,32);c.bezierCurveTo(14,40,4,26,0,10);c.fill();c.stroke()
c.beginPath();c.moveTo(0,-4);c.bezierCurveTo(18,-32,50,-30,46,-8);c.bezierCurveTo(44,8,16,10,0,4);c.fill();c.stroke()
c.fillStyle=MS;c.beginPath();c.arc(30,-10,6,0,T);c.fill();c.beginPath();c.arc(16,20,4,0,T);c.fill();c.restore()}
for(const d of[-1,1])for(const[w,st]of[[7,'#111'],[3,MW]])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.moveTo(d*3,-16),c.quadraticCurveTo(d*6,-30,d*16,-34),c.stroke()
c.strokeStyle='#111';c.lineWidth=4.5;c.fillStyle=MB;c.beginPath();c.ellipse(0,8,8,20,0,0,T);c.fill();c.stroke()
c.beginPath();c.arc(0,-13,9,0,T);c.fill();c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(d*3.5,-14,2,0,T),c.fill()
c.restore()
}
const pos=u=>[128+30*sin(u*T*1.5)*min(1,u*3),184-240*u]
export default(c,t)=>{
const u=t/.8
c.fillStyle=WB;c.beginPath();c.roundRect(42,86,172,70,18);c.fill();c.stroke()
c.setLineDash([7,6]);c.strokeStyle=ST;c.lineWidth=3;c.beginPath();c.moveTo(60,100);c.lineTo(196,100);c.stroke();c.setLineDash([])
c.strokeStyle='#111';c.fillStyle=WI;c.lineWidth=6;c.beginPath();c.roundRect(50,116,156,28,12);c.fill();c.stroke()
if(u<1){const[x,y]=pos(u);moth(c,x,y,1.15,.25+.75*abs(cos(5*PI*t)),.25*cos(u*T*1.5))
for(let k=1;k<4;k++){const[dx,dy]=pos(u-k*.05),r=7-k*1.5;if(dy<120&&u-k*.05>0)c.fillStyle=DU,c.lineWidth=3,c.beginPath(),c.arc(dx+(k%2?10:-10),dy+40,r,0,T),c.fill(),c.stroke()}}
c.lineWidth=7;c.fillStyle=WF;c.beginPath();c.roundRect(30,130,188,104,22);c.fill();c.stroke()
c.setLineDash([8,7]);c.strokeStyle=ST;c.lineWidth=3;c.beginPath();c.roundRect(42,142,164,80,14);c.stroke();c.setLineDash([])
c.strokeStyle='#111';c.fillStyle=WB;c.lineWidth=6;c.beginPath();c.roundRect(164,158,68,48,16);c.fill();c.stroke()
c.fillStyle='#ffd43b';c.lineWidth=4;c.beginPath();c.arc(210,182,7,0,T);c.fill();c.stroke()
const bl=(t*3)%1<.06,X=104
c.fillStyle='#111';for(const d of[-1,1])bl?(c.lineWidth=4.5,c.beginPath(),c.moveTo(X+d*24-6,180),c.lineTo(X+d*24+6,180),c.stroke()):(c.beginPath(),c.arc(X+d*24,180,6.5,0,T),c.fill())
if(!bl){c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(X-2+d*24,178,2.2,0,T),c.fill()}
c.lineWidth=4.5;for(const d of[-1,1])c.beginPath(),c.moveTo(X+d*14,162),c.lineTo(X+d*32,167),c.stroke()
c.beginPath();for(let x=-12;x<=12;x+=2)c.lineTo(X+x,202+2.5*sin(x/2.5));c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(X+d*44,194,8,5,0,0,T),c.fill()
const sy=(t*2)%1*8;c.fillStyle=SW;c.lineWidth=3;c.beginPath();c.moveTo(148,150+sy);c.quadraticCurveTo(155,161+sy,148,163+sy);c.quadraticCurveTo(141,161+sy,148,150+sy);c.fill();c.stroke()
}
+25
View File
@@ -0,0 +1,25 @@
// alarmed red siren on a hazard-striped base, its light spinning inside the dome, sweeping beams side to side and flashing bright when it faces you
const{sin,cos,PI,max,abs,sign}=Math,T=2*PI
export const frames=20,delay=50
const RD='#fa5252',RB='#ff8787',GL='#fff3bf',BM='#ffc9c9',HZ='#ffd43b',KN='#868e96'
const dome=c=>{c.beginPath();c.moveTo(66,186);c.lineTo(66,124);c.arc(128,124,62,PI,0);c.lineTo(190,186);c.closePath()}
export default(c,t)=>{
const a=2*T*t,s=sin(a),k=cos(a),I=max(0,abs(s)-.25)/.75,fr=k>.55
if(I>0){const d=sign(s);c.fillStyle=BM;c.lineWidth=5;c.beginPath();c.moveTo(128+d*48,112);c.lineTo(128+d*112,124-60*I);c.lineTo(128+d*112,124+60*I);c.lineTo(128+d*48,140);c.closePath();c.fill();c.stroke()}
if(fr)for(const r of[-.84,-.67,-.5,-.33,-.16]){const b=r*PI,l=14+10*(k-.55)/.45;for(const[w,st]of[[11,'#111'],[5,HZ]])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.moveTo(128+cos(b)*80,124+sin(b)*80),c.lineTo(128+cos(b)*(80+l),124+sin(b)*(80+l)),c.stroke()}
c.strokeStyle='#111';c.lineWidth=7
c.fillStyle=KN;c.beginPath();c.roundRect(114,50,28,16,6);c.fill();c.stroke()
dome(c);c.fillStyle=fr?RB:RD;c.fill()
c.save();dome(c);c.clip()
if(k>0){const x=128+46*s,w=34*max(.18,k);c.fillStyle=GL;c.beginPath();c.ellipse(x,128,w,52,0,0,T);c.fill();c.fillStyle='#fff';c.beginPath();c.ellipse(x,128,w*.45,30,0,0,T);c.fill()}
c.restore()
dome(c);c.stroke()
c.strokeStyle='#fff';c.lineWidth=7;c.beginPath();c.arc(128,124,48,PI*1.1,PI*1.36);c.stroke();c.beginPath();c.moveTo(80,128);c.lineTo(80,150);c.stroke();c.strokeStyle='#111'
c.lineWidth=5;c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*22,136,11,13,0,0,T),c.fill(),c.stroke()
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+d*22,138,5,0,T),c.fill()
c.lineWidth=4.5;for(const d of[-1,1])c.beginPath(),c.arc(128+d*22,120,11,PI*1.25,PI*1.75),c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(128,166,8,9,0,0,T);c.fill()
c.lineWidth=7;c.fillStyle=HZ;c.beginPath();c.roundRect(44,182,168,44,10);c.fill()
c.save();c.clip();c.strokeStyle='#111';c.lineWidth=12;c.beginPath();for(let x=30;x<240;x+=32)c.moveTo(x,230),c.lineTo(x+36,178);c.stroke();c.restore()
c.beginPath();c.roundRect(44,182,168,44,10);c.stroke()
}
+34
View File
@@ -0,0 +1,34 @@
// blue front door swings open toward you, warm golden light pours out with sparkles over a heart welcome mat, then it eases shut
const{sin,cos,PI,min,max}=Math,T=2*PI
export const frames=20,delay=80
const FR='#a9744f',FRD='#8d6346',DR='#4dabf7',DRD='#339af0',IN='#ffd43b',GLOW='#fff3bf',MAT='#ff6b6b',MATL='#ffa8a8',KN='#ffd43b'
const back=u=>{const s=1.4;return 1+(s+1)*(u-1)**3+s*(u-1)**2},io=u=>u*u*(3-2*u)
const sp=(c,x,y,s)=>{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()}
const X0=76,X1=180,Y0=36,Y1=208
export default(c,t)=>{
const o=t<.08?0:t<.36?back((t-.08)/.28):t<.78?1:t<.94?1-io((t-.78)/.16):0,th=o*1.2,fx=X0+(X1-X0)*cos(th),d=18*sin(th)
const m=(u,v)=>[X0+u*(fx-X0),(Y0-d*u)+v*((Y1+d*u)-(Y0-d*u))],q=(u0,v0,u1,v1)=>{c.beginPath();for(const[u,v]of[[u0,v0],[u1,v0],[u1,v1],[u0,v1]])c.lineTo(...m(u,v));c.closePath()}
const L=min(1,o*1.5)
if(L>.05)for(let k=0;k<6;k++){
const e=k%3-1,a=k<3?e*.5:PI-e*.5,tw=.75+.25*sin(2*T*t+k*2),x=128+(k<3?78:-78),y=118+e*64,l=24*L*tw
for(const[w,s]of[[11,'#111'],[5,IN]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(x,y),c.lineTo(x+cos(a)*l,y+sin(a)*l),c.stroke()
}
c.strokeStyle='#111';c.lineWidth=7
c.fillStyle=FR;c.beginPath();c.roundRect(60,20,136,196,[18,18,4,4]);c.fill();c.stroke()
c.fillStyle=FRD;c.fillRect(64,24,8,188)
c.fillStyle=IN;c.beginPath();c.rect(X0,Y0,X1-X0,Y1-Y0);c.fill()
c.save();c.clip();c.fillStyle=GLOW;c.beginPath();c.ellipse(140,120,40*L+4,70*L+4,0,0,T);c.fill();c.restore()
c.lineWidth=5;c.beginPath();c.rect(X0,Y0,X1-X0,Y1-Y0);c.stroke()
c.lineWidth=7;c.fillStyle=MAT;c.beginPath();c.roundRect(46,212,164,30,8);c.fill();c.stroke()
c.strokeStyle=MATL;c.lineWidth=4;c.beginPath();c.roundRect(56,219,144,16,4);c.stroke();c.strokeStyle='#111'
c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.moveTo(128,234);c.bezierCurveTo(112,226,116,214,128,221);c.bezierCurveTo(140,214,144,226,128,234);c.fill();c.stroke()
if(L>.3)for(const[x0,y0,ph]of[[150,150,0],[118,96,.33],[160,70,.66]]){const p=(t*2+ph)%1,s=11*sin(PI*p)*min(1,(L-.3)*3);if(s>1.5)sp(c,x0+30*p,y0-26*p,s)}
c.lineWidth=7;q(0,0,1,1);c.fillStyle=DR;c.fill();c.stroke()
if(th<1.45){
c.fillStyle=DRD;c.lineWidth=5
for(const[u0,v0,u1,v1]of[[.18,.5,.82,.68],[.18,.74,.82,.9]])q(u0,v0,u1,v1),c.fill(),c.stroke()
c.fillStyle=IN;c.beginPath();for(let k=0;k<24;k++){const a=k*T/24;c.lineTo(...m(.5+.26*cos(a),.25+.15*sin(a)))}c.closePath();c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=4;c.beginPath();for(let k=0;k<6;k++){const a=PI*1.1+k*.08;c.lineTo(...m(.5+.19*cos(a),.25+.11*sin(a)))}c.stroke();c.strokeStyle='#111'
const[kx,ky]=m(.86,.46);c.fillStyle=KN;c.lineWidth=4;c.beginPath();c.ellipse(kx,ky,7*max(.35,cos(th)),7,0,0,T);c.fill();c.stroke()
}
}