Add gift/open, note/bounce, clock/tick, icecream/melt, popcorn/pop, cake/candle, lol/bounce, rocket/launch
Brings the gallery to 50. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@@ -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,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,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,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,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,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,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,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()
|
||||
}
|
||||
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 64 KiB |