mirror of
https://github.com/direct-img/vibegif.direct-img.link.git
synced 2026-10-29 03:34:51 +00:00
Split the gallery into sections with a divider, start the colored set
Generators now live in gen/<section>/<subject>/<action>.js; the section folder picks where a tile shows in the gallery and isn't part of the URL. The first 50 are in gen/bw, a dashed divider follows, then gen/color. First colored ones: fox/sleep, pig/oink, duck/swim, whale/spout, turtle/walk, owl/blink, crab/dance, butterfly/flutter, dino/stomp, jellyfish/pulse. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
// two balloons tied together bobbing and swaying out of step, strings waving
|
||||
const{sin,cos,PI}=Math,T=2*PI
|
||||
export const frames=20,delay=80
|
||||
const balloon=(c,x,y,r,a)=>{
|
||||
c.save();c.translate(x,y);c.rotate(a)
|
||||
c.beginPath();c.moveTo(0,-r*1.15);c.bezierCurveTo(r*1.12,-r*1.15,r*1.05,r*.6,0,r*1.05);c.bezierCurveTo(-r*1.05,r*.6,-r*1.12,-r*1.15,0,-r*1.15);c.fill();c.stroke()
|
||||
c.beginPath();c.moveTo(0,r*1.05);c.lineTo(-7,r*1.05+11);c.lineTo(7,r*1.05+11);c.closePath();c.fill();c.stroke()
|
||||
c.lineWidth=5;c.beginPath();c.arc(0,-r*.1,r*.75,PI*1.12,PI*1.38);c.stroke();c.lineWidth=7
|
||||
c.restore()
|
||||
}
|
||||
export default(c,t)=>{
|
||||
const B=[[170,96,40,.6],[100,84,52,0]].map(([x,y,r,o])=>{const a=.12*sin(t*T+o*5),bx=x+6*sin(t*T+o*5),by=y+6*sin(2*T*t+o*3);return[bx,by,r,a]})
|
||||
for(const[bx,by,r,a]of B){
|
||||
const kx=bx-sin(a)*(r*1.05+11),ky=by+cos(a)*(r*1.05+11)
|
||||
for(const[w,s]of[[8,'#111'],[3,'#fff']]){
|
||||
c.lineWidth=w;c.strokeStyle=s;c.beginPath();c.moveTo(kx,ky)
|
||||
for(let u=0;u<=1;u+=.05)c.lineTo(kx+(132-kx)*u+6*sin(u*7-t*T*2)*(1-u),ky+(240-ky)*u)
|
||||
c.stroke()
|
||||
}
|
||||
}
|
||||
c.lineWidth=7;c.strokeStyle='#111'
|
||||
for(const b of B)balloon(c,...b)
|
||||
const[bx,by]=B[1]
|
||||
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(bx+d*15,by-4,5,0,T),c.fill()
|
||||
c.lineWidth=5;c.beginPath();c.arc(bx,by+8,10,.15*PI,.85*PI);c.stroke()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// bell swinging back and forth, clapper lagging behind, ring lines on each swing
|
||||
const{sin,cos,PI,abs}=Math,T=2*PI
|
||||
export const frames=20,delay=60
|
||||
export default(c,t)=>{
|
||||
const a=.38*sin(2*T*t),ca=-.5*sin(2*T*t-.9)
|
||||
if(abs(a)>.3){
|
||||
const d=a>0?-1:1
|
||||
for(const r of[96,118])for(const[w,s]of[[11,'#111'],[4,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.arc(128,120,r,d>0?-.35:PI-.35,d>0?.35:PI+.35),c.stroke()
|
||||
}
|
||||
c.lineWidth=7;c.strokeStyle='#111'
|
||||
c.translate(128,48);c.rotate(a)
|
||||
c.save();c.rotate(ca);c.beginPath();c.moveTo(0,40);c.lineTo(0,140);c.lineWidth=6;c.stroke();c.lineWidth=7;c.beginPath();c.arc(0,150,13,0,T);c.fill();c.stroke();c.restore()
|
||||
c.beginPath();c.arc(0,4,10,0,T);c.fill();c.stroke()
|
||||
c.beginPath();c.moveTo(-46,128);c.bezierCurveTo(-46,86,-42,16,0,14);c.bezierCurveTo(42,16,46,86,46,128);c.closePath();c.fill();c.stroke()
|
||||
c.beginPath();c.roundRect(-60,122,120,20,10);c.fill();c.stroke()
|
||||
c.lineWidth=5;c.beginPath();c.moveTo(-28,40);c.quadraticCurveTo(-34,70,-34,100);c.stroke()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// sleepy light bulb flickers on, wakes up with a grin and shines, then dozes off again
|
||||
const{sin,cos,PI}=Math,T=2*PI
|
||||
export const frames=24,delay=70
|
||||
export default(c,t,i)=>{
|
||||
const on=t>=.36&&t<.86||t>=.25&&t<.36&&i%2==1
|
||||
if(on)for(let k=0;k<7;k++){
|
||||
const a=PI+k*PI/6,r1=74,r2=96+6*sin(2*T*t*2+k)
|
||||
for(const[w,s]of[[13,'#111'],[5,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(128+cos(a)*r1,100+sin(a)*r1),c.lineTo(128+cos(a)*r2,100+sin(a)*r2),c.stroke()
|
||||
}
|
||||
c.lineWidth=7;c.strokeStyle='#111'
|
||||
c.beginPath();c.arc(128,100,58,.7*PI,.3*PI);c.lineTo(150,170);c.lineTo(106,170);c.closePath();c.fill();c.stroke()
|
||||
for(const[x,y,w,h]of[[102,168,52,13],[105,181,46,13],[112,194,32,12]])c.beginPath(),c.roundRect(x,y,w,h,5),c.fill(),c.stroke()
|
||||
c.beginPath();c.arc(128,208,7,0,PI);c.fill();c.stroke()
|
||||
c.lineWidth=5
|
||||
if(on){
|
||||
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+d*20,100,6,0,T),c.fill()
|
||||
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(128+d*20-2,97,2.2,0,T),c.fill()
|
||||
c.beginPath();c.arc(128,112,16,.15*PI,.85*PI);c.stroke()
|
||||
c.lineWidth=4;c.beginPath();c.arc(128,100,44,PI*1.15,PI*1.4);c.stroke()
|
||||
}else{
|
||||
for(const d of[-1,1])c.beginPath(),c.arc(128+d*20,98,7,.15*PI,.85*PI),c.stroke()
|
||||
c.beginPath();c.moveTo(122,122);c.lineTo(134,122);c.stroke()
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// two-tier birthday cake, candle flame flickering, sparkles popping around it
|
||||
const{sin,cos,PI,max}=Math,T=2*PI
|
||||
export const frames=20,delay=80
|
||||
const star=(c,x,y,r)=>{const k=r*.18;c.beginPath();c.moveTo(x,y-r);for(const[px,py,qx,qy]of[[r,0,k,-k],[0,r,k,k],[-r,0,-k,k],[0,-r,-k,-k]])c.quadraticCurveTo(x+qx,y+qy,x+px,y+py);c.fill();c.stroke()}
|
||||
const tier=(c,x,y,w,h)=>{
|
||||
c.beginPath();c.roundRect(x,y,w,h,10);c.fill();c.stroke()
|
||||
c.beginPath();c.moveTo(x,y+12);const n=Math.round(w/22);for(let k=0;k<n;k++){const a=x+k*w/n;c.arc(a+w/n/2,y+12,w/n/2,PI,0,true)}c.lineWidth=5;c.stroke();c.lineWidth=7
|
||||
}
|
||||
export default(c,t)=>{
|
||||
c.lineWidth=4;for(const[x,y,o]of[[42,70,0],[214,56,.33],[206,128,.66]]){const r=13*max(0,sin(PI*((t*2+o)%1)));if(r>1.5)star(c,x,y,r)}
|
||||
c.lineWidth=7
|
||||
c.beginPath();c.ellipse(128,230,100,12,0,0,T);c.fill();c.stroke()
|
||||
tier(c,48,152,160,76);tier(c,74,98,108,58)
|
||||
c.lineWidth=4;for(const[x,y,a]of[[70,196,.4],[100,212,-.5],[140,200,.8],[176,210,-.2],[188,184,.3],[96,136,-.6],[124,144,.5],[160,132,-.3]])c.beginPath(),c.moveTo(x-cos(a)*5,y-sin(a)*5),c.lineTo(x+cos(a)*5,y+sin(a)*5),c.stroke()
|
||||
c.lineWidth=7;c.beginPath();c.roundRect(119,50,18,50,4);c.fill();c.stroke()
|
||||
c.save();c.beginPath();c.rect(119,50,18,50);c.clip();c.lineWidth=4;for(const y of[56,72,88])c.beginPath(),c.moveTo(118,y+8),c.lineTo(138,y),c.stroke();c.restore()
|
||||
c.beginPath();c.moveTo(128,50);c.lineTo(128,42);c.lineWidth=4;c.stroke()
|
||||
const h=26+5*sin(2*T*t)+3*sin(5*T*t),b=4*sin(3*T*t)
|
||||
c.lineWidth=6;c.beginPath();c.moveTo(128+b,40-h);c.quadraticCurveTo(142,32,138,22+0);c.arc(128,24,10,0,PI);c.quadraticCurveTo(114,32,128+b,40-h);c.fill();c.stroke()
|
||||
c.fillStyle='#111';c.beginPath();c.ellipse(128,28,4,6,0,0,T);c.fill()
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// badge pops in, a check mark draws itself, a burst of lines goes off, then it shrinks away
|
||||
const{sin,cos,PI,min,max,hypot}=Math,T=2*PI
|
||||
export const frames=24,delay=60
|
||||
const back=u=>{const s=2;return 1+(s+1)*(u-1)**3+s*(u-1)**2}
|
||||
const P=[[90,132],[118,160],[168,102]],L=hypot(28,28)+hypot(50,58)
|
||||
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)/.28)),b=(t-.45)/.25
|
||||
if(b>0&&b<1)for(let k=0;k<8;k++){
|
||||
const a=k*T/8+PI/8,r1=82+30*b,r2=r1+20*(1-b)
|
||||
for(const[w,st]of[[12,'#111'],[5,'#fff']])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';c.lineWidth=7
|
||||
if(s<=.01)return
|
||||
c.translate(128,128);c.scale(s,s);c.translate(-128,-128);c.lineWidth=7/s
|
||||
c.beginPath();c.arc(128,128,74,0,T);c.fill();c.stroke()
|
||||
if(p>0){c.lineWidth=20;c.setLineDash([L*p,999]);c.beginPath();for(const[x,y]of P)c.lineTo(x,y);c.stroke();c.setLineDash([])}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// alarm clock rocking tick-tock while the second hand steps once a frame around the dial
|
||||
const{sin,cos,PI}=Math,T=2*PI
|
||||
export const frames=12,delay=160
|
||||
export default(c,t,i)=>{
|
||||
c.translate(128,232);c.rotate(i%2?.045:-.045);c.translate(-128,-232)
|
||||
for(const d of[-1,1]){
|
||||
c.beginPath();c.moveTo(128+d*40,212);c.lineTo(128+d*56,236);c.lineWidth=12;c.stroke();c.lineWidth=7
|
||||
c.save();c.translate(128+d*50,66);c.rotate(d*.6);c.beginPath();c.arc(0,0,24,PI,0);c.closePath();c.fill();c.stroke();c.restore()
|
||||
}
|
||||
for(const[w,s]of[[14,'#111'],[4,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.arc(128,64,30,PI*1.15,PI*1.85),c.stroke()
|
||||
c.lineWidth=7;c.strokeStyle='#111'
|
||||
c.beginPath();c.arc(128,140,82,0,T);c.fill();c.stroke()
|
||||
c.lineWidth=5;c.beginPath();c.arc(128,140,70,0,T);c.stroke()
|
||||
for(let k=0;k<12;k++){const a=k*T/12,r=k%3?62:56;c.lineWidth=k%3?4:6;c.beginPath();c.moveTo(128+cos(a)*r,140+sin(a)*r);c.lineTo(128+cos(a)*66,140+sin(a)*66);c.stroke()}
|
||||
c.lineWidth=8;for(const[a,r]of[[-PI*.83,34],[-PI*.17,48]])c.beginPath(),c.moveTo(128,140),c.lineTo(128+cos(a)*r,140+sin(a)*r),c.stroke()
|
||||
const s=i/12*T-PI/2
|
||||
c.lineWidth=3;c.beginPath();c.moveTo(128-cos(s)*12,140-sin(s)*12);c.lineTo(128+cos(s)*58,140+sin(s)*58);c.stroke()
|
||||
c.fillStyle='#111';c.beginPath();c.arc(128,140,7,0,T);c.fill()
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// sleepy rain cloud drifting while drops fall out from under it
|
||||
const{sin,PI}=Math,T=2*PI
|
||||
export default(c,t)=>{
|
||||
for(const[x,o]of[[72,0],[100,.55],[128,.25],[156,.8],[184,.4]]){
|
||||
const y=150+((t+o)%1)*120
|
||||
c.beginPath();c.moveTo(x,y-14);c.bezierCurveTo(x+3,y-7,x+8,y-3,x+8,y+3);c.arc(x,y+3,8,0,PI);c.bezierCurveTo(x-8,y-3,x-3,y-7,x,y-14)
|
||||
c.lineWidth=5;c.fill();c.stroke()
|
||||
}
|
||||
const y=sin(t*T)*3,parts=[[78,118+y,36],[124,92+y,48],[176,112+y,38]],base=()=>c.roundRect(44,112+y,168,52,26)
|
||||
c.lineWidth=14;for(const[x,yy,r]of parts)c.beginPath(),c.arc(x,yy,r,0,T),c.stroke()
|
||||
c.beginPath();base();c.stroke()
|
||||
for(const[x,yy,r]of parts)c.beginPath(),c.arc(x,yy,r,0,T),c.fill()
|
||||
c.beginPath();base();c.fill()
|
||||
c.lineWidth=6
|
||||
for(const x of[104,152])c.beginPath(),c.arc(x,126+y,9,PI*.15,PI*.85),c.stroke()
|
||||
c.beginPath();c.arc(128,154+y,8,PI*1.2,PI*1.8);c.stroke()
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// happy coffee mug rocking a little while steam curls up out of it
|
||||
const{sin,PI}=Math,T=2*PI
|
||||
export const delay=90
|
||||
export default(c,t)=>{
|
||||
c.save();c.translate(119,214);c.rotate(.04*sin(t*T));c.translate(-119,-214)
|
||||
for(const[w,s]of[[27,'#111'],[13,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.arc(172,160,26,-PI/2,PI/2),c.stroke()
|
||||
c.lineWidth=7;c.strokeStyle='#111'
|
||||
c.beginPath();c.moveTo(66,120);c.lineTo(66,192);c.quadraticCurveTo(66,214,88,214);c.lineTo(150,214);c.quadraticCurveTo(172,214,172,192);c.lineTo(172,120)
|
||||
c.ellipse(119,120,53,12,0,0,PI,true);c.fill();c.stroke()
|
||||
c.beginPath();c.ellipse(119,120,53,12,0,0,T);c.fill();c.stroke()
|
||||
c.fillStyle='#111';c.beginPath();c.ellipse(119,121,42,7,0,0,T);c.fill()
|
||||
c.lineWidth=6
|
||||
for(const x of[100,138])c.beginPath(),c.arc(x,166,8,PI*1.15,PI*1.85),c.stroke()
|
||||
c.beginPath();c.arc(119,174,10,PI*.2,PI*.8);c.stroke()
|
||||
c.restore()
|
||||
for(const[x0,top,ph]of[[93,46,0],[119,30,.5],[145,46,1]])
|
||||
for(const[w,s]of[[13,'#111'],[6,'#fff']]){
|
||||
c.lineWidth=w;c.strokeStyle=s;c.beginPath()
|
||||
for(let y=100;y>=top;y-=2)c.lineTo(x0+(2+5*(100-y)/70)*sin((100-y)/40*T-t*T+ph),y)
|
||||
c.stroke()
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// face laughing so hard it shakes, with tears of joy squirting out both sides
|
||||
const{sin,cos,PI,abs}=Math,T=2*PI
|
||||
export const frames=18,delay=60
|
||||
export default(c,t)=>{
|
||||
const r=.1*sin(3*T*t),b=-5*abs(sin(3*PI*t)),m=38+5*sin(6*T*t)
|
||||
for(const d of[-1,1])for(let k=0;k<3;k++){
|
||||
const p=(t*2+k/3)%1,x=128+d*(56+p*58),y=112+b-34*p+70*p*p,s=7*sin(PI*p)+2,vx=d*58,vy=-34+140*p,a=Math.atan2(vy,vx)
|
||||
c.save();c.translate(x,y);c.rotate(a-PI/2);c.beginPath();c.moveTo(0,-s*1.8);c.quadraticCurveTo(s,-s*.2,s,s*.3);c.arc(0,s*.3,s,0,PI);c.quadraticCurveTo(-s,-s*.2,0,-s*1.8);c.restore();c.lineWidth=4;c.fill();c.stroke()
|
||||
}
|
||||
c.lineWidth=7
|
||||
c.translate(128,132+b);c.rotate(r);c.translate(-128,-132)
|
||||
c.beginPath();c.arc(128,132,76,0,T);c.fill();c.stroke()
|
||||
for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*44,104),c.lineTo(128+d*24,112),c.lineTo(128+d*44,120),c.stroke()
|
||||
c.save();c.beginPath();c.moveTo(128-m,140);c.arc(128,140,m,0,PI);c.closePath();c.fillStyle='#111';c.fill();c.clip()
|
||||
c.fillStyle='#fff';c.fillRect(80,136,96,12);c.beginPath();c.ellipse(128,140+m,m*.55,m*.42,0,0,T);c.fill();c.lineWidth=5;c.stroke();c.restore()
|
||||
c.beginPath();c.moveTo(128-m,140);c.arc(128,140,m,0,PI);c.closePath();c.stroke()
|
||||
c.lineWidth=3;for(const d of[-1,1])for(const k of[-5,0,5])c.beginPath(),c.moveTo(128+d*58+k-2,140),c.lineTo(128+d*58+k+2,133),c.stroke()
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// campfire: three flame tongues flickering on two crossed logs, little face in the flame, sparks floating up
|
||||
// the black flame gets a white rim so it still shows on dark backgrounds
|
||||
const{sin,PI}=Math,T=2*PI
|
||||
export const frames=20,delay=70
|
||||
const tongue=(c,x,by,h,w,b)=>{
|
||||
c.moveTo(x+b,by-h)
|
||||
c.bezierCurveTo(x+w*.2+b*.5,by-h*.55,x+w,by-h*.5,x+w,by-w)
|
||||
c.arc(x,by-w,w,0,PI)
|
||||
c.bezierCurveTo(x-w,by-h*.5,x-w*.2+b*.5,by-h*.55,x+b,by-h)
|
||||
}
|
||||
export default(c,t)=>{
|
||||
const s=k=>sin(T*t*k)
|
||||
c.lineWidth=4
|
||||
for(const[x0,o]of[[98,0],[152,.4],[126,.75]]){const p=(t+o)%1;c.beginPath();c.arc(x0+10*sin(p*T*2+o*5),120-p*110,4*(1-p)+1.5,0,T);c.fill();c.stroke()}
|
||||
c.beginPath()
|
||||
tongue(c,128,214,156+8*s(2),54,14*s(2))
|
||||
tongue(c,96,214,100+8*s(3),34,-16+8*s(2))
|
||||
tongue(c,160,214,112+8*s(2),36,16-8*s(3))
|
||||
c.lineWidth=16;c.strokeStyle='#fff';c.stroke();c.fillStyle='#111';c.fill();c.lineWidth=7;c.strokeStyle='#111';c.stroke()
|
||||
c.beginPath();tongue(c,128,212,92+6*s(3),30,8*s(2));c.fillStyle='#fff';c.fill()
|
||||
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+d*10,180,4,0,T),c.fill()
|
||||
c.lineWidth=4;c.beginPath();c.arc(128,187,6,.15*PI,.85*PI);c.stroke()
|
||||
c.fillStyle='#fff';c.lineWidth=7
|
||||
for(const d of[-1,1]){
|
||||
c.save();c.translate(128,222);c.rotate(d*.22);c.beginPath();c.roundRect(-78,-13,156,26,13);c.fill();c.stroke()
|
||||
c.lineWidth=4;c.beginPath();c.ellipse(d*68,0,6,9,0,0,T);c.stroke();c.lineWidth=7;c.restore()
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// ghost bobbing in place, hem rippling, little arms flapping, blinks once per loop
|
||||
const{sin,PI}=Math,T=2*PI
|
||||
export default(c,t,i)=>{
|
||||
const y=sin(t*T)*8,L=66,R=190,hem=x=>196+y+7*sin((x-L)/(R-L)*3*T-t*T)
|
||||
for(const s of[-1,1]){
|
||||
c.beginPath();c.ellipse(128+s*68,150+y,20,10,s*(.5+.3*sin(t*T*2)),0,T);c.fill();c.stroke()
|
||||
}
|
||||
c.beginPath();c.moveTo(L,hem(L));c.arc(128,104+y,62,PI,0)
|
||||
for(let x=R;x>=L;x-=2)c.lineTo(x,hem(x))
|
||||
c.closePath();c.fill();c.stroke()
|
||||
c.fillStyle='#111'
|
||||
for(const x of[106,150]){
|
||||
c.beginPath()
|
||||
if(i==11||i==12)c.moveTo(x-7,108+y),c.lineTo(x+7,108+y),c.stroke()
|
||||
else c.ellipse(x,108+y,6.5,10,0,0,T),c.fill(),c.fillStyle='#fff',c.beginPath(),c.arc(x-2,104+y,2.5,0,T),c.fill(),c.fillStyle='#111'
|
||||
}
|
||||
c.beginPath();c.ellipse(128,138+y,6,8,0,0,T);c.fill()
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// gift box rattles, the lid pops off and confetti bursts out, then the lid drops back on
|
||||
const{sin,cos,PI,min,max}=Math,T=2*PI
|
||||
export const frames=24,delay=70
|
||||
const C=[[-90,-150,0],[-50,-190,1],[-10,-200,2],[40,-185,0],[85,-140,1],[-120,-90,2],[115,-100,0],[20,-150,1],[-70,-120,1],[60,-210,2]]
|
||||
export default(c,t)=>{
|
||||
const sh=t<.3?.07*sin(t*T*10):0,up=t<.32?0:t<.45?(t-.32)/.13:t<.62?1:t<.78?1-((t-.62)/.16)**2:0,ly=-70*up,lr=-.35*up
|
||||
const u=(t-.36)/.44
|
||||
if(u>0&&u<1)for(const[vx,vy,k]of C){
|
||||
const x=128+vx*u,y=120+vy*u+260*u*u
|
||||
c.save();c.translate(x,y);c.rotate(u*T*(k+1));c.lineWidth=4;c.beginPath()
|
||||
if(k==0)c.rect(-6,-4,12,8);else if(k==1)c.arc(0,0,6,0,T);else c.moveTo(0,-7),c.lineTo(7,5),c.lineTo(-7,5),c.closePath()
|
||||
c.restore();c.fill();c.stroke()
|
||||
}
|
||||
c.lineWidth=7
|
||||
c.translate(128,226);c.rotate(sh);c.translate(-128,-226)
|
||||
c.beginPath();c.roundRect(64,128,128,96,6);c.fill();c.stroke()
|
||||
c.beginPath();c.rect(116,128,24,96);c.fill();c.stroke()
|
||||
c.translate(128,116+ly);c.rotate(lr);c.translate(-128,-116)
|
||||
for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*20,88,22,13,d*.5,0,T),c.fill(),c.stroke()
|
||||
c.beginPath();c.roundRect(56,100,144,32,6);c.fill();c.stroke()
|
||||
c.beginPath();c.rect(116,100,24,32);c.fill();c.stroke()
|
||||
c.beginPath();c.arc(128,96,9,0,T);c.fill();c.stroke()
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// two mitten hands clapping twice per loop with a burst of lines each time they meet
|
||||
const{sin,cos,PI}=Math,T=2*PI
|
||||
export const delay=60
|
||||
export default(c,t)=>{
|
||||
const k=(1+cos(2*T*t))/2,g=8+44*k
|
||||
if(k<.12)for(const d of[-1,1])for(const a of[-.5,0,.5]){
|
||||
const ang=-PI/2+d*(.55+a*.5)
|
||||
for(const[w,s]of[[11,'#111'],[4,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(128+cos(ang)*58,104+sin(ang)*58),c.lineTo(128+cos(ang)*84,104+sin(ang)*84),c.stroke()
|
||||
}
|
||||
c.lineWidth=7;c.strokeStyle='#111'
|
||||
for(const d of[-1,1]){
|
||||
c.save();c.translate(128+d*g,212);c.scale(d,1);c.rotate(-.22-.12*k)
|
||||
c.beginPath();c.ellipse(-2,-74,12,24,-.5,0,T);c.fill();c.stroke()
|
||||
c.beginPath();c.roundRect(0,-150,46,118,23);c.fill();c.stroke()
|
||||
c.lineWidth=4;c.beginPath();for(const x of[12,23,34])c.moveTo(x,-150+8),c.lineTo(x,-126);c.stroke();c.lineWidth=7
|
||||
c.beginPath();c.roundRect(-3,-40,52,22,5);c.fill();c.stroke()
|
||||
c.restore()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// heart thumping with a double beat, pop lines burst out on the big one
|
||||
const{exp,cos,sin,PI}=Math
|
||||
const p=(t,m)=>exp(-((((t-m+1.5)%1-.5)/.06)**2))
|
||||
export const delay=60
|
||||
export default(c,t)=>{
|
||||
const s=1+.14*p(t,.1)+.07*p(t,.32),k=p(t,.1)
|
||||
c.translate(128,140);c.scale(s,s);c.lineWidth/=s
|
||||
c.beginPath();c.moveTo(0,70)
|
||||
c.bezierCurveTo(-30,45,-92,10,-92,-30);c.bezierCurveTo(-92,-62,-66,-82,-44,-82);c.bezierCurveTo(-22,-82,-6,-68,0,-50)
|
||||
c.bezierCurveTo(6,-68,22,-82,44,-82);c.bezierCurveTo(66,-82,92,-62,92,-30);c.bezierCurveTo(92,10,30,45,0,70)
|
||||
c.closePath();c.fill();c.stroke()
|
||||
c.beginPath();c.arc(-46,-34,24,PI*1.1,PI*1.45);c.stroke()
|
||||
if(k<.15)return
|
||||
for(const[x,a]of[[-46,-140],[-46,-110],[-46,-80],[46,-40],[46,-70],[46,-100]])
|
||||
for(const[w,s2]of[[12,'#111'],[5,'#fff']]){
|
||||
const r=a*PI/180;c.lineWidth=w/s;c.strokeStyle=s2;c.beginPath()
|
||||
c.moveTo(x+cos(r)*56,-38+sin(r)*56);c.lineTo(x+cos(r)*(56+16*k),-38+sin(r)*(56+16*k));c.stroke()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// sand runs from the top bulb to the bottom, then the hourglass flips over and it starts again
|
||||
const{PI,min}=Math,T=2*PI
|
||||
export const frames=24,delay=90
|
||||
const glass=c=>{
|
||||
c.beginPath();c.moveTo(86,54);c.bezierCurveTo(86,100,120,110,122,128);c.bezierCurveTo(120,146,86,156,86,202)
|
||||
c.lineTo(170,202);c.bezierCurveTo(170,156,136,146,134,128);c.bezierCurveTo(136,110,170,100,170,54);c.closePath()
|
||||
}
|
||||
export default(c,t)=>{
|
||||
const p=min(1,t/.72),f=t>.75?(t-.75)/.25:0,e=f<.5?2*f*f:1-2*(1-f)**2
|
||||
c.translate(128,128);c.rotate(e*PI);c.translate(-128,-128)
|
||||
glass(c);c.fill()
|
||||
c.save();glass(c);c.clip();c.fillStyle='#111'
|
||||
if(f>0)c.fillRect(80,152-24*e,96,52+4*e)
|
||||
else{
|
||||
const top=72+p*56,lv=204-52*p,m=22*Math.sin(PI*p)
|
||||
c.fillRect(80,top,96,128-top)
|
||||
if(p>0){c.beginPath();c.moveTo(80,204);c.lineTo(80,lv+m*.4);c.quadraticCurveTo(128,lv-m,176,lv+m*.4);c.lineTo(176,204);c.fill()}
|
||||
if(p<1)c.fillRect(126,126,4,80)
|
||||
}
|
||||
c.restore()
|
||||
glass(c);c.stroke()
|
||||
for(const x of[74,182])for(const[w,s]of[[14,'#111'],[4,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(x,50),c.lineTo(x,206),c.stroke()
|
||||
c.lineWidth=7;c.strokeStyle='#111'
|
||||
for(const y of[36,204])c.beginPath(),c.roundRect(62,y,132,16,7),c.fill(),c.stroke()
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// ice cream cone melting: drips stretch down the cone and drops fall off, the scoop looks worried
|
||||
const{sin,cos,PI,min}=Math,T=2*PI
|
||||
export const frames=24,delay=80
|
||||
export default(c,t)=>{
|
||||
c.beginPath();c.moveTo(80,146);c.lineTo(176,146);c.lineTo(128,246);c.closePath();c.fill()
|
||||
c.save();c.clip();c.lineWidth=4;for(let k=-6;k<8;k++)c.beginPath(),c.moveTo(60+k*18,140),c.lineTo(160+k*18,250),c.moveTo(196-k*18,140),c.lineTo(96-k*18,250),c.stroke();c.restore()
|
||||
c.lineWidth=7;c.beginPath();c.moveTo(80,146);c.lineTo(176,146);c.lineTo(128,246);c.closePath();c.stroke()
|
||||
for(const[x,o]of[[108,0],[150,.5]]){
|
||||
const p=(t+o)%1,L=p<.7?10+40*(p/.7)**1.5:10+40*(1-(p-.7)/.3)**3,dy=p>=.7?150+50+(p-.7)/.3*90:0
|
||||
c.beginPath();c.roundRect(x-8,140,16,L+10,[0,0,8,8]);c.fill();c.stroke()
|
||||
if(dy){c.beginPath();c.arc(x,dy,7,0,T);c.fill();c.stroke()}
|
||||
}
|
||||
c.beginPath();c.arc(128,102,56,PI*.92,PI*.08)
|
||||
for(let k=0;k<=6;k++){const x=184-k*18.7;c.arc(x-9.3,148,9.4,0,PI)}
|
||||
c.closePath();c.fill();c.stroke()
|
||||
c.beginPath();c.moveTo(128,46);c.quadraticCurveTo(132,24,148,20);c.lineWidth=5;c.stroke()
|
||||
c.lineWidth=7;c.beginPath();c.arc(128,48,13,0,T);c.fill();c.stroke()
|
||||
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+d*18,104,5,0,T),c.fill()
|
||||
c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*12,90),c.lineTo(128+d*24,94),c.stroke()
|
||||
c.beginPath();c.moveTo(118,124);c.quadraticCurveTo(123,118,128,124);c.quadraticCurveTo(133,130,138,124);c.stroke()
|
||||
const sw=(t*2)%1
|
||||
c.save();c.translate(178,72+sw*20);c.fillStyle='#fff';c.beginPath();c.moveTo(0,-9);c.quadraticCurveTo(6,0,0,6);c.quadraticCurveTo(-6,0,0,-9);c.fill();c.lineWidth=4;c.stroke();c.restore()
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// leaf rocking down through the air like a pendulum while two small leaves tumble past behind it
|
||||
const{sin,cos,PI}=Math,T=2*PI
|
||||
export const frames=24,delay=70
|
||||
const leaf=(c,x,y,r,s)=>{
|
||||
c.save();c.translate(x,y);c.rotate(r);c.scale(s,s);c.lineWidth=7/s
|
||||
for(const[l,st]of[[10,'#111'],[4,'#fff']])c.lineWidth=l/s,c.strokeStyle=st,c.beginPath(),c.moveTo(-44,0),c.lineTo(-62,6),c.stroke()
|
||||
c.lineWidth=7/s;c.strokeStyle='#111';c.beginPath();c.moveTo(-46,0);c.quadraticCurveTo(0,-36,46,0);c.quadraticCurveTo(0,36,-46,0);c.fill();c.stroke()
|
||||
c.lineWidth=4/s;c.beginPath();c.moveTo(-44,0);c.lineTo(38,0);for(const v of[-22,-2,18])c.moveTo(v,0),c.lineTo(v+12,-13),c.moveTo(v,0),c.lineTo(v+12,13);c.stroke()
|
||||
c.restore()
|
||||
}
|
||||
export default(c,t)=>{
|
||||
for(const[x0,o,s]of[[56,0,.68],[200,.5,.58]]){const p=(t+o)%1;leaf(c,x0+24*sin(p*T*2),-40+p*336,p*T*2,s)}
|
||||
leaf(c,128+46*sin(t*T),122+22*cos(2*t*T),.5*sin(t*T)+.15,1.45)
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// grumpy storm cloud that zaps a lightning bolt twice and shakes when it does
|
||||
const{sin,cos,PI}=Math,T=2*PI
|
||||
export const frames=20,delay=80
|
||||
export default(c,t,i)=>{
|
||||
const z=i==2||i==3||i==6,sx=z?(i%2?3:-3):0
|
||||
if(z){
|
||||
c.beginPath();for(const[x,y]of[[146,136],[100,192],[132,192],[96,242],[172,170],[140,170],[168,136]])c.lineTo(x+sx,y);c.closePath();c.fill();c.stroke()
|
||||
for(const[a,l]of[[-2.7,18],[-2.1,22],[-.4,18],[-1,22]])
|
||||
for(const[w,s]of[[11,'#111'],[4,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(96+sx+cos(a)*16,240+sin(a)*16),c.lineTo(96+sx+cos(a)*(16+l),240+sin(a)*(16+l)),c.stroke()
|
||||
c.lineWidth=7;c.strokeStyle='#111'
|
||||
}
|
||||
const P=[[76,112,34],[122,84,46],[176,104,38]],base=()=>c.roundRect(40+sx,104,176,50,25)
|
||||
c.lineWidth=14;for(const[x,y,r]of P)c.beginPath(),c.arc(x+sx,y,r,0,T),c.stroke()
|
||||
c.beginPath();base();c.stroke()
|
||||
for(const[x,y,r]of P)c.beginPath(),c.arc(x+sx,y,r,0,T),c.fill()
|
||||
c.beginPath();base();c.fill()
|
||||
c.lineWidth=6;for(const d of[-1,1])c.beginPath(),c.moveTo(128+sx+d*36,110+(z?-2:0)),c.lineTo(128+sx+d*14,118),c.stroke()
|
||||
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+sx+d*24,126,5,0,T),c.fill()
|
||||
c.beginPath();if(z)c.ellipse(128+sx,144,8,6,0,0,T),c.fill();else c.arc(128+sx,148,9,PI*1.2,PI*1.8),c.stroke()
|
||||
c.fillStyle='#fff'
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// chunky bubble letters "lol" hopping one after another like a wave
|
||||
const{sin,max}=Math,T=2*Math.PI
|
||||
export const frames=20,delay=60
|
||||
export default(c,t)=>{
|
||||
const L=[[x=>{c.moveTo(x,70);c.lineTo(x,180)},48],[x=>{c.moveTo(x+32,148);c.arc(x,148,32,0,T)},128],[x=>{c.moveTo(x,70);c.lineTo(x,180)},208]]
|
||||
L.forEach(([f,x],k)=>{
|
||||
const h=max(0,sin(T*(t-k*.14))),y=-38*h**.8,sq=h<.15?1-(.15-h)*.6:1
|
||||
c.save();c.translate(x,212);c.scale(2-sq,sq);c.translate(-x,-212+y/sq)
|
||||
for(const[w,s]of[[44,'#111'],[28,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),f(x),c.stroke()
|
||||
c.restore()
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// envelope flap opens, a letter with a beating heart slides out, then tucks back in and the flap closes
|
||||
const{sin,cos,PI,min,max}=Math,T=2*PI
|
||||
export const frames=24,delay=70
|
||||
const ease=u=>(u=min(1,max(0,u)),u<.5?2*u*u:1-2*(1-u)**2)
|
||||
export default(c,t)=>{
|
||||
const fy=1-2*ease(t/.18)+2*ease((t-.82)/.18),ly=118-78*ease((t-.18)/.25)+78*ease((t-.62)/.2),hb=1+.15*sin(2*T*t*3)
|
||||
const flap=()=>{c.beginPath();c.moveTo(48,110);c.lineTo(128,110+64*fy);c.lineTo(208,110);c.closePath();c.fill();c.stroke()}
|
||||
c.beginPath();c.roundRect(48,108,160,108,10);c.fill();c.stroke()
|
||||
if(fy<0)flap()
|
||||
c.beginPath();c.rect(68,ly,120,96);c.fill();c.stroke()
|
||||
c.lineWidth=4;for(const y of[64,76])c.beginPath(),c.moveTo(92,ly+y),c.lineTo(164,ly+y),c.stroke()
|
||||
c.save();c.translate(128,ly+32);c.scale(hb,hb);c.fillStyle='#111';c.beginPath();c.moveTo(0,16);c.bezierCurveTo(-26,-2,-14,-22,0,-10);c.bezierCurveTo(14,-22,26,-2,0,16);c.fill();c.restore()
|
||||
c.lineWidth=7;c.fillStyle='#fff'
|
||||
c.beginPath();c.moveTo(48,116);c.lineTo(128,172);c.lineTo(208,116);c.lineTo(208,206);c.quadraticCurveTo(208,216,198,216);c.lineTo(58,216);c.quadraticCurveTo(48,216,48,206);c.closePath();c.fill();c.stroke()
|
||||
if(fy>=0)flap()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// pair of music notes bouncing on the beat while little notes float up on either side
|
||||
const{sin,cos,PI,abs}=Math,T=2*PI
|
||||
export const frames=20,delay=70
|
||||
const D=(c,f,a=18,b=6)=>{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 head=(c,x,y,s=1)=>{c.beginPath();c.ellipse(x,y,22*s,15*s,-.35,0,T);c.fill();c.stroke()}
|
||||
export default(c,t)=>{
|
||||
for(const[x0,o,d]of[[40,0,1],[216,.5,-1]]){
|
||||
const p=(t+o)%1,s=.55*sin(PI*p),x=x0+10*sin(p*T),y=230-p*170
|
||||
if(s<.08)continue
|
||||
c.save();c.translate(x,y);c.scale(s,s)
|
||||
D(c,()=>{c.moveTo(18,-6);c.lineTo(18,-80);c.quadraticCurveTo(26,-56,44,-50)},16,6)
|
||||
c.lineWidth=7/s;head(c,0,0);c.restore()
|
||||
}
|
||||
const b=abs(sin(2*PI*t)),y=-26*b,sq=1+.08*(1-b)
|
||||
c.translate(128,200);c.scale(sq,2-sq);c.translate(-128,-200+y)
|
||||
D(c,()=>{c.moveTo(110,176);c.lineTo(110,74);c.moveTo(182,156);c.lineTo(182,54)})
|
||||
c.beginPath();c.moveTo(104,64);c.lineTo(188,40);c.lineTo(188,68);c.lineTo(104,92);c.closePath();c.fill();c.stroke()
|
||||
head(c,90,182);head(c,162,162)
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// striped popcorn bucket with kernels popping up out of the pile and dropping back in
|
||||
const{sin,cos,PI}=Math,T=2*PI
|
||||
export const frames=20,delay=60
|
||||
const kernel=(c,x,y,a,s=1)=>{
|
||||
const B=[[0,0,11],[10,-6,9],[-9,-7,9],[2,-14,8]]
|
||||
c.save();c.translate(x,y);c.rotate(a);c.scale(s,s)
|
||||
c.lineWidth=12/s;for(const[bx,by,r]of B)c.beginPath(),c.arc(bx,by,r,0,T),c.stroke()
|
||||
for(const[bx,by,r]of B)c.beginPath(),c.arc(bx,by,r,0,T),c.fill()
|
||||
c.restore()
|
||||
}
|
||||
export default(c,t)=>{
|
||||
const pile=[[84,120],[106,108],[130,104],[154,110],[174,122],[96,128],[120,124],[146,126],[164,130]]
|
||||
for(const[x,y]of pile)kernel(c,x,y,x*.1)
|
||||
for(const[x0,vx,h,o]of[[100,-50,80,0],[150,46,70,.35],[124,10,88,.7]]){
|
||||
const p=(t*1.5+o)%1,x=x0+vx*sin(PI*p),y=112-h*4*p*(1-p)
|
||||
kernel(c,x,y,p*T*(vx>0?1:-1),1.1)
|
||||
}
|
||||
c.lineWidth=7
|
||||
const bucket=()=>{c.beginPath();c.moveTo(68,132);c.lineTo(188,132);c.lineTo(172,238);c.lineTo(84,238);c.closePath()}
|
||||
bucket();c.fill()
|
||||
c.save();bucket();c.clip();c.fillStyle='#111'
|
||||
for(const k of[-1,1])c.beginPath(),c.moveTo(128+k*30-10,132),c.lineTo(128+k*30+10,132),c.lineTo(128+k*25+8,238),c.lineTo(128+k*25-8,238),c.fill()
|
||||
c.restore();bucket();c.stroke()
|
||||
c.beginPath();c.roundRect(62,126,132,14,5);c.fill();c.stroke()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// rocket blasting along with its flame flickering, body rattling and speed lines streaking past
|
||||
const{sin,PI}=Math,T=2*PI
|
||||
export const frames=16,delay=50
|
||||
export default(c,t,i)=>{
|
||||
for(const[x,len,o]of[[34,46,0],[66,30,.5],[196,38,.25],[226,52,.75]]){
|
||||
const y=((t*2+o)%1)*(256+len*2)-len*2
|
||||
for(const[w,s]of[[11,'#111'],[4,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(x,y),c.lineTo(x,y+len),c.stroke()
|
||||
}
|
||||
c.lineWidth=7;c.strokeStyle='#111'
|
||||
c.translate(i%2?2:-2,0)
|
||||
const h=44+10*sin(2*T*t)+6*sin(5*T*t)
|
||||
c.beginPath();c.moveTo(108,178);c.quadraticCurveTo(110,178+h*.7,128,178+h);c.quadraticCurveTo(146,178+h*.7,148,178);c.closePath();c.fill();c.stroke()
|
||||
c.fillStyle='#111';c.beginPath();c.moveTo(118,182);c.quadraticCurveTo(120,180+h*.45,128,180+h*.6);c.quadraticCurveTo(136,180+h*.45,138,182);c.closePath();c.fill();c.fillStyle='#fff'
|
||||
for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*30,128),c.quadraticCurveTo(128+d*56,150,128+d*58,186),c.lineTo(128+d*30,172),c.closePath(),c.fill(),c.stroke()
|
||||
c.beginPath();c.roundRect(110,166,36,16,4);c.fill();c.stroke()
|
||||
c.beginPath();c.moveTo(128,28);c.bezierCurveTo(162,52,162,96,160,170);c.lineTo(96,170);c.bezierCurveTo(94,96,94,52,128,28);c.closePath();c.fill();c.stroke()
|
||||
c.lineWidth=5;c.beginPath();c.moveTo(106,62);c.quadraticCurveTo(128,70,150,62);c.stroke()
|
||||
c.lineWidth=7;c.beginPath();c.arc(128,106,19,0,T);c.fill();c.stroke()
|
||||
c.lineWidth=4;c.beginPath();c.arc(128,106,11,PI*1.1,PI*1.6);c.stroke()
|
||||
c.lineWidth=7;c.beginPath();c.moveTo(128,140);c.lineTo(128,166);c.stroke()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// snowflakes of different sizes drifting down and slowly spinning
|
||||
const{sin,cos,PI}=Math,T=2*PI
|
||||
export const frames=20,delay=90
|
||||
const F=[[46,0,20,1],[112,.3,30,1],[186,.62,24,1],[228,.15,16,1],[150,.82,38,1],[70,.55,26,1],[206,.42,32,1]]
|
||||
export default(c,t)=>{
|
||||
for(const[x0,o,r,n]of F){
|
||||
const p=(t*n+o)%1,x=x0+12*sin(p*T+o*7),y=-r-6+p*(256+2*r+12),a=t*T/6*(n%2?1:-1)
|
||||
for(const[l,s]of[[10,'#111'],[4,'#fff']]){
|
||||
c.lineWidth=l;c.strokeStyle=s;c.beginPath()
|
||||
for(let k=0;k<6;k++){
|
||||
const b=a+k*PI/3,ux=cos(b),uy=sin(b),m=r*.55,q=r*.28
|
||||
c.moveTo(x,y);c.lineTo(x+ux*r,y+uy*r)
|
||||
for(const d of[-1,1])c.moveTo(x+ux*m,y+uy*m),c.lineTo(x+ux*m+cos(b+d*.9)*q,y+uy*m+sin(b+d*.9)*q)
|
||||
}
|
||||
c.stroke()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// big sparkle pulsing in the middle while small sparkles pop in and out around it
|
||||
const{sin,PI,max}=Math,T=2*PI
|
||||
export const frames=20,delay=70
|
||||
const star=(c,x,y,r,a=0)=>{
|
||||
const k=r*.16;c.save();c.translate(x,y);c.rotate(a);c.beginPath();c.moveTo(0,-r)
|
||||
for(const[px,py,qx,qy]of[[r,0,k,-k],[0,r,k,k],[-r,0,-k,k],[0,-r,-k,-k]])c.quadraticCurveTo(qx,qy,px,py)
|
||||
c.restore();c.fill();c.stroke()
|
||||
}
|
||||
export default(c,t)=>{
|
||||
c.lineWidth=5
|
||||
for(const[x,y,r,o]of[[52,60,26,0],[206,54,20,.17],[214,176,28,.33],[60,190,22,.5],[150,222,16,.66],[96,30,14,.83]]){
|
||||
const s=max(0,sin(PI*((t*2+o)%1)))
|
||||
if(s>.08)star(c,x,y,r*s,.3*s)
|
||||
}
|
||||
c.lineWidth=7;star(c,128,128,62+10*sin(t*T),.12*sin(t*T))
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// loading ring of dots with a fading trail, and a little face in the middle watching it go round
|
||||
const{sin,cos,PI}=Math,T=2*PI
|
||||
export const delay=60
|
||||
export default(c,t)=>{
|
||||
const h=t*T
|
||||
c.lineWidth=5
|
||||
for(let k=0;k<10;k++){
|
||||
const a=k*T/10-PI/2,g=((t-k/10)%1+1)%1,r=5+13*(1-g)**1.6
|
||||
c.beginPath();c.arc(128+cos(a)*78,128+sin(a)*78,r,0,T);c.fill();c.stroke()
|
||||
}
|
||||
c.lineWidth=7;c.beginPath();c.arc(128,128,40,0,T);c.fill();c.stroke()
|
||||
const ex=cos(h-PI/2)*5,ey=sin(h-PI/2)*5
|
||||
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+d*13+ex,122+ey,6,0,T),c.fill()
|
||||
c.lineWidth=5;c.beginPath();c.arc(128+ex*.5,140+ey*.5,6,0,T);c.stroke()
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// sprout boings up out of the dirt, opens its leaves, wiggles happily, then ducks back down
|
||||
const{sin,cos,PI,min,max}=Math,T=2*PI
|
||||
export const frames=24,delay=70
|
||||
const back=u=>{const s=1.9;return 1+(s+1)*(u-1)**3+s*(u-1)**2}
|
||||
export default(c,t)=>{
|
||||
const g=t<.3?back(t/.3):t<.8?1:1-((t-.8)/.2)**2,H=112*g
|
||||
const o=min(1,max(0,(t-.18)/.22))*(t>.8?1-(t-.8)/.2:1),sw=t>.3&&t<.8?.22*sin((t-.3)/.5*2*T*2):0
|
||||
const tx=128+sw*H*.5,ty=214-H
|
||||
if(H>2){
|
||||
for(const[l,s]of[[16,'#111'],[4,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(128,226),c.quadraticCurveTo(128,214-H*.5,tx,ty),c.stroke()
|
||||
c.lineWidth=7;c.strokeStyle='#111'
|
||||
for(const d of[-1,1]){
|
||||
c.save();c.translate(tx,ty);c.rotate(d*(.15+1.05*o)+sw);c.scale(.5+.8*g,.5+.8*g)
|
||||
c.beginPath();c.moveTo(0,0);c.bezierCurveTo(d*10,-30,d*44,-40,d*40,-16);c.bezierCurveTo(d*38,-4,d*16,4,0,0);c.restore();c.fill();c.stroke()
|
||||
c.lineWidth=4;c.save();c.translate(tx,ty);c.rotate(d*(.15+1.05*o)+sw);c.scale(.5+.8*g,.5+.8*g);c.beginPath();c.moveTo(d*4,-4);c.quadraticCurveTo(d*20,-20,d*32,-18);c.restore();c.stroke();c.lineWidth=7
|
||||
}
|
||||
}
|
||||
c.lineWidth=7;c.beginPath();c.ellipse(128,232,76,26,0,PI,T);c.closePath();c.fill();c.stroke()
|
||||
c.fillStyle='#111';for(const[x,y]of[[96,224],[112,216],[150,220],[166,226],[132,224]])c.beginPath(),c.arc(x,y,3,0,T),c.fill()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// thumbs up bouncing on the beat while little sparkles pop around it
|
||||
const{sin,cos,PI,max}=Math,T=2*PI
|
||||
export const delay=70
|
||||
const star=(c,x,y,s)=>{c.beginPath();for(let k=0;k<8;k++){const r=k%2?s*.32:s,a=k*PI/4;c.lineTo(x+r*cos(a),y+r*sin(a))}c.closePath();c.fill();c.stroke()}
|
||||
export default(c,t)=>{
|
||||
const b=max(0,sin(2*T*t)),y=-14*b,r=-.06+.1*sin(2*T*t-.6)
|
||||
c.lineWidth=5;for(const[x,yy,p]of[[48,70,0],[208,92,.33],[196,30,.66]]){const s=16*max(0,sin(((t+p)%1)*T*2));if(s>1)star(c,x,yy,s)}
|
||||
c.lineWidth=7
|
||||
c.translate(128,226+y);c.rotate(r);c.translate(-128,-226)
|
||||
c.save();c.translate(104,128);c.rotate(-.12);c.beginPath();c.roundRect(-17,-82,34,96,17);c.restore();c.fill();c.stroke()
|
||||
c.lineWidth=4;c.save();c.translate(104,128);c.rotate(-.12);c.beginPath();c.arc(0,-62,10,PI*1.1,PI*1.9);c.stroke();c.restore();c.lineWidth=7
|
||||
c.beginPath();c.roundRect(74,112,56,100,20);c.fill();c.stroke()
|
||||
for(let k=0;k<4;k++)c.beginPath(),c.roundRect(100,114+k*24,74,26,13),c.fill(),c.stroke()
|
||||
c.beginPath();c.roundRect(76,204,82,26,6);c.fill();c.stroke()
|
||||
c.lineWidth=4;c.beginPath();c.moveTo(86,212);c.lineTo(148,212);c.moveTo(86,222);c.lineTo(148,222);c.stroke()
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
Reference in New Issue
Block a user