diff --git a/gen/bear/wave.js b/gen/bear/wave.js new file mode 100644 index 0000000..774093d --- /dev/null +++ b/gen/bear/wave.js @@ -0,0 +1,23 @@ +// bear sitting and waving hello with one paw +const{sin,cos,PI}=Math,T=2*PI +export const delay=70 +export default(c,t)=>{ + c.beginPath();c.ellipse(128,190,62,50,0,0,T);c.fill();c.stroke() + c.lineWidth=5;c.beginPath();c.ellipse(128,200,34,28,0,0,T);c.stroke();c.lineWidth=7 + for(const x of[92,164])c.beginPath(),c.ellipse(x,232,22,12,0,0,T),c.fill(),c.stroke() + for(const x of[84,172]){ + c.beginPath();c.arc(x,58,20,0,T);c.fill();c.stroke() + c.lineWidth=5;c.beginPath();c.arc(x,60,9,0,T);c.stroke();c.lineWidth=7 + } + c.beginPath();c.arc(128,100,54,0,T);c.fill();c.stroke() + c.fillStyle='#111';for(const x of[106,150])c.beginPath(),c.arc(x,96,6,0,T),c.fill() + c.fillStyle='#fff';for(const x of[104,148])c.beginPath(),c.arc(x,94,2.2,0,T),c.fill() + c.beginPath();c.ellipse(128,122,26,19,0,0,T);c.fill();c.stroke() + c.lineWidth=5;c.beginPath();c.moveTo(128,118);c.lineTo(128,126);c.arc(121,126,7,0,PI);c.moveTo(142,126);c.arc(135,126,7,0,PI);c.stroke();c.lineWidth=7 + c.fillStyle='#111';c.beginPath();c.ellipse(128,113,10,7,0,0,T);c.fill();c.fillStyle='#fff' + const a=-1+.4*sin(2*T*t),hx=172+50*cos(a),hy=176+50*sin(a) + for(const[x0,y0,x1,y1]of[[94,176,84,212],[164,186,hx,hy]]) + for(const[l,s]of[[42,'#111'],[28,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(x0,y0),c.lineTo(x1,y1),c.stroke() + c.lineWidth=5;c.strokeStyle='#111';c.beginPath();c.arc(hx,hy,7,0,T);c.stroke() + for(const k of[-1,0,1])c.beginPath(),c.arc(hx+cos(a+k*.7)*13,hy+sin(a+k*.7)*13,3,0,T),c.stroke() +} diff --git a/gen/bunny/ears.js b/gen/bunny/ears.js new file mode 100644 index 0000000..1bb6ab5 --- /dev/null +++ b/gen/bunny/ears.js @@ -0,0 +1,23 @@ +// bunny sitting still, one ear stays up while the other keeps flopping over, nose twitching +const{sin,cos,PI}=Math,T=2*PI +export default(c,t)=>{ + const ear=(x,y,a,b)=>{ + const mx=x+34*sin(a),my=y-34*cos(a),ex=mx+34*sin(a+b),ey=my-34*cos(a+b) + for(const[l,s]of[[36,'#111'],[22,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(x,y),c.lineTo(mx,my),c.lineTo(ex,ey),c.stroke() + c.lineWidth=4;c.strokeStyle='#111';c.beginPath();c.moveTo(x+14*sin(a),y-14*cos(a));c.lineTo(mx,my);c.lineTo(mx+16*sin(a+b),my-16*cos(a+b));c.stroke() + } + ear(108,100,-.2+.05*sin(t*T),.08*sin(t*T)) + ear(148,100,.2,.8-.8*cos(t*T)) + c.lineWidth=7 + c.beginPath();c.ellipse(128,200,50,40,0,0,T);c.fill();c.stroke() + for(const x of[100,156])c.beginPath(),c.ellipse(x,232,20,9,0,0,T),c.fill(),c.stroke() + c.beginPath();c.ellipse(128,136,54,46,0,0,T);c.fill();c.stroke() + c.fillStyle='#111' + for(const x of[108,148])c.beginPath(),c.ellipse(x,132,6,8,0,0,T),c.fill() + c.fillStyle='#fff';for(const x of[106,146])c.beginPath(),c.arc(x,129,2.5,0,T),c.fill() + const n=1+.3*Math.max(0,sin(3*T*t)) + c.save();c.translate(128,148);c.scale(1,n);c.fillStyle='#111';c.beginPath();c.moveTo(-7,-3);c.lineTo(7,-3);c.lineTo(0,5);c.closePath();c.restore();c.lineWidth=3;c.fill();c.stroke() + c.lineWidth=4;c.beginPath();c.moveTo(128,152);c.arc(122,152,6,0,PI);c.moveTo(140,152);c.arc(134,152,6,0,PI);c.stroke() + c.fillStyle='#fff';c.lineWidth=3;c.beginPath();c.rect(124,158,8,7);c.fill();c.stroke() + for(const s of[-1,1])c.beginPath(),c.moveTo(128+s*26,148),c.lineTo(128+s*44,144),c.moveTo(128+s*26,153),c.lineTo(128+s*44,155),c.stroke() +} diff --git a/gen/dog/wag.js b/gen/dog/wag.js new file mode 100644 index 0000000..ef0f517 --- /dev/null +++ b/gen/dog/wag.js @@ -0,0 +1,26 @@ +// pup sitting and panting with its tail going and ears bouncing +const{sin,cos,PI}=Math,T=2*PI +export const delay=60 +export default(c,t)=>{ + const b=2*sin(2*T*t),w=sin(2*T*t+1),a=-1+.5*w,ex=176+52*cos(a),ey=196+52*sin(a) + for(const[l,s]of[[24,'#111'],[10,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(150,206),c.quadraticCurveTo(186,196,ex,ey),c.stroke() + c.lineWidth=7;c.strokeStyle='#111' + c.beginPath();c.ellipse(128,180,52,50,0,0,T);c.fill();c.stroke() + for(const x of[106,150]){ + c.beginPath();c.roundRect(x-13,178,26,46,13);c.fill();c.stroke() + c.lineWidth=4;c.beginPath();c.moveTo(x-4,224);c.lineTo(x-4,216);c.moveTo(x+4,224);c.lineTo(x+4,216);c.stroke();c.lineWidth=7 + } + c.beginPath();c.arc(128,98+b,52,0,T);c.fill();c.stroke() + for(const s of[-1,1])c.beginPath(),c.ellipse(128+s*50,100+b,18,36,-s*(.35+.12*sin(2*T*t+.5)),0,T),c.fill(),c.stroke() + c.fillStyle='#111';c.beginPath();c.ellipse(150,92+b,17,15,0,0,T);c.fill() + c.beginPath();c.arc(106,94+b,7,0,T);c.fill() + c.fillStyle='#fff';c.beginPath();c.arc(150,94+b,8,0,T);c.fill() + c.fillStyle='#111';c.beginPath();c.arc(151,95+b,5,0,T);c.fill() + c.fillStyle='#fff';for(const x of[104,149])c.beginPath(),c.arc(x,92+b,2.5,0,T),c.fill() + c.beginPath();c.ellipse(128,120+b,26,18,0,0,T);c.fill();c.stroke() + const L=16+5*sin(2*T*t+2) + c.beginPath();c.roundRect(120,124+b,16,L,[0,0,8,8]);c.fill();c.stroke() + c.lineWidth=3;c.beginPath();c.moveTo(128,128+b);c.lineTo(128,120+b+L*.8);c.stroke() + c.lineWidth=5;c.beginPath();c.moveTo(128,114+b);c.lineTo(128,122+b);c.arc(121,122+b,7,0,PI);c.moveTo(142,122+b);c.arc(135,122+b,7,0,PI);c.stroke() + c.fillStyle='#111';c.beginPath();c.ellipse(128,110+b,10,7,0,0,T);c.fill() +} diff --git a/gen/fish/swim.js b/gen/fish/swim.js new file mode 100644 index 0000000..13eb7d5 --- /dev/null +++ b/gen/fish/swim.js @@ -0,0 +1,18 @@ +// fish swimming in place with its body waving, tail flicking and bubbles rising from its mouth +const{sin,PI}=Math,T=2*PI +export default(c,t)=>{ + const bob=4*sin(t*T),s=x=>(x-56)/124,yc=x=>128+bob+9*s(x)**1.5*sin(4*s(x)-t*T),hh=x=>50*sin(PI*s(x)**.75) + c.lineWidth=5 + for(const o of[0,.33,.66]){const k=(t+o)%1;c.beginPath();c.arc(42+5*sin(k*T*1.5+o*9),104+bob-k*84,4+6*k,0,T);c.fill();c.stroke()} + c.lineWidth=7 + c.save();c.translate(178,yc(178));c.rotate(.4*sin(t*T-1.6));c.beginPath();c.moveTo(-4,0);c.lineTo(46,-38);c.quadraticCurveTo(32,0,46,38);c.closePath();c.restore();c.fill();c.stroke() + const top=x=>yc(x)-hh(x) + c.beginPath();c.moveTo(96,top(96)+6);c.quadraticCurveTo(116,top(110)-34,148,top(148)+4);c.fill();c.stroke() + c.beginPath();for(let x=56;x<=180;x+=2)c.lineTo(x,top(x));for(let x=180;x>=56;x-=2)c.lineTo(x,yc(x)+hh(x));c.closePath();c.fill();c.stroke() + c.lineWidth=5;c.beginPath();c.arc(96,yc(96),28,-.3*PI,.3*PI);c.stroke() + c.save();c.translate(124,yc(124)+18);c.rotate(.35+.25*sin(2*T*t));c.beginPath();c.moveTo(-6,0);c.quadraticCurveTo(10,-12,26,-2);c.quadraticCurveTo(12,8,-6,0);c.restore();c.fill();c.stroke() + c.lineWidth=4;c.beginPath();c.arc(70,yc(70)+4,9,.55*PI,.9*PI);c.stroke() + c.lineWidth=5;c.beginPath();c.arc(82,yc(82)-10,11,0,T);c.fill();c.stroke() + c.fillStyle='#111';c.beginPath();c.arc(80,yc(82)-10,6,0,T);c.fill() + c.fillStyle='#fff';c.beginPath();c.arc(78,yc(82)-13,2,0,T);c.fill() +} diff --git a/gen/frog/hop.js b/gen/frog/hop.js new file mode 100644 index 0000000..6097170 --- /dev/null +++ b/gen/frog/hop.js @@ -0,0 +1,17 @@ +// frog hopping in place: squashes on the ground, stretches on takeoff and landing, kicks up dust +const{sin,PI}=Math,T=2*PI +export const delay=60 +export default(c,t)=>{ + const air=t>=.2,a=(t-.2)/.8,h=air?80*4*a*(1-a):0,g=air?0:sin(PI*t/.2),st=air?.1*(1-4*a*(1-a)):0 + const sx=1+.2*g-.5*st,sy=1-.2*g+st + const P=(f,fill='#fff',line=1)=>{c.save();c.translate(128,228-h);c.scale(sx,sy);c.beginPath();f();c.restore();if(fill)c.fillStyle=fill,c.fill();if(line)c.stroke()} + for(const s of[-1,1])P(()=>c.ellipse(s*50,-16,26,16,0,0,T)),P(()=>c.ellipse(s*68,-6,18,7,0,0,T)),P(()=>c.arc(s*30,-96,22,0,T)) + P(()=>c.ellipse(0,-44,64,46,0,0,T)) + for(const s of[-1,1]){ + P(()=>c.arc(s*30,-102,8,0,T),'#111',0);P(()=>c.arc(s*30-3,-105,2.5,0,T),'#fff',0) + P(()=>c.arc(s*8,-66,2.5,0,T),'#111',0);P(()=>c.ellipse(s*26,-4,13,8,0,0,T)) + } + P(()=>c.arc(0,-58,30,.2*PI,.8*PI),0) + c.fillStyle='#fff' + if(g>.2)for(const s of[-1,1])c.beginPath(),c.arc(128+s*(108+12*g),220,9*g,0,T),c.fill(),c.stroke() +} diff --git a/gen/octopus/wiggle.js b/gen/octopus/wiggle.js new file mode 100644 index 0000000..5ce41e1 --- /dev/null +++ b/gen/octopus/wiggle.js @@ -0,0 +1,20 @@ +// octopus bobbing with all six arms wiggling under it +const{sin,PI}=Math,T=2*PI +export default(c,t)=>{ + const b=4*sin(t*T) + for(let i=0;i<6;i++){ + const x0=78+i*20,d=(i-2.5)/2.5 + for(const[l,s]of[[26,'#111'],[12,'#fff']]){ + c.lineWidth=l;c.strokeStyle=s;c.beginPath() + for(let y=130;y<=224;y+=3){const k=(y-130)/94;c.lineTo(x0+d*k*36+13*k*sin(k*5-t*T+i*1.1),y+b*(1-k))} + c.stroke() + } + } + c.lineWidth=7;c.strokeStyle='#111' + c.beginPath();c.ellipse(128,98+b,64,60,0,0,T);c.fill();c.stroke() + c.lineWidth=5;for(const[x,y,r]of[[104,64,7],[150,56,9],[130,76,5]])c.beginPath(),c.arc(x,y+b,r,0,T),c.stroke() + c.fillStyle='#111';for(const x of[106,150])c.beginPath(),c.ellipse(x,112+b,8,11,0,0,T),c.fill() + c.fillStyle='#fff';for(const x of[103,147])c.beginPath(),c.arc(x,108+b,3,0,T),c.fill() + c.beginPath();c.arc(128,130+b,9,.15*PI,.85*PI);c.stroke() + c.lineWidth=3;for(const x of[86,162])for(const o of[-6,0,6])c.beginPath(),c.moveTo(x+o-2,132+b),c.lineTo(x+o+3,124+b),c.stroke() +} diff --git a/gen/penguin/waddle.js b/gen/penguin/waddle.js new file mode 100644 index 0000000..dcec3a9 --- /dev/null +++ b/gen/penguin/waddle.js @@ -0,0 +1,18 @@ +// penguin waddling in place, rocking side to side and lifting each foot in turn +// the black body gets a white rim so it doesn't vanish on dark backgrounds +const{sin,max,PI}=Math,T=2*PI +export default(c,t)=>{ + const s=sin(t*T) + c.translate(128,226);c.rotate(.1*s);c.translate(-128,-226) + const dark=f=>{c.beginPath();f();c.lineWidth=16;c.strokeStyle='#fff';c.stroke();c.fillStyle='#111';c.fill();c.lineWidth=7;c.strokeStyle='#111';c.stroke()} + for(const d of[-1,1])dark(()=>c.ellipse(128+d*58,148,14,40,-d*(.25+.15*sin(t*T+(d>0?PI:0))),0,T)) + dark(()=>c.ellipse(128,140,60,82,0,0,T)) + c.fillStyle='#fff' + c.beginPath();c.ellipse(128,158,44,60,0,0,T);c.fill() + for(const x of[112,144])c.beginPath(),c.arc(x,104,23,0,T),c.fill() + c.fillStyle='#111';for(const x of[114,142])c.beginPath(),c.arc(x,100,6,0,T),c.fill() + c.fillStyle='#fff';for(const x of[112,140])c.beginPath(),c.arc(x,98,2,0,T),c.fill() + c.fillStyle='#111';c.beginPath();c.moveTo(118,111);c.quadraticCurveTo(128,105,138,111);c.lineTo(128,124);c.closePath();c.lineWidth=4;c.fill();c.stroke() + c.fillStyle='#fff';c.lineWidth=7 + for(const[x,d]of[[106,1],[150,-1]])c.beginPath(),c.ellipse(x,224-max(0,d*s)*10,18,8,0,0,T),c.fill(),c.stroke() +} diff --git a/gen/snail/crawl.js b/gen/snail/crawl.js new file mode 100644 index 0000000..6944e95 --- /dev/null +++ b/gen/snail/crawl.js @@ -0,0 +1,21 @@ +// snail inching along in place: body stretches and bunches up, shell rocks, eye stalks wobble +const{sin,cos,PI}=Math,T=2*PI +export const delay=90 +export default(c,t)=>{ + const f=196+12*sin(t*T),b=56+12*sin(t*T-1.4),w=3*sin(2*T*t) + for(const[l,s,r]of[[38,'#111',26],[24,'#fff',19]]){ + c.lineWidth=l;c.strokeStyle=c.fillStyle=s + c.beginPath();c.moveTo(b,210);c.lineTo(f-14,210);c.quadraticCurveTo(f,208,f,180);c.stroke() + c.beginPath();c.arc(f,172,r,0,T);c.fill() + } + c.lineWidth=7;c.strokeStyle='#111';c.fillStyle='#fff' + const sx=(b+f)/2-14,sy=150+2*sin(2*T*t),r=.08*sin(t*T-.7) + c.beginPath();c.arc(sx,sy,50,0,T);c.fill();c.stroke() + c.lineWidth=6;c.beginPath();for(let a=0;a<3.6*PI;a+=.1)c.lineTo(sx+(4+a*3.6)*cos(a+r*6),sy+(4+a*3.6)*sin(a+r*6));c.stroke() + for(const[x0,x1,y1]of[[f-8,f-16+w,118],[f+6,f+14-w,122]]){ + for(const[l,s]of[[12,'#111'],[5,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(x0,160),c.lineTo(x1,y1),c.stroke() + c.lineWidth=5;c.strokeStyle='#111';c.beginPath();c.arc(x1,y1,8,0,T);c.fill();c.stroke() + c.fillStyle='#111';c.beginPath();c.arc(x1+2,y1,4,0,T);c.fill();c.fillStyle='#fff' + } + c.beginPath();c.arc(f+4,174,9,.1*PI,.7*PI);c.stroke() +} diff --git a/public/bear/wave.gif b/public/bear/wave.gif new file mode 100644 index 0000000..c9c5fa1 Binary files /dev/null and b/public/bear/wave.gif differ diff --git a/public/bear/wave.webp b/public/bear/wave.webp new file mode 100644 index 0000000..3078307 Binary files /dev/null and b/public/bear/wave.webp differ diff --git a/public/bunny/ears.gif b/public/bunny/ears.gif new file mode 100644 index 0000000..30cdd54 Binary files /dev/null and b/public/bunny/ears.gif differ diff --git a/public/bunny/ears.webp b/public/bunny/ears.webp new file mode 100644 index 0000000..186f8d4 Binary files /dev/null and b/public/bunny/ears.webp differ diff --git a/public/dog/wag.gif b/public/dog/wag.gif new file mode 100644 index 0000000..2e66077 Binary files /dev/null and b/public/dog/wag.gif differ diff --git a/public/dog/wag.webp b/public/dog/wag.webp new file mode 100644 index 0000000..00279b4 Binary files /dev/null and b/public/dog/wag.webp differ diff --git a/public/fish/swim.gif b/public/fish/swim.gif new file mode 100644 index 0000000..e142c9a Binary files /dev/null and b/public/fish/swim.gif differ diff --git a/public/fish/swim.webp b/public/fish/swim.webp new file mode 100644 index 0000000..43d5f2f Binary files /dev/null and b/public/fish/swim.webp differ diff --git a/public/frog/hop.gif b/public/frog/hop.gif new file mode 100644 index 0000000..cf7145c Binary files /dev/null and b/public/frog/hop.gif differ diff --git a/public/frog/hop.webp b/public/frog/hop.webp new file mode 100644 index 0000000..0cde0be Binary files /dev/null and b/public/frog/hop.webp differ diff --git a/public/octopus/wiggle.gif b/public/octopus/wiggle.gif new file mode 100644 index 0000000..8c093f7 Binary files /dev/null and b/public/octopus/wiggle.gif differ diff --git a/public/octopus/wiggle.webp b/public/octopus/wiggle.webp new file mode 100644 index 0000000..55b99be Binary files /dev/null and b/public/octopus/wiggle.webp differ diff --git a/public/penguin/waddle.gif b/public/penguin/waddle.gif new file mode 100644 index 0000000..cf7d36e Binary files /dev/null and b/public/penguin/waddle.gif differ diff --git a/public/penguin/waddle.webp b/public/penguin/waddle.webp new file mode 100644 index 0000000..3b8ce9d Binary files /dev/null and b/public/penguin/waddle.webp differ diff --git a/public/snail/crawl.gif b/public/snail/crawl.gif new file mode 100644 index 0000000..bfb7569 Binary files /dev/null and b/public/snail/crawl.gif differ diff --git a/public/snail/crawl.webp b/public/snail/crawl.webp new file mode 100644 index 0000000..81c6f6e Binary files /dev/null and b/public/snail/crawl.webp differ