Add colored hearts/float, gamepad/press, headphones/bop, camera/flash, phone/ring, trophy/shine, dice/roll, magnet/pull, brush/paint, battery/charge
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@@ -0,0 +1,22 @@
|
|||||||
|
// battery charging up bar by bar from red to green, sparks running down the cable, happy when full
|
||||||
|
const{sin,cos,PI,floor,max}=Math,T=2*PI
|
||||||
|
export const frames=25,delay=110
|
||||||
|
const LV=['#ff6b6b','#ffa94d','#ffd43b','#51cf66'],CB='#495057'
|
||||||
|
export default(c,t)=>{
|
||||||
|
const n=floor(t*5),full=n>=4,col=LV[max(0,n-1)]
|
||||||
|
for(const[w,st]of[[14,'#111'],[6,'#ced4da']])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.moveTo(0,200),c.bezierCurveTo(30,200,10,128,36,128),c.stroke()
|
||||||
|
if(!full)for(let k=0;k<3;k++){const p=(t*3+k/3)%1,u=p,x=(1-u)**3*0+3*(1-u)**2*u*30+3*(1-u)*u*u*10+u**3*36,y=(1-u)**3*200+3*(1-u)**2*u*200+3*(1-u)*u*u*128+u**3*128;c.fillStyle='#ffd43b';c.lineWidth=3;c.strokeStyle='#111';c.beginPath();c.arc(x,y,4,0,T);c.fill();c.stroke()}
|
||||||
|
c.strokeStyle='#111';c.lineWidth=7
|
||||||
|
c.fillStyle=CB;c.beginPath();c.roundRect(30,114,16,28,4);c.fill();c.stroke()
|
||||||
|
c.fillStyle='#fff';c.beginPath();c.roundRect(46,72,160,112,20);c.fill();c.stroke()
|
||||||
|
c.fillStyle='#ced4da';c.beginPath();c.roundRect(206,106,18,44,6);c.fill();c.stroke()
|
||||||
|
c.lineWidth=5;for(let k=0;k<4;k++)if(k<n){c.fillStyle=col;c.beginPath();c.roundRect(60+k*36,86,30,84,8);c.fill();c.stroke()}
|
||||||
|
c.lineWidth=7
|
||||||
|
if(!full&&floor(t*10)%2==0){c.fillStyle='#ffd43b';c.beginPath();for(const[x,y]of[[136,92],[110,134],[128,134],[118,166],[148,120],[130,120],[142,92]])c.lineTo(x,y);c.closePath();c.lineWidth=5;c.fill();c.stroke();c.lineWidth=7}
|
||||||
|
if(full){
|
||||||
|
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(126+d*22,118,6,0,T),c.fill()
|
||||||
|
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.arc(126+d*22-2,116,2.2,0,T),c.fill()
|
||||||
|
c.lineWidth=5;c.beginPath();c.arc(126,128,12,.15*PI,.85*PI);c.stroke()
|
||||||
|
for(const[x,y]of[[44,54],[214,56],[226,198],[60,206]]){const s=10;c.lineWidth=4;c.fillStyle='#fff';c.beginPath();c.moveTo(x,y-s);for(const[px,py,qx,qy]of[[s,0,s*.18,-s*.18],[0,s,s*.18,s*.18],[-s,0,-s*.18,s*.18],[0,-s,-s*.18,-s*.18]])c.quadraticCurveTo(x+qx,y+qy,x+px,y+py);c.fill();c.stroke()}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
// paintbrush looping around a figure eight, leaving a rainbow stroke trailing behind its tip
|
||||||
|
const{sin,cos,PI,atan2}=Math,T=2*PI
|
||||||
|
export const frames=24,delay=60
|
||||||
|
const pos=u=>[128+78*sin(u*T),128+46*sin(2*u*T)]
|
||||||
|
const hue=k=>`hsl(${(k*300)%360},85%,65%)`
|
||||||
|
export default(c,t)=>{
|
||||||
|
const N=36,L=.5
|
||||||
|
for(const[w,a]of[[30,0],[18,1]])for(let k=0;k<N;k++){
|
||||||
|
const u0=t-L+k*L/N,u1=u0+L/N,[x0,y0]=pos(u0),[x1,y1]=pos(u1+.002)
|
||||||
|
c.lineWidth=w*(.4+.6*k/N);c.strokeStyle=a?hue(u0+5):'#111';c.beginPath();c.moveTo(x0,y0);c.lineTo(x1,y1);c.stroke()
|
||||||
|
}
|
||||||
|
c.strokeStyle='#111';c.lineWidth=7
|
||||||
|
const[x,y]=pos(t),[px,py]=pos(t-.01),ang=atan2(y-py,x-px)
|
||||||
|
c.save();c.translate(x,y);c.rotate(-PI/4+.25*sin(t*T))
|
||||||
|
c.fillStyle=hue(t+5);c.beginPath();c.moveTo(0,0);c.quadraticCurveTo(-12,-14,-10,-30);c.lineTo(10,-30);c.quadraticCurveTo(12,-14,0,0);c.fill();c.stroke()
|
||||||
|
c.fillStyle='#ced4da';c.beginPath();c.roundRect(-12,-48,24,20,3);c.fill();c.stroke()
|
||||||
|
c.fillStyle='#e0a96d';c.beginPath();c.moveTo(-9,-48);c.lineTo(-6,-110);c.quadraticCurveTo(0,-118,6,-110);c.lineTo(9,-48);c.closePath();c.fill();c.stroke()
|
||||||
|
c.restore()
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// instant camera fires its flash, a photo with a heart on it slides out the bottom and drops away
|
||||||
|
const{sin,cos,PI,min,max}=Math,T=2*PI
|
||||||
|
export const frames=24,delay=70
|
||||||
|
const BODY='#fff4e6',TOP='#ced4da',LENS='#343a40',GLASS='#74c0fc',STR=['#ff6b6b','#ffa94d','#ffd43b','#51cf66','#4dabf7'],PIC='#a5d8ff'
|
||||||
|
export default(c,t,i)=>{
|
||||||
|
const fl=t>=.18&&t<.3,out=min(1,max(0,(t-.3)/.35)),drop=max(0,(t-.72)/.2)
|
||||||
|
const py=150+out*62+drop*drop*160
|
||||||
|
c.save();c.translate(128,py);c.rotate(drop*.6)
|
||||||
|
c.fillStyle='#fff';c.beginPath();c.roundRect(-46,-30,92,100,6);c.fill();c.stroke()
|
||||||
|
c.fillStyle=PIC;c.beginPath();c.rect(-36,-20,72,62);c.fill();c.lineWidth=4;c.stroke()
|
||||||
|
c.fillStyle='#ff6b6b';c.beginPath();c.moveTo(0,22);c.bezierCurveTo(-22,6,-14,-12,0,-2);c.bezierCurveTo(14,-12,22,6,0,22);c.fill();c.stroke()
|
||||||
|
c.restore();c.lineWidth=7
|
||||||
|
if(fl)for(let k=0;k<8;k++){const a=k*T/8,r1=26,r2=44;for(const[w,st]of[[11,'#111'],[4,'#ffd43b']])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.moveTo(70+cos(a)*r1,58+sin(a)*r1),c.lineTo(70+cos(a)*r2,58+sin(a)*r2),c.stroke();c.strokeStyle='#111'}
|
||||||
|
c.lineWidth=7
|
||||||
|
c.fillStyle=TOP;c.beginPath();c.roundRect(40,62,176,40,[20,20,0,0]);c.fill();c.stroke()
|
||||||
|
c.fillStyle='#ff6b6b';c.beginPath();c.roundRect(176,48,26,16,5);c.fill();c.stroke()
|
||||||
|
c.fillStyle=BODY;c.beginPath();c.roundRect(36,92,184,110,22);c.fill();c.stroke()
|
||||||
|
c.save();c.beginPath();c.roundRect(36,92,184,110,22);c.clip();STR.forEach((col,k)=>{c.fillStyle=col;c.fillRect(56+k*9,92,9,110)});c.restore()
|
||||||
|
c.beginPath();c.roundRect(36,92,184,110,22);c.stroke()
|
||||||
|
c.fillStyle=fl?'#fff':'#e7f5ff';c.beginPath();c.roundRect(54,70,32,22,6);c.fill();c.lineWidth=5;c.stroke()
|
||||||
|
c.fillStyle='#111';c.beginPath();c.roundRect(170,70,26,18,5);c.fill()
|
||||||
|
c.lineWidth=7;c.fillStyle=LENS;c.beginPath();c.arc(140,146,44,0,T);c.fill();c.stroke()
|
||||||
|
const ap=fl?18:28
|
||||||
|
c.fillStyle=GLASS;c.beginPath();c.arc(140,146,ap,0,T);c.fill();c.lineWidth=5;c.stroke()
|
||||||
|
c.fillStyle='#fff';c.beginPath();c.ellipse(132,138,ap*.28,ap*.18,-.6,0,T);c.fill()
|
||||||
|
c.fillStyle='#111';c.beginPath();c.roundRect(64,194,128,8,4);c.fill()
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// two dice bouncing and tumbling, landing on a new number every bounce
|
||||||
|
const{sin,cos,PI,abs,floor}=Math,T=2*PI
|
||||||
|
export const frames=24,delay=60
|
||||||
|
const PIPS={1:[[0,0]],2:[[-1,-1],[1,1]],3:[[-1,-1],[0,0],[1,1]],4:[[-1,-1],[1,-1],[-1,1],[1,1]],5:[[-1,-1],[1,-1],[0,0],[-1,1],[1,1]],6:[[-1,-1],[1,-1],[-1,0],[1,0],[-1,1],[1,1]]}
|
||||||
|
const die=(c,x,y,a,col,n)=>{
|
||||||
|
c.save();c.translate(x,y);c.rotate(a)
|
||||||
|
c.fillStyle=col;c.beginPath();c.roundRect(-34,-34,68,68,14);c.fill();c.stroke()
|
||||||
|
c.fillStyle='#fff';c.lineWidth=3;for(const[px,py]of PIPS[n])c.beginPath(),c.arc(px*17,py*17,6.5,0,T),c.fill(),c.stroke()
|
||||||
|
c.restore();c.lineWidth=7
|
||||||
|
}
|
||||||
|
export default(c,t)=>{
|
||||||
|
for(const[x,o,col,seq]of[[80,0,'#ff6b6b',[3,5]],[176,.25,'#4dabf7',[6,2]]]){
|
||||||
|
const u=(t+o)%1,h=abs(sin(2*PI*u)),y=196-90*h,a=u*PI*(o?-1:1),n=seq[floor(u*2)%2]
|
||||||
|
c.fillStyle='rgba(0,0,0,0)'
|
||||||
|
die(c,x,y,a,col,n)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// game controller wiggling as its four colored buttons get pressed one after another
|
||||||
|
const{sin,cos,PI,floor}=Math,T=2*PI
|
||||||
|
export const frames=24,delay=70
|
||||||
|
const BODY='#9775fa',DP='#495057',BTN=[['#ffd43b',0,-20],['#4dabf7',-20,0],['#51cf66',0,20],['#ff6b6b',20,0]]
|
||||||
|
export default(c,t)=>{
|
||||||
|
const k=floor(t*4),u=(t*4)%1,pr=u<.45,r=.05*sin(t*T*4)
|
||||||
|
c.translate(128,140);c.rotate(r);c.translate(-128,-140)
|
||||||
|
const body=()=>{c.roundRect(34,84,188,86,43)},grips=[[70,168,32],[186,168,32]]
|
||||||
|
c.lineWidth=14;c.beginPath();body();c.stroke();for(const[x,y,rr]of grips)c.beginPath(),c.arc(x,y,rr,0,T),c.stroke()
|
||||||
|
c.fillStyle=BODY;c.beginPath();body();c.fill();for(const[x,y,rr]of grips)c.beginPath(),c.arc(x,y,rr,0,T),c.fill()
|
||||||
|
c.lineWidth=7;c.fillStyle=DP;c.beginPath();c.moveTo(78,104);for(const[x,y]of[[90,104],[90,116],[102,116],[102,128],[90,128],[90,140],[78,140],[78,128],[66,128],[66,116],[78,116]])c.lineTo(x,y);c.closePath();c.fill();c.lineWidth=5;c.stroke()
|
||||||
|
BTN.forEach(([col,dx,dy],i)=>{
|
||||||
|
const on=i==k&&pr,s=on?.78:1,x=176+dx,y=122+dy
|
||||||
|
c.fillStyle=col;c.beginPath();c.arc(x,y+(on?2:0),10*s,0,T);c.fill();c.lineWidth=5;c.stroke()
|
||||||
|
if(on)for(let j=0;j<3;j++){const a=-PI/2+(j-1)*.7+Math.atan2(dy,dx)+PI/2;for(const[w,st]of[[9,'#111'],[3,'#fff']])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.moveTo(x+cos(a)*16,y+sin(a)*16),c.lineTo(x+cos(a)*24,y+sin(a)*24),c.stroke();c.strokeStyle='#111'}
|
||||||
|
})
|
||||||
|
c.fillStyle='#e5dbff';c.lineWidth=4;for(const x of[118,138])c.beginPath(),c.roundRect(x-7,104,14,6,3),c.fill(),c.stroke()
|
||||||
|
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+d*12,134,4.5,0,T),c.fill()
|
||||||
|
c.lineWidth=4;c.beginPath();c.arc(128,140,6,.15*PI,.85*PI);c.stroke()
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
// headphones bopping to the beat, ear cups thumping, music notes popping out the sides
|
||||||
|
const{sin,cos,PI,max,abs}=Math,T=2*PI
|
||||||
|
export const frames=16,delay=70
|
||||||
|
const BAND='#4dabf7',CUP='#f783ac',CUSH='#ffd43b',NOTES=['#b197fc','#69db7c','#ffa94d']
|
||||||
|
export default(c,t)=>{
|
||||||
|
const b=abs(sin(2*PI*t)),y=-8*b,s=1+.06*b
|
||||||
|
for(const d of[-1,1])for(let k=0;k<2;k++){
|
||||||
|
const p=(t+k/2+(d>0?.25:0))%1,sz=sin(PI*p)*.9,x=128+d*(86+p*30),yy=150-p*110
|
||||||
|
if(sz<.15)continue
|
||||||
|
c.save();c.translate(x,yy);c.scale(sz,sz);c.rotate(.3*sin(p*T))
|
||||||
|
for(const[w,st]of[[12,'#111'],[5,NOTES[(k+(d>0?1:0))%3]]])c.lineWidth=w/sz>30?30:w,c.strokeStyle=st,c.beginPath(),c.moveTo(8,4),c.lineTo(8,-30),c.quadraticCurveTo(14,-18,24,-16),c.stroke()
|
||||||
|
c.strokeStyle='#111';c.lineWidth=5;c.fillStyle=NOTES[(k+(d>0?1:0))%3];c.beginPath();c.ellipse(0,6,11,8,-.4,0,T);c.fill();c.stroke()
|
||||||
|
c.restore()
|
||||||
|
}
|
||||||
|
c.translate(0,y)
|
||||||
|
for(const[w,st]of[[26,'#111'],[14,BAND]])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.arc(128,140,78,PI*1.05,PI*1.95),c.stroke()
|
||||||
|
c.strokeStyle='#111';c.lineWidth=7
|
||||||
|
for(const d of[-1,1]){
|
||||||
|
c.save();c.translate(128+d*80,152);c.scale(s,s)
|
||||||
|
c.fillStyle=CUSH;c.beginPath();c.roundRect(-d*22-10,-34,20,68,10);c.fill();c.stroke()
|
||||||
|
c.fillStyle=CUP;c.beginPath();c.roundRect(-18+d*6,-42,36,84,18);c.fill();c.stroke()
|
||||||
|
c.lineWidth=4;c.beginPath();c.arc(d*6,0,10,0,T);c.stroke()
|
||||||
|
c.restore()
|
||||||
|
}
|
||||||
|
if(b>.7)for(const d of[-1,1])for(const r of[20,32])for(const[w,st]of[[9,'#111'],[3,'#fff']])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.arc(128+d*86,152,r+20,d>0?-.5:PI-.5,d>0?.5:PI+.5),c.stroke()
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// hearts of different colors floating up and swaying, swelling in and shrinking away as they rise
|
||||||
|
const{sin,cos,PI}=Math,T=2*PI
|
||||||
|
export const frames=24,delay=70
|
||||||
|
const H=[[60,0,'#ff6b6b',34],[128,.5,'#f783ac',44],[196,.25,'#b197fc',30],[96,.75,'#ffa94d',24],[168,.85,'#ff8787',26],[40,.4,'#faa2c1',22]]
|
||||||
|
export default(c,t)=>{
|
||||||
|
for(const[x0,o,col,r]of H){
|
||||||
|
const p=(t+o)%1,s=r*sin(PI*p)/22,x=x0+14*sin(p*T+o*9),y=236-p*210
|
||||||
|
if(s<.15)continue
|
||||||
|
c.save();c.translate(x,y);c.rotate(.25*sin(p*T*2+o*5));c.scale(s,s)
|
||||||
|
c.beginPath();c.moveTo(0,16);c.bezierCurveTo(-26,-2,-18,-24,0,-11);c.bezierCurveTo(18,-24,26,-2,0,16);c.restore()
|
||||||
|
c.fillStyle=col;c.lineWidth=Math.min(7,3+s*2);c.fill();c.stroke()
|
||||||
|
c.fillStyle='#fff';c.beginPath();c.ellipse(x-8*s,y-8*s,3.5*s,2*s,-.6,0,T);c.fill()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
// horseshoe magnet pulling paperclips in, holding them, then dropping them and starting again
|
||||||
|
const{sin,cos,PI,min,max}=Math,T=2*PI
|
||||||
|
export const frames=24,delay=70
|
||||||
|
const R='#fa5252',TIP='#ced4da',CL='#adb5bd'
|
||||||
|
const clip=(c,x,y,a)=>{
|
||||||
|
c.save();c.translate(x,y);c.rotate(a)
|
||||||
|
for(const[w,st]of[[9,'#111'],[4,CL]])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.moveTo(14,-6),c.lineTo(-12,-6),c.arc(-12,0,6,-PI/2,PI/2,true),c.lineTo(12,6),c.arc(12,1,5,PI/2,-PI/2,true),c.lineTo(-8,-4),c.stroke()
|
||||||
|
c.restore();c.strokeStyle='#111';c.lineWidth=7
|
||||||
|
}
|
||||||
|
export default(c,t,i)=>{
|
||||||
|
const pull=min(1,t/.5),e=pull*pull,hold=t>=.5&&t<.75,drop=max(0,(t-.75)/.25),sh=hold?(i%2?2:-2):0
|
||||||
|
if(t<.5)for(let k=0;k<3;k++){const a=-PI*.3+k*.3;for(const[w,st]of[[8,'#111'],[3,'#fff']])c.lineWidth=w,c.strokeStyle=st,c.setLineDash([8,10]),c.lineDashOffset=-t*80,c.beginPath(),c.arc(150,128,70+k*18,a-.4,a+.4),c.stroke();c.setLineDash([])}
|
||||||
|
c.strokeStyle='#111';c.lineWidth=7
|
||||||
|
for(const[y0,tipY,o]of[[56,70,0],[204,186,.2],[128,96,.1]]){
|
||||||
|
const sx=286,tx=212+(o*30),x=drop?tx+o*20:sx+(tx-sx)*e,y=drop?tipY+drop*drop*200:y0+(tipY-y0)*e,a=drop?drop*3+o*5:(1-e)*2+o
|
||||||
|
clip(c,x+sh,y,a)
|
||||||
|
}
|
||||||
|
c.translate(sh,0)
|
||||||
|
c.fillStyle=R;c.beginPath();c.moveTo(176,45);c.lineTo(110,45);c.arc(110,128,83,-PI/2,PI/2,true);c.lineTo(176,211);c.lineTo(176,161);c.lineTo(110,161);c.arc(110,128,33,PI/2,-PI/2);c.lineTo(176,95);c.closePath();c.fill();c.stroke()
|
||||||
|
c.fillStyle=TIP;for(const y of[45,161])c.beginPath(),c.roundRect(174,y,30,50,[0,6,6,0]),c.fill(),c.stroke()
|
||||||
|
c.fillStyle='#fff';c.beginPath();c.ellipse(60,104,6,16,.5,0,T);c.fill()
|
||||||
|
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(48,128+d*12,4.5,0,T),c.fill()
|
||||||
|
c.lineWidth=4;c.beginPath();c.arc(56,128,7,-.35*PI,.35*PI);c.stroke()
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// phone buzzing with an incoming call from a smiley, ring waves on each side, green button pulsing
|
||||||
|
const{sin,cos,PI}=Math,T=2*PI
|
||||||
|
export const frames=20,delay=60
|
||||||
|
const BODY='#9775fa',SCR='#e7f5ff',AV='#ffd43b',GO='#51cf66',NO='#ff6b6b'
|
||||||
|
export default(c,t,i)=>{
|
||||||
|
const buzz=(t*2)%1<.6,r=buzz?(i%2?.07:-.07):0,p=1+.12*sin(4*T*t)
|
||||||
|
if(buzz)for(const d of[-1,1])for(const rr of[96,116])for(const[w,st]of[[11,'#111'],[4,'#fff']])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.arc(128,128,rr,d>0?-.4:PI-.4,d>0?.4:PI+.4),c.stroke()
|
||||||
|
c.strokeStyle='#111';c.lineWidth=7
|
||||||
|
c.translate(128,128);c.rotate(r);c.translate(-128,-128)
|
||||||
|
c.fillStyle=BODY;c.beginPath();c.roundRect(76,24,104,208,22);c.fill();c.stroke()
|
||||||
|
c.fillStyle=SCR;c.beginPath();c.roundRect(88,46,80,164,10);c.fill();c.lineWidth=5;c.stroke()
|
||||||
|
c.fillStyle='#111';c.beginPath();c.roundRect(114,32,28,7,3.5);c.fill()
|
||||||
|
c.lineWidth=5;c.fillStyle=AV;c.beginPath();c.arc(128,96,26,0,T);c.fill();c.stroke()
|
||||||
|
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(128+d*9,92,3.5,0,T),c.fill()
|
||||||
|
c.lineWidth=4;c.beginPath();c.arc(128,99,8,.15*PI,.85*PI);c.stroke()
|
||||||
|
c.lineWidth=5;for(const[x,col,s]of[[106,NO,1],[150,GO,p]]){
|
||||||
|
c.save();c.translate(x,176);c.scale(s,s);c.fillStyle=col;c.beginPath();c.arc(0,0,14,0,T);c.fill();c.stroke()
|
||||||
|
c.strokeStyle='#fff';c.lineWidth=4;c.beginPath();c.arc(0,4,7,PI*1.15,PI*1.85);c.stroke();c.restore()
|
||||||
|
}
|
||||||
|
c.fillStyle='#adb5bd';for(const[x,w]of[[128,44],[128,30]])c.beginPath(),c.roundRect(x-w/2,w>40?132:142,w,6,3),c.fill()
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// gold trophy with a star on it, a glint sweeping across the cup and sparkles popping around
|
||||||
|
const{sin,cos,PI,max}=Math,T=2*PI
|
||||||
|
export const frames=20,delay=80
|
||||||
|
const G='#ffd43b',GD='#fab005',WD='#a9744f',PL='#ffe8cc'
|
||||||
|
const cup=c=>{c.beginPath();c.moveTo(70,44);c.lineTo(186,44);c.bezierCurveTo(186,110,160,140,128,142);c.bezierCurveTo(96,140,70,110,70,44);c.closePath()}
|
||||||
|
export default(c,t)=>{
|
||||||
|
const y=-3*sin(t*T)
|
||||||
|
for(const[x,yy,o]of[[38,60,0],[220,74,.33],[214,172,.66],[44,168,.5]]){const s=11*max(0,sin(PI*((t*2+o)%1)));if(s>1.5){c.lineWidth=4;c.fillStyle='#fff';c.beginPath();c.moveTo(x,yy-s);for(const[px,py,qx,qy]of[[s,0,s*.18,-s*.18],[0,s,s*.18,s*.18],[-s,0,-s*.18,s*.18],[0,-s,-s*.18,-s*.18]])c.quadraticCurveTo(x+qx,yy+qy,x+px,yy+py);c.fill();c.stroke()}}
|
||||||
|
c.lineWidth=7;c.translate(0,y)
|
||||||
|
for(const d of[-1,1])for(const[w,st]of[[24,'#111'],[12,G]])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.arc(128+d*58,74,24,d<0?PI*.45:-PI*.55,d<0?PI*1.55:PI*.55),c.stroke()
|
||||||
|
c.strokeStyle='#111';c.lineWidth=7
|
||||||
|
c.fillStyle=GD;c.beginPath();c.moveTo(114,140);c.lineTo(142,140);c.lineTo(148,184);c.lineTo(108,184);c.closePath();c.fill();c.stroke()
|
||||||
|
cup(c);c.fillStyle=G;c.fill()
|
||||||
|
c.save();cup(c);c.clip();c.fillStyle=GD;c.fillRect(150,40,40,110)
|
||||||
|
const g=((t*1.5)%1)*200-40;c.strokeStyle='#fff';c.lineWidth=12;c.beginPath();c.moveTo(40+g,160);c.lineTo(100+g,30);c.stroke();c.lineWidth=5;c.beginPath();c.moveTo(62+g,160);c.lineTo(122+g,30);c.stroke();c.restore()
|
||||||
|
cup(c);c.stroke()
|
||||||
|
c.fillStyle='#fff';c.beginPath();for(let k=0;k<10;k++){const r=k%2?9:20,a=k*PI/5-PI/2;c.lineTo(128+cos(a)*r,88+sin(a)*r)}c.closePath();c.fill();c.lineWidth=5;c.stroke();c.lineWidth=7
|
||||||
|
c.fillStyle=WD;c.beginPath();c.roundRect(80,182,96,46,8);c.fill();c.stroke()
|
||||||
|
c.fillStyle=PL;c.beginPath();c.roundRect(100,194,56,20,4);c.fill();c.lineWidth=4;c.stroke()
|
||||||
|
c.lineWidth=3;c.beginPath();c.moveTo(110,204);c.lineTo(146,204);c.stroke()
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 178 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 125 KiB |