diff --git a/gen/bee/buzz.js b/gen/bee/buzz.js new file mode 100644 index 0000000..e897571 --- /dev/null +++ b/gen/bee/buzz.js @@ -0,0 +1,22 @@ +// bee buzzing around a figure eight, wings flapping every frame, dotted trail behind it +const{sin,cos,PI}=Math,T=2*PI +export const frames=24,delay=50 +const Z=1.45,pos=t=>[128+52*sin(t*T),128+32*sin(2*t*T)] +export default(c,t,i)=>{ + c.lineWidth=3 + for(let k=1;k<=7;k++){const[x,y]=pos(t-k*.035);c.beginPath();c.arc(x,y,4,0,T);c.fill();c.stroke()} + const[x,y]=pos(t),dx=cos(t*T),dy=2*cos(2*t*T)*32/52,w=n=>c.lineWidth=n/Z + c.translate(x,y);c.scale(dx<0?-Z:Z,Z);c.rotate(.25*dy*(dx<0?-1:1)) + w(5);const f=i%2?1:.55 + for(const[wx,wy,r]of[[-6,-26,-.4],[10,-24,.35]])c.beginPath(),c.ellipse(wx,wy-(1-f)*6,13,22*f,r,0,T),c.fill(),c.stroke() + c.fillStyle='#111';c.beginPath();c.moveTo(-30,-6);c.lineTo(-46,0);c.lineTo(-30,6);c.closePath();w(4);c.fill();c.stroke() + c.fillStyle='#fff';w(7);c.beginPath();c.ellipse(0,0,33,25,0,0,T);c.fill() + c.save();c.clip();c.fillStyle='#111';c.fillRect(-22,-30,11,60);c.fillRect(-3,-30,11,60);c.restore();c.stroke() + for(const[x0,y0,x1,y1]of[[22,-20,32,-40],[14,-22,16,-42]]){ + for(const[l,s]of[[9,'#111'],[3,'#fff']])w(l),c.strokeStyle=s,c.beginPath(),c.moveTo(x0,y0),c.lineTo(x1,y1),c.stroke() + w(4);c.strokeStyle='#111';c.fillStyle='#fff';c.beginPath();c.arc(x1,y1,4.5,0,T);c.fill();c.stroke() + } + c.fillStyle='#111';c.beginPath();c.arc(21,-5,4.5,0,T);c.fill() + c.fillStyle='#fff';c.beginPath();c.arc(20,-7,1.6,0,T);c.fill() + w(4);c.beginPath();c.arc(22,4,6,.1*PI,.6*PI);c.stroke() +} diff --git a/gen/blob/jiggle.js b/gen/blob/jiggle.js new file mode 100644 index 0000000..2d4efd1 --- /dev/null +++ b/gen/blob/jiggle.js @@ -0,0 +1,17 @@ +// slime blob jiggling: squashes and stretches, a ripple rolls over its top, mouth goes "o" +const{sin,cos,PI}=Math,T=2*PI +export default(c,t)=>{ + const q=sin(2*T*t),rx=80*(1+.07*q),ry=92*(1-.09*q),cy=212 + c.beginPath() + for(let a=PI;a<=T+.01;a+=.04){const r=1+.025*sin(3*a-2*T*t);c.lineTo(128+rx*r*cos(a),cy+ry*r*sin(a))} + c.ellipse(128,cy,rx,16,0,0,PI);c.closePath();c.fill();c.stroke() + c.lineWidth=6;c.beginPath();c.arc(128,cy,ry*.78,PI*1.16,PI*1.33);c.stroke() + const fy=cy-ry*.45 + c.fillStyle='#111' + for(const d of[-1,1]){ + c.beginPath();c.ellipse(128+d*28,fy,11,15*(1-.08*q),0,0,T);c.fill() + c.fillStyle='#fff';c.beginPath();c.arc(128+d*28-4,fy-6,4.5,0,T);c.fill();c.fillStyle='#111' + } + c.beginPath();c.ellipse(128,fy+30,9+3*q,11-2*q,0,0,T);c.fill() + c.lineWidth=3;for(const d of[-1,1])for(const k of[-5,0,5])c.beginPath(),c.moveTo(128+d*52+k-2,fy+24),c.lineTo(128+d*52+k+2,fy+17),c.stroke() +} diff --git a/gen/chick/hatch.js b/gen/chick/hatch.js new file mode 100644 index 0000000..7974f29 --- /dev/null +++ b/gen/chick/hatch.js @@ -0,0 +1,22 @@ +// egg wobbles, then the top pops up and a chick peeks out, blinks, and ducks back in +const{sin,cos,PI,max,min,asin}=Math,T=2*PI +export const frames=24,delay=70 +const X=128,Y=150,RX=62,RY=78,CY=140,a0=asin((CY-Y)/RY),L=X-RX*cos(a0),W=2*RX*cos(a0) +const zig=(c,ltr)=>{for(let k=0;k<=8;k++)c.lineTo(L+W*(ltr?k:8-k)/8,CY+(k%2?8:-8))} +export default(c,t)=>{ + const o=min(1,max(0,(t-.08)/.6)),lift=sin(PI*o),w=t>.72?.08*sin((t-.72)/.28*2*T)*sin(PI*(t-.72)/.28):0 + c.translate(X,228);c.rotate(w);c.translate(-X,-228) + const hy=184-56*lift + c.beginPath();c.arc(X,hy,36,0,T);c.fill();c.stroke() + for(const d of[-1,1])c.beginPath(),c.arc(X+d*6,hy-36,9,d<0?PI*1.1:PI*1.5,d<0?PI*1.5:PI*1.9),c.stroke() + c.fillStyle='#111' + for(const d of[-1,1]) + if(o>.45&&o<.55)c.lineWidth=4,c.beginPath(),c.moveTo(X+d*14-5,hy-4),c.lineTo(X+d*14+5,hy-4),c.stroke() + else c.beginPath(),c.arc(X+d*14,hy-4,5,0,T),c.fill() + c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.moveTo(X-8,hy+6);c.lineTo(X+8,hy+6);c.lineTo(X,hy+15);c.closePath();c.fill();c.stroke() + c.lineWidth=3;for(const d of[-1,1])for(const k of[-4,0,4])c.beginPath(),c.moveTo(X+d*24+k-2,hy+12),c.lineTo(X+d*24+k+2,hy+6),c.stroke() + c.lineWidth=7 + c.beginPath();c.ellipse(X,Y,RX,RY,0,a0,PI-a0);zig(c,1);c.closePath();c.fill();c.stroke() + c.translate(L,CY);c.rotate(-.5*lift);c.translate(-L,-CY-30*lift) + c.beginPath();c.ellipse(X,Y,RX,RY,0,PI-a0,T+a0);zig(c,0);c.closePath();c.fill();c.stroke() +} diff --git a/gen/flower/bloom.js b/gen/flower/bloom.js new file mode 100644 index 0000000..b6ca497 --- /dev/null +++ b/gen/flower/bloom.js @@ -0,0 +1,22 @@ +// potted flower swaying while its petals open wide and close back into a bud +const{sin,cos,PI}=Math,T=2*PI +export const frames=20,delay=90 +export default(c,t)=>{ + const k=.55-.45*cos(t*T),hx=128+10*sin(t*T),hy=100 + for(const[l,s]of[[16,'#111'],[4,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(128,206),c.quadraticCurveTo(128,150,hx,hy),c.stroke() + c.lineWidth=7;c.strokeStyle='#111' + for(const d of[-1,1]){ + const lx=128+d*4+(hx-128)*.3,ly=168 + c.save();c.translate(lx,ly);c.rotate(d*(-.6+.08*sin(t*T+d)));c.beginPath();c.moveTo(0,0);c.quadraticCurveTo(d*16,-22,d*40,-6);c.quadraticCurveTo(d*20,8,0,0);c.restore();c.fill();c.stroke() + } + for(let p=0;p<8;p++){ + const a=p*T/8+t*T/8,o=18+16*k + c.save();c.translate(hx+o*cos(a),hy+o*sin(a));c.rotate(a+PI/2);c.beginPath();c.ellipse(0,0,10+8*k,14+18*k,0,0,T);c.restore();c.fill();c.stroke() + } + c.beginPath();c.arc(hx,hy,24,0,T);c.fill();c.stroke() + c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.arc(hx+d*8,hy-2,4,PI*1.1,PI*1.9),c.stroke() + c.beginPath();c.arc(hx,hy+4,7,.15*PI,.85*PI);c.stroke() + c.lineWidth=7 + c.beginPath();c.moveTo(98,212);c.lineTo(158,212);c.lineTo(150,244);c.lineTo(106,244);c.closePath();c.fill();c.stroke() + c.beginPath();c.roundRect(90,198,76,16,5);c.fill();c.stroke() +} diff --git a/gen/moon/sleep.js b/gen/moon/sleep.js new file mode 100644 index 0000000..157bd24 --- /dev/null +++ b/gen/moon/sleep.js @@ -0,0 +1,24 @@ +// crescent moon sleeping and rocking gently while z's drift up and two stars twinkle +const{sin,cos,PI}=Math,T=2*PI +export const frames=20,delay=90 +export default(c,t)=>{ + for(const[x,y,p]of[[44,58,0],[214,206,.5]]){ + const s=8+6*(1+sin((t+p)*T))/2 + c.lineWidth=5;c.beginPath() + for(let k=0;k<8;k++){const r=k%2?s*.35:s,a=k*PI/4-PI/2;c.lineTo(x+r*cos(a),y+r*sin(a))} + c.closePath();c.fill();c.stroke() + } + c.save();c.translate(128,128);c.rotate(.06*sin(t*T));c.translate(-128,-128) + c.lineWidth=7;c.beginPath();c.arc(124,132,72,0,T);c.fill();c.stroke() + c.globalCompositeOperation='destination-out';c.beginPath();c.arc(162,104,63.5,0,T);c.fill();c.globalCompositeOperation='source-over' + c.save();c.beginPath();c.arc(124,132,75.5,0,T);c.clip();c.beginPath();c.arc(162,104,60,0,T);c.stroke();c.restore() + c.lineWidth=5;c.beginPath();c.arc(84,134,9,.15*PI,.85*PI);c.stroke() + c.beginPath();c.arc(100,166,7,.1*PI,.9*PI);c.stroke() + c.lineWidth=3;for(const k of[-5,0,5])c.beginPath(),c.moveTo(80+k-2,154),c.lineTo(80+k+2,148),c.stroke() + c.restore() + for(let k=0;k<3;k++){ + const p=(t+k/3)%1,s=22*sin(PI*p),x=156+p*58,y=96-p*72 + if(s<2)continue + for(const[l,st]of[[12,'#111'],[5,'#fff']])c.lineWidth=l,c.strokeStyle=st,c.beginPath(),c.moveTo(x-s/2,y-s/2),c.lineTo(x+s/2,y-s/2),c.lineTo(x-s/2,y+s/2),c.lineTo(x+s/2,y+s/2),c.stroke() + } +} diff --git a/gen/robot/dance.js b/gen/robot/dance.js new file mode 100644 index 0000000..c1c5b17 --- /dev/null +++ b/gen/robot/dance.js @@ -0,0 +1,27 @@ +// little robot dancing: bouncing on its knees, swaying, swinging its arms, antenna blinking on the beat +const{sin,cos,PI}=Math,T=2*PI +export const delay=70 +export default(c,t)=>{ + const b=6*(1-cos(2*T*t))/2,sw=.08*sin(t*T),beat=t%.5<.25 + const D=(f,a=20,i=8)=>{for(const[l,s]of[[a,'#111'],[i,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),f(),c.stroke();c.lineWidth=7;c.strokeStyle='#111'} + for(const d of[-1,1]){const hx=128+d*20,kx=128+d*(24+b*1.6);D(()=>{c.moveTo(hx,186+b);c.lineTo(kx,208);c.lineTo(128+d*24,224)})} + for(const d of[-1,1])c.beginPath(),c.roundRect(128+d*24-15,222,30,12,6),c.fill(),c.stroke() + c.translate(128,190+b);c.rotate(sw);c.translate(-128,-190) + for(const d of[-1,1]){ + const a=-.1+.7*sin(2*T*t+(d>0?PI:0)),b=a-1,sx=128+d*44,sy=134 + const ex=sx+d*30*cos(a),ey=sy+30*sin(a),hx=ex+d*28*cos(b),hy=ey+28*sin(b) + D(()=>{c.moveTo(sx,sy);c.lineTo(ex,ey);c.lineTo(hx,hy)}) + c.lineWidth=6;c.beginPath();c.arc(hx,hy,10,0,T);c.fill();c.stroke();c.lineWidth=7 + } + c.beginPath();c.roundRect(84,118,88,68,12);c.fill();c.stroke() + c.fillStyle='#111';for(const[x,f]of[[110,1],[128,0],[146,1]])c.beginPath(),c.arc(x,140,6,0,T),f?c.fill():(c.lineWidth=4,c.stroke()) + c.lineWidth=4;for(const y of[160,168,176])c.beginPath(),c.moveTo(112,y),c.lineTo(144,y),c.stroke() + c.lineWidth=7;c.fillStyle='#fff' + c.beginPath();c.rect(120,108,16,12);c.fill();c.stroke() + for(const d of[-1,1])c.beginPath(),c.arc(128+d*42,78,8,0,T),c.fill(),c.stroke() + D(()=>{c.moveTo(128,46);c.lineTo(128,26)},12,5) + c.beginPath();c.arc(128,22,8,0,T);c.fillStyle=beat?'#111':'#fff';c.fill();c.stroke();c.fillStyle='#fff' + c.beginPath();c.roundRect(86,46,84,64,14);c.fill();c.stroke() + c.fillStyle='#111';for(const x of[108,148])c.beginPath(),c.roundRect(x-6,beat?66:70,12,beat?20:12,6),c.fill() + c.lineWidth=5;c.beginPath();c.arc(128,90,10,.15*PI,.85*PI);c.stroke() +} diff --git a/gen/sun/shine.js b/gen/sun/shine.js new file mode 100644 index 0000000..1aed255 --- /dev/null +++ b/gen/sun/shine.js @@ -0,0 +1,20 @@ +// sun in sunglasses, rays slowly turning and pulsing, a glint sliding across the lenses +const{sin,cos,PI,max}=Math,T=2*PI +export const frames=20,delay=80 +export default(c,t)=>{ + const rot=t*T/6 + for(let k=0;k<12;k++){ + const a=rot+k*T/12,r1=60,r2=(k%2?86:100)+4*sin(2*T*t+k),w=.12 + c.beginPath();c.moveTo(128+r1*cos(a-w),128+r1*sin(a-w));c.lineTo(128+r2*cos(a),128+r2*sin(a));c.lineTo(128+r1*cos(a+w),128+r1*sin(a+w));c.closePath();c.fill();c.stroke() + } + c.beginPath();c.arc(128,128,62,0,T);c.fill();c.stroke() + c.fillStyle='#111' + for(const d of[-1,1])c.beginPath(),c.roundRect(128+d*24-20,104,40,28,[6,6,16,16]),c.fill() + c.lineWidth=6;c.beginPath();c.moveTo(112,110);c.quadraticCurveTo(128,104,144,110);c.stroke() + c.beginPath();c.moveTo(86,110);c.lineTo(70,104);c.moveTo(170,110);c.lineTo(186,104);c.stroke() + const g=((t*1.6)%1)*90-30 + c.save();c.beginPath();for(const d of[-1,1])c.roundRect(128+d*24-20,104,40,28,[6,6,16,16]);c.clip() + c.strokeStyle='#fff';c.lineWidth=5;for(const o of[0,12])c.beginPath(),c.moveTo(80+g+o,136),c.lineTo(98+g+o,100),c.stroke() + c.restore() + c.lineWidth=6;c.strokeStyle='#111';c.beginPath();c.arc(128,146,18,.2*PI,.8*PI);c.stroke() +} diff --git a/gen/ufo/beam.js b/gen/ufo/beam.js new file mode 100644 index 0000000..9a23759 --- /dev/null +++ b/gen/ufo/beam.js @@ -0,0 +1,20 @@ +// flying saucer hovering with its lights chasing and a tractor beam pulling rings upward +const{sin,PI,floor}=Math,T=2*PI +export const frames=20,delay=70 +export default(c,t)=>{ + const h=5*sin(t*T) + const D=(f,a=12,b=5)=>{for(const[l,s]of[[a,'#111'],[b,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),f(),c.stroke();c.lineWidth=7;c.strokeStyle='#111'} + const hw=y=>26+(y-112)/120*46 + D(()=>{c.moveTo(128-hw(112),112+h);c.lineTo(128-hw(232),232);c.moveTo(128+hw(112),112+h);c.lineTo(128+hw(232),232)}) + for(let k=0;k<3;k++){const y=232-((t+k/3)%1)*112;D(()=>c.ellipse(128,y,hw(y),6,0,0,T),10,4)} + c.translate(128,96+h);c.rotate(.04*sin(t*T+1));c.translate(-128,-96) + c.beginPath();c.ellipse(128,106,52,13,0,0,T);c.fill();c.stroke() + c.beginPath();c.arc(128,90,36,PI,0);c.closePath();c.fill() + c.lineWidth=4;c.beginPath();c.arc(128,84,15,0,T);c.stroke() + c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*6,83,4,6,d*.3,0,T),c.fill() + c.fillStyle='#fff';c.lineWidth=7;c.beginPath();c.arc(128,90,36,PI,0);c.stroke() + c.lineWidth=4;c.beginPath();c.arc(128,90,26,PI*1.15,PI*1.4);c.stroke();c.lineWidth=7 + c.beginPath();c.ellipse(128,98,86,22,0,0,T);c.fill();c.stroke() + const on=floor(t*5) + c.lineWidth=5;for(let k=0;k<5;k++)c.beginPath(),c.arc(72+k*28,100+(k==0||k==4?-2:3),6,0,T),c.fillStyle=k==on?'#111':'#fff',c.fill(),c.stroke() +} diff --git a/public/bee/buzz.gif b/public/bee/buzz.gif new file mode 100644 index 0000000..5251f8b Binary files /dev/null and b/public/bee/buzz.gif differ diff --git a/public/bee/buzz.webp b/public/bee/buzz.webp new file mode 100644 index 0000000..893c8e0 Binary files /dev/null and b/public/bee/buzz.webp differ diff --git a/public/blob/jiggle.gif b/public/blob/jiggle.gif new file mode 100644 index 0000000..15defeb Binary files /dev/null and b/public/blob/jiggle.gif differ diff --git a/public/blob/jiggle.webp b/public/blob/jiggle.webp new file mode 100644 index 0000000..79e3d6a Binary files /dev/null and b/public/blob/jiggle.webp differ diff --git a/public/chick/hatch.gif b/public/chick/hatch.gif new file mode 100644 index 0000000..5af987f Binary files /dev/null and b/public/chick/hatch.gif differ diff --git a/public/chick/hatch.webp b/public/chick/hatch.webp new file mode 100644 index 0000000..7f05609 Binary files /dev/null and b/public/chick/hatch.webp differ diff --git a/public/flower/bloom.gif b/public/flower/bloom.gif new file mode 100644 index 0000000..d49302c Binary files /dev/null and b/public/flower/bloom.gif differ diff --git a/public/flower/bloom.webp b/public/flower/bloom.webp new file mode 100644 index 0000000..90c2ae0 Binary files /dev/null and b/public/flower/bloom.webp differ diff --git a/public/moon/sleep.gif b/public/moon/sleep.gif new file mode 100644 index 0000000..d14c6af Binary files /dev/null and b/public/moon/sleep.gif differ diff --git a/public/moon/sleep.webp b/public/moon/sleep.webp new file mode 100644 index 0000000..7e37128 Binary files /dev/null and b/public/moon/sleep.webp differ diff --git a/public/robot/dance.gif b/public/robot/dance.gif new file mode 100644 index 0000000..d839478 Binary files /dev/null and b/public/robot/dance.gif differ diff --git a/public/robot/dance.webp b/public/robot/dance.webp new file mode 100644 index 0000000..38b4158 Binary files /dev/null and b/public/robot/dance.webp differ diff --git a/public/sun/shine.gif b/public/sun/shine.gif new file mode 100644 index 0000000..a112c9f Binary files /dev/null and b/public/sun/shine.gif differ diff --git a/public/sun/shine.webp b/public/sun/shine.webp new file mode 100644 index 0000000..96c27c2 Binary files /dev/null and b/public/sun/shine.webp differ diff --git a/public/ufo/beam.gif b/public/ufo/beam.gif new file mode 100644 index 0000000..337e638 Binary files /dev/null and b/public/ufo/beam.gif differ diff --git a/public/ufo/beam.webp b/public/ufo/beam.webp new file mode 100644 index 0000000..0d59814 Binary files /dev/null and b/public/ufo/beam.webp differ