Fill the anime section to 50 with tropes, hobbies, seasons and fantasy

45 new animations, each its own girl doing something different: running late
with toast, soul leaving, glasses glint, waterfall tears, table flip, love
letter, ojou laugh, ramen, idol, gamer, kotatsu, onsen, sparkler, goldfish
scooping, fishing a star off the moon, kitsune, mermaid, vampire, ninja,
astronaut, skating, walking a shiba and more.

npm run gen with ids now renders only those ids, so parallel renders of
different ids don't touch each other's files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-22 21:52:29 +00:00
co-authored by Claude Opus 5.5
parent 7cebe4a05e
commit 454602f0cd
136 changed files with 2394 additions and 2 deletions
+47
View File
@@ -0,0 +1,47 @@
// full-body chibi with ginger hair whose single ahoge strand boings and wobbles wildly, then curls into a heart and springs loose
const{sin,PI,exp}=Math,T=2*PI
export const frames=24,delay=70
const SKIN='#ffe3d1',HAIR='#8c5a3c',HD='#6b4226',HL='#d9b38c',EYE='#15aabf',ED='#0b7285',DRESS='#8ce99a',DD='#40c057',SHOE='#e03131',BL='#ffa8a8',MO='#c92a2a',CLIP='#fff',SP='#ffd43b'
const ease=x=>x<=0?0:x>=1?1:x*x*(3-2*x)
const S0=[[0,0],[-2,-8],[-6,-14],[-4,-22],[-2,-34],[-12,-44],[-2,-56],[8,-66],[28,-64],[24,-50]],W=[0,1,2,4,6,9,13,16,20,22]
const H=[[0,0],[0,-6],[0,-12],[0,-18],[-31,-40],[-22,-66],[0,-49],[22,-66],[31,-40],[2,-20]]
const eye=(c,x,y,d,u)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3-u,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5-u,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8-u,2,0,T);c.fill();c.restore()
c.lineWidth=3.5;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.lineWidth=8;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const spark=(c,x,y,r)=>{c.beginPath();c.moveTo(x,y-r);for(const[px,py,qx,qy]of[[r,0,r*.18,-r*.18],[0,r,r*.18,r*.18],[-r,0,-r*.18,r*.18],[0,-r,-r*.18,-r*.18]])c.quadraticCurveTo(x+qx,y+qy,x+px,y+py);c.fill();c.stroke()}
export default(c,t)=>{
const m=ease((t-.5)/.12)-ease((t-.84)/.1),A=t<.5?exp(-5*t):t>=.84?(t-.84)/.16:0,b=A*sin(T*5*t),hap=m>.5,Z=.66
const P=S0.map(([x,y],k)=>[128+(x+W[k]*b)*(1-m)+H[k][0]*m,78+y*(1-m)+H[k][1]*m])
for(const[l,s]of[[12,'#111'],[6,HAIR]]){c.lineWidth=l;c.strokeStyle=s;c.beginPath();c.moveTo(...P[0]);for(let k=1;k<10;k+=3)c.bezierCurveTo(...P[k],...P[k+1],...P[k+2]);c.stroke()}
c.strokeStyle='#111';c.lineWidth=5
for(const d of[-1,1])for(const[l,s]of[[15,'#111'],[8,SKIN]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(128+d*12,214),c.lineTo(128+d*12,236),c.stroke(),c.beginPath(),c.moveTo(128+d*24,180),c.lineTo(128+d*36,206),c.stroke()
c.strokeStyle='#111';c.lineWidth=5;c.fillStyle=SHOE;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*14,240,11,6.5,0,0,T),c.fill(),c.stroke()
c.fillStyle=SKIN;for(const d of[-1,1])c.beginPath(),c.arc(128+d*37,208,6,0,T),c.fill(),c.stroke()
c.fillStyle=DRESS;c.beginPath();c.moveTo(112,166);c.quadraticCurveTo(100,168,98,182);c.lineTo(88,218);c.quadraticCurveTo(128,228,168,218);c.lineTo(158,182);c.quadraticCurveTo(156,168,144,166);c.closePath();c.fill();c.stroke()
for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*26,178,9,8,d*.5,0,T),c.fill(),c.stroke()
c.strokeStyle=DD;c.lineWidth=3;c.beginPath();c.moveTo(92,212);c.quadraticCurveTo(128,220,164,212);c.stroke();c.strokeStyle='#111'
c.fillStyle='#fff';c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.moveTo(128,170),c.quadraticCurveTo(128+d*14,166,128+d*16,176),c.quadraticCurveTo(128+d*8,184,128,176),c.fill(),c.stroke()
c.save();c.translate(128,72);c.scale(Z,Z);c.translate(-128,-40)
c.lineWidth=8;c.fillStyle=HD;c.beginPath();c.moveTo(128,36);c.bezierCurveTo(196,36,206,96,198,146);c.quadraticCurveTo(208,160,194,160);c.lineTo(62,160);c.quadraticCurveTo(48,160,58,146);c.bezierCurveTo(50,96,60,36,128,36);c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
if(hap){c.lineWidth=7;for(const x of[103,153])c.beginPath(),c.arc(x,146,13,PI*1.15,PI*1.85),c.stroke()}
else{const u=4*A;eye(c,103,140,-1,u);eye(c,153,140,1,u)}
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,162,14,7,0,0,T),c.fill()
c.lineWidth=3.5;c.fillStyle=MO;c.beginPath()
if(hap)c.moveTo(116,164),c.quadraticCurveTo(128,184,140,164),c.closePath(),c.fill(),c.stroke()
else c.ellipse(128,170,6,7,0,0,T),c.fill(),c.stroke()
c.lineWidth=8;c.fillStyle=HAIR;c.beginPath();c.moveTo(66,148)
c.bezierCurveTo(50,74,88,38,128,38);c.bezierCurveTo(168,38,206,74,190,148)
c.quadraticCurveTo(186,120,180,108);c.quadraticCurveTo(170,100,164,112);c.quadraticCurveTo(160,96,148,90);c.quadraticCurveTo(142,106,132,110)
c.quadraticCurveTo(128,96,118,88);c.quadraticCurveTo(112,104,100,108);c.quadraticCurveTo(96,96,88,94);c.quadraticCurveTo(84,106,78,110)
c.quadraticCurveTo(70,124,66,148);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=6;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,58,PI*a,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle=CLIP;c.lineWidth=6;c.beginPath();c.roundRect(150,72,26,10,4);c.fill();c.stroke()
c.restore()
if(m>.6){c.fillStyle=SP;c.lineWidth=3.5;for(const[x,y,o]of[[84,26,0],[176,34,.5],[90,60,.25]]){const s=sin(PI*(((t-.56)/.3*2+o)%1));if(s>.1)spark(c,x,y,11*s)}}
}
+57
View File
@@ -0,0 +1,57 @@
// little angel with long platinum hair and a side braid floating with her hands clasped, wings flapping, halo bobbing, a feather drifting down
const{sin,cos,PI,round}=Math,T=2*PI
export const frames=16,delay=70
const SKIN='#ffe3d1',HAIR='#f8f9fa',HD='#dee2e6',HS='#adb5bd',EYE='#3bc9db',ED='#0b7285',DR='#d0ebff',DD='#74c0fc',GOLD='#ffd43b',GD='#f59f00',BL='#ffa8a8',WL='#ced4da'
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2,0,T);c.fill()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const wing=(c,x,y,d,a)=>{
c.save();c.translate(x,y);c.scale(d,1);c.rotate(-a)
const p=()=>{c.beginPath();c.moveTo(0,4);c.bezierCurveTo(24,-40,70,-62,104,-56);c.quadraticCurveTo(100,-34,84,-30);c.quadraticCurveTo(92,-12,70,-8);c.quadraticCurveTo(76,8,52,10);c.quadraticCurveTo(54,26,30,24);c.quadraticCurveTo(14,24,0,14);c.closePath()}
c.lineWidth=5;c.fillStyle='#fff';p();c.fill()
c.strokeStyle=WL;c.lineWidth=3;c.beginPath();for(const[ex,ey]of[[84,-30],[70,-8],[52,10]])c.moveTo(ex,ey),c.quadraticCurveTo(ex*.6,ey*.6-8,ex*.3,ey*.3-6);c.moveTo(20,-12);c.quadraticCurveTo(50,-38,90,-48);c.stroke()
c.strokeStyle='#111';c.lineWidth=5;p();c.stroke();c.restore()
}
export default(c,t,i)=>{
const by=round(2*sin(T*t)),a=.38*sin(2*T*t),hy=24+by+round(3*sin(2*T*t+1))
const fp=t,fx=40+14*sin(fp*T*2),fy=150+120*fp
c.save();c.translate(fx,fy);c.rotate(.6*sin(fp*T*2)+.4)
c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.moveTo(0,-14);c.bezierCurveTo(9,-8,8,8,0,14);c.bezierCurveTo(-8,8,-9,-8,0,-14);c.fill();c.stroke()
c.lineWidth=2.5;c.beginPath();c.moveTo(0,-9);c.lineTo(0,18);c.stroke();c.restore()
c.translate(0,by)
for(const d of[-1,1])wing(c,128+d*12,146,d,a)
c.save();c.translate(128,92);c.scale(.6,.6);c.translate(-128,-128)
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(200,34,214,96,206,150);c.bezierCurveTo(216,210,204,250,212,290);c.quadraticCurveTo(170,302,128,290);c.quadraticCurveTo(86,302,44,290);c.bezierCurveTo(52,250,40,210,50,150);c.bezierCurveTo(42,96,56,34,128,34);c.fill();c.stroke()
c.restore()
for(const[x,s]of[[118,-1],[138,1]]){for(const[w,col]of[[13,'#111'],[7,SKIN]])c.lineWidth=w,c.strokeStyle=col,c.beginPath(),c.moveTo(x,196),c.lineTo(x+s*2,222),c.stroke()
c.strokeStyle='#111';c.lineWidth=4;c.fillStyle=SKIN;c.beginPath();c.ellipse(x+s*3,226,5,8,s*.3,0,T);c.fill();c.stroke()}
c.lineWidth=5;c.fillStyle=DR;c.beginPath();c.moveTo(112,138);c.lineTo(144,138);c.bezierCurveTo(154,156,160,176,174,198);for(let k=0;k<4;k++)c.quadraticCurveTo(163-k*23,208,152-k*23,200);c.bezierCurveTo(96,176,102,156,112,138);c.closePath();c.fill();c.stroke()
c.strokeStyle=DD;c.lineWidth=3;c.beginPath();c.moveTo(120,170);c.lineTo(114,196);c.moveTo(136,170);c.lineTo(142,196);c.stroke()
c.strokeStyle='#111';c.fillStyle=GOLD;c.lineWidth=4;c.beginPath();c.moveTo(108,160);c.quadraticCurveTo(128,166,148,160);c.lineTo(150,170);c.quadraticCurveTo(128,176,106,170);c.closePath();c.fill();c.stroke()
c.fillStyle=SKIN;c.lineWidth=4;c.beginPath();c.rect(123,128,10,12);c.fill();c.beginPath();c.moveTo(123,128);c.lineTo(123,138);c.moveTo(133,128);c.lineTo(133,138);c.stroke()
for(const d of[-1,1])for(const[w,col]of[[14,'#111'],[8,DR]])c.lineWidth=w,c.strokeStyle=col,c.beginPath(),c.moveTo(128+d*15,142),c.quadraticCurveTo(128+d*18,156,128+d*6,156),c.stroke()
c.strokeStyle='#111';c.lineWidth=4;c.fillStyle=SKIN;c.beginPath();c.ellipse(128,152,8,10,0,0,T);c.fill();c.stroke();c.lineWidth=2;c.beginPath();c.moveTo(128,144);c.lineTo(128,158);c.stroke()
c.save();c.translate(128,92);c.scale(.6,.6);c.translate(-128,-128)
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
if(i==12||i==13){c.lineWidth=6;for(const x of[103,153])c.beginPath(),c.moveTo(x-15,142),c.quadraticCurveTo(x,150,x+15,142),c.stroke()}else eye(c,103,140,-1),eye(c,153,140,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,161,12,6,0,0,T),c.fill()
c.lineWidth=4;c.beginPath();c.arc(128,164,8,.15*PI,.85*PI);c.stroke()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(66,190)
c.bezierCurveTo(48,74,88,36,128,36);c.bezierCurveTo(168,36,208,74,190,190)
c.quadraticCurveTo(184,140,180,104);c.quadraticCurveTo(172,100,166,110);c.quadraticCurveTo(158,96,148,92);c.quadraticCurveTo(142,104,134,110)
c.quadraticCurveTo(128,96,120,92);c.quadraticCurveTo(116,104,108,110);c.quadraticCurveTo(100,96,92,94);c.quadraticCurveTo(86,104,84,110)
c.quadraticCurveTo(80,102,76,104);c.quadraticCurveTo(72,140,66,190);c.closePath();c.fill();c.stroke()
c.strokeStyle=HS;c.lineWidth=4;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle=HAIR;c.lineWidth=6
for(let k=0;k<5;k++){const y=192+k*20;c.beginPath();c.ellipse(186-k,y,15-k*1.4,13,0,0,T);c.fill();c.stroke()}
c.fillStyle=DD;c.lineWidth=5;c.beginPath();c.ellipse(180,290,10,6,0,0,T);c.fill();c.stroke()
c.restore()
c.translate(0,-by)
for(const[w,col]of[[13,'#111'],[6,GOLD]])c.lineWidth=w,c.strokeStyle=col,c.beginPath(),c.ellipse(128,hy,30,8,0,0,T),c.stroke()
c.strokeStyle='#111'
}
+46
View File
@@ -0,0 +1,46 @@
// red side-ponytail girl fuming with puffed cheeks, the anger mark pulsing on her head, steam puffing out, fists shaking
const{sin,cos,PI,max,abs}=Math,T=2*PI
export const frames=12,delay=70
const SKIN='#ffe3d1',HAIR='#ff6b6b',HD='#e03131',HL='#ffc9c9',EYE='#fab005',ED='#e67700',JK='#20c997',JD='#0ca678',BL='#ff8787',VN='#f03e3e'
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x+d*2,y+6,3.5,5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-3,y+3,2.5,0,T);c.fill()
c.fillStyle=SKIN;c.beginPath();c.moveTo(x-d*20,y-26);c.lineTo(x-d*20,y-14);c.lineTo(x+d*20,y+2);c.lineTo(x+d*20,y-26);c.fill()
c.lineWidth=6;c.beginPath();c.moveTo(x-d*17,y-13);c.lineTo(x+d*17,y+1);c.stroke()
c.lineWidth=2.5;c.beginPath();c.moveTo(x-8,y+18);c.lineTo(x+8,y+18);c.stroke()
}
const puff=(c,x,y,r)=>{c.beginPath();for(const[a,b,s]of[[-.8,0,.7],[0,-.5,.8],[.8,0,.7],[0,.3,.75]])c.moveTo(x+a*r+s*r,y+b*r),c.arc(x+a*r,y+b*r,s*r,0,T);c.lineWidth=8;c.stroke();c.fillStyle='#fff';c.fill()}
const fist=(c,x,y,d)=>{c.fillStyle=SKIN;c.lineWidth=5;c.beginPath();c.roundRect(x-17,y-15,34,30,12);c.fill();c.stroke();c.lineWidth=2.5;c.beginPath();for(const k of[-6,1,8])c.moveTo(x+k*d,y-13),c.lineTo(x+k*d,y-5);c.stroke();c.beginPath();c.ellipse(x-d*13,y+3,6,9,d*.3,0,T);c.lineWidth=4;c.fill();c.stroke()}
export default(c,t)=>{
const pu=1+.25*abs(sin(2*T*t)),sh=3*sin(3*T*t)
c.save();c.translate(178,62);c.rotate(-.15)
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(-6,0);c.bezierCurveTo(40,-6,58,50,48,110);c.quadraticCurveTo(44,128,30,134);c.quadraticCurveTo(38,96,22,56);c.quadraticCurveTo(12,28,-6,14);c.closePath();c.fill();c.stroke()
c.strokeStyle=HD;c.lineWidth=3;c.beginPath();c.moveTo(14,12);c.bezierCurveTo(32,30,40,70,40,108);c.stroke();c.strokeStyle='#111'
c.restore()
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(196,34,206,96,198,160);c.lineTo(58,160);c.bezierCurveTo(50,96,60,34,128,34);c.fill();c.stroke()
c.fillStyle=JK;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(62,198,54,256);c.lineTo(202,256);c.quadraticCurveTo(194,198,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(104,188);c.lineTo(128,206);c.lineTo(152,188);c.lineTo(160,196);c.lineTo(128,226);c.lineTo(96,196);c.closePath();c.fill();c.lineWidth=5;c.stroke()
c.strokeStyle=JD;c.lineWidth=4;c.beginPath();c.moveTo(128,226);c.lineTo(128,256);c.stroke();c.strokeStyle='#111'
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,166);c.lineTo(116,190);c.lineTo(128,204);c.lineTo(140,190);c.lineTo(140,166);c.fill();c.beginPath();c.moveTo(116,166);c.lineTo(116,188);c.moveTo(140,166);c.lineTo(140,188);c.stroke()
for(const d of[-1,1]){const p=(t*2+(d>0?.5:0))%1;puff(c,128+d*(70+40*p),132-34*p,13*sin(PI*p))}
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
for(const d of[-1,1])c.beginPath(),c.arc(128+d*44,160,15,d<0?PI*.5:-PI*.5,d<0?PI*1.5:PI*.5),c.fill(),c.stroke()
eye(c,103,140,-1);eye(c,153,140,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,162,12,6,0,0,T),c.fill()
c.lineWidth=2.5;for(const d of[-1,1])for(const k of[-5,0,5])c.beginPath(),c.moveTo(128+d*42+k-2,165),c.lineTo(128+d*42+k+2,159),c.stroke()
c.lineWidth=4;c.beginPath();c.moveTo(119,172);c.quadraticCurveTo(128,163,137,172);c.stroke()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,150)
c.bezierCurveTo(54,74,88,36,128,36);c.bezierCurveTo(168,36,202,74,186,150)
c.quadraticCurveTo(186,118,178,104);c.lineTo(170,112);c.lineTo(160,96);c.lineTo(150,110);c.lineTo(138,92);c.lineTo(126,108)
c.lineTo(114,92);c.lineTo(104,108);c.lineTo(94,96);c.lineTo(84,112);c.lineTo(78,104);c.quadraticCurveTo(70,124,70,150);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,b]of[[1.22,1.34],[1.42,1.5],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*b),c.stroke()
c.strokeStyle='#111';c.lineWidth=7;c.beginPath();c.moveTo(84,104);c.lineTo(118,124);c.moveTo(172,104);c.lineTo(138,124);c.stroke()
c.fillStyle=HD;c.lineWidth=5;c.beginPath();c.ellipse(172,58,8,12,.5,0,T);c.fill();c.stroke()
c.save();c.translate(84,66);c.scale(1.3*pu,1.3*pu)
for(const[w,s]of[[11,'#111'],[5,VN]]){c.lineWidth=w;c.strokeStyle=s;c.beginPath();for(let k=0;k<4;k++){const a=k*PI/2+PI/4,ca=cos(a),sa=sin(a),q=(x,y)=>[x*ca-y*sa,x*sa+y*ca];const[a1,b1]=q(5,-11),[a2,b2]=q(5,-4),[a3,b3]=q(11,-4);c.moveTo(a1,b1);c.quadraticCurveTo(a2,b2,a3,b3)}c.stroke()}
c.restore();c.strokeStyle='#111'
for(const d of[-1,1]){const y=206+d*sh;for(const[w,s]of[[30,'#111'],[19,JK]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(128+d*76,262),c.lineTo(128+d*50,y+8),c.stroke();c.strokeStyle='#111';fist(c,128+d*44,y,-d)}
}
+62
View File
@@ -0,0 +1,62 @@
// plum haired artist in a red beret doodling a cat in her sketchbook line by line, tongue out, then flipping to a fresh page
const{sin,cos,PI,hypot,min}=Math,T=2*PI
export const frames=20,delay=80
const SKIN='#ffe3d1',HAIR='#be4bdb',HD='#862e9c',HL='#f3d9fa',EYE='#40c057',ED='#2b8a3e',BL='#ffa8a8',BER='#fa5252',SMK='#a5d8ff',KRA='#d9a066',PEN='#495057'
const ds=(c,a,b,s,f)=>{for(const[l,k]of[[a,'#111'],[b,s]])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),f(),c.stroke();c.strokeStyle='#111'}
const R=-.06,W=(x,y)=>[180+x*cos(R)-y*sin(R),164+x*sin(R)+y*cos(R)]
const ST=[[...Array(41)].map((_,k)=>[32*cos(PI+k/40*T),10+30*sin(PI+k/40*T)]),[[-27,-6],[-24,-36],[-9,-18]],[[9,-18],[24,-36],[27,-6]],[[-17,8],[-12,3],[-7,8]],[[7,8],[12,3],[17,8]],[[-8,20],[-4,24],[0,20],[4,24],[8,20]],[[-20,16],[-42,11]],[[-20,22],[-42,25]],[[20,16],[42,11]],[[20,22],[42,25]]]
const LEN=ST.map(s=>s.slice(1).reduce((a,p,k)=>a+hypot(p[0]-s[k][0],p[1]-s[k][1]),0)),TOT=LEN.reduce((a,b)=>a+b)
const doodle=(c,q)=>{ // draws the first q px of the doodle, returns where the pencil is
let tip=ST[0][0];c.strokeStyle=PEN;c.lineWidth=3.5
for(const[k,s]of ST.entries()){if(q<=0)break;c.beginPath();c.moveTo(...s[0]);tip=s[0]
for(let j=1;j<s.length&&q>0;j++){const[a,b]=[s[j-1],s[j]],l=hypot(b[0]-a[0],b[1]-a[1]),f=min(1,q/l);tip=[a[0]+(b[0]-a[0])*f,a[1]+(b[1]-a[1])*f];c.lineTo(...tip);q-=l}
c.stroke()}
c.strokeStyle='#111';return tip
}
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.clip();c.beginPath();c.ellipse(x+4,y+5,11.5,15,0,0,T);c.fillStyle=EYE;c.fill();c.lineWidth=2.5;c.stroke()
c.save();c.clip();c.fillStyle=ED;c.beginPath();c.ellipse(x+4,y-5,13,10,0,0,T);c.fill();c.restore()
c.fillStyle='#111';c.beginPath();c.ellipse(x+4,y+6,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x,y,4.5,0,T);c.fill();c.restore()
c.lineWidth=7;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
export default(c,t)=>{
const dr=t<.75,done=t>=.75&&t<.85,fp=t>=.85?(t-.85)/.15:-1,q=dr?t/.75*TOT:TOT
c.lineWidth=6;c.fillStyle=SMK;c.beginPath();c.moveTo(70,166);c.quadraticCurveTo(28,176,22,256);c.lineTo(160,256);c.quadraticCurveTo(152,176,114,166);c.closePath();c.fill();c.stroke()
c.fillStyle='#ffd43b';c.lineWidth=3;for(const[x,y,r]of[[48,226,6],[60,238,4],[132,214,5]])c.beginPath(),c.arc(x,y,r,0,T),c.fill(),c.stroke()
c.save();c.translate(92,152);c.scale(.72,.72);c.translate(-128,-186)
c.lineWidth=7;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(196,34,206,96,196,166);c.lineTo(60,166);c.bezierCurveTo(50,96,60,34,128,34);c.fill();c.stroke()
c.fillStyle=HAIR;for(let k=0;k<5;k++)c.beginPath(),c.ellipse(62-k,160+k*18,13-k,11,0,0,T),c.fill(),c.stroke()
c.fillStyle=BER;c.beginPath();c.ellipse(52,252,8,6,0,0,T);c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
if(dr){eye(c,103,140,-1);eye(c,153,140,1)}
else for(const d of[-1,1]){const x=128+d*25;c.lineWidth=7;c.beginPath();c.arc(x,148,13,PI*1.15,PI*1.85);c.stroke()}
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,162,13,7,0,0,T),c.fill()
c.lineWidth=2.5;for(const d of[-1,1])for(const k of[-5,0,5])c.beginPath(),c.moveTo(128+d*44+k-2,165),c.lineTo(128+d*44+k+2,159),c.stroke()
if(dr){c.lineWidth=4.5;c.beginPath();c.moveTo(116,168);c.quadraticCurveTo(126,172,138,166);c.stroke();c.fillStyle='#ff8fab';c.lineWidth=3.5;c.beginPath();c.ellipse(140,172,5,6,-.4,0,T);c.fill();c.stroke()}
else{c.lineWidth=4.5;c.fillStyle='#c92a2a';c.beginPath();c.moveTo(114,164);c.quadraticCurveTo(128,186,142,164);c.closePath();c.fill();c.stroke()}
c.lineWidth=7;c.fillStyle=HAIR;c.beginPath();c.moveTo(68,156)
c.bezierCurveTo(52,74,88,36,128,36);c.bezierCurveTo(168,36,204,74,188,156)
c.quadraticCurveTo(186,120,178,104);c.quadraticCurveTo(168,106,160,98);c.quadraticCurveTo(152,108,140,110);c.quadraticCurveTo(140,98,132,92)
c.quadraticCurveTo(124,106,110,110);c.quadraticCurveTo(108,98,100,94);c.quadraticCurveTo(92,106,80,108);c.quadraticCurveTo(70,126,68,156);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=6;for(const[s,e]of[[1.36,1.44],[1.52,1.6]])c.beginPath(),c.arc(128,104,56,PI*s,PI*e),c.stroke()
c.strokeStyle='#111';c.save();c.translate(112,46);c.rotate(.22);c.fillStyle=BER;c.lineWidth=7;c.beginPath();c.ellipse(0,0,74,26,0,0,T);c.fill();c.stroke()
c.strokeStyle='#c92a2a';c.lineWidth=4;c.beginPath();c.ellipse(-4,4,58,15,0,.2,PI-.2);c.stroke();c.strokeStyle='#111'
ds(c,13,6,BER,()=>{c.moveTo(4,-25);c.lineTo(6,-38)});c.restore()
c.restore()
c.save();c.translate(180,164);c.rotate(R)
c.fillStyle=KRA;c.lineWidth=6;c.beginPath();c.roundRect(-66,-62,132,128,6);c.fill();c.stroke()
c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.rect(-60,-56,120,116);c.fill();c.stroke()
let tip=[0,0]
if(fp<0){tip=doodle(c,q);if(done){c.fillStyle='#ffc9c9';for(const d of[-1,1])c.beginPath(),c.ellipse(d*20,16,5,3,0,0,T),c.fill();c.fillStyle='#ffd43b';c.lineWidth=3;c.beginPath();c.moveTo(40,-44);for(const[a,b]of[[1,0],[0,1],[-1,0],[0,-1]])c.quadraticCurveTo(40+(a+b)*1.6,-34+(b-a)*1.6,40+a*10,-34+b*10);c.fill();c.stroke()}}
else if(fp<.5){const h=116*(1-2*fp);c.save();c.translate(0,-56);c.scale(1,h/116);c.translate(0,56);c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.rect(-60,-56,120,116);c.fill();c.stroke();doodle(c,TOT);c.restore()}
else{const h=60*sin(PI*fp);c.fillStyle='#e9ecef';c.lineWidth=4;c.beginPath();c.rect(-60,-56-h,120,h);c.fill();c.stroke()}
c.fillStyle='#ced4da';c.lineWidth=3;for(let x=-52;x<=52;x+=13)c.beginPath(),c.ellipse(x,-58,3.5,7,0,0,T),c.fill(),c.stroke()
c.restore()
const[px,py]=fp<0&&dr?W(...tip):[150,214],hx=px+10,hy=py+24
ds(c,20,11,SMK,()=>{c.moveTo(118,200);c.quadraticCurveTo(130,236,hx,hy+4)})
ds(c,9,4.5,'#ffd43b',()=>{c.moveTo(px+2,py+5);c.lineTo(px+10,py+30)})
c.fillStyle='#ffe8cc';c.lineWidth=3;c.beginPath();c.moveTo(px,py);c.lineTo(px+5,py+4);c.lineTo(px-1,py+6);c.closePath();c.fill();c.stroke()
c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(hx,hy,9,9,0,0,T);c.fill();c.stroke()
}
+56
View File
@@ -0,0 +1,56 @@
// little astronaut with short crimson hair drifting in her bubble helmet, waving on a wavy tether while stars twinkle around her
const{sin,cos,PI}=Math,T=2*PI
export const frames=12,delay=110
const SKIN='#ffe3d1',HAIR='#e03131',HD='#c92a2a',HL='#ffc9c9',EYE='#51cf66',ED='#2b8a3e',SUIT='#fff',SS='#dee2e6',ACC='#ff922b',GL='#a5d8ff',BL='#ffa8a8',FR='#e8590c',PL='#b197fc',PD='#7950f2',ST='#ffd43b'
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2,0,T);c.fill()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const spark=(c,x,y,r)=>{c.beginPath();c.moveTo(x,y-r);c.quadraticCurveTo(x+r*.2,y-r*.2,x+r,y);c.quadraticCurveTo(x+r*.2,y+r*.2,x,y+r);c.quadraticCurveTo(x-r*.2,y+r*.2,x-r,y);c.quadraticCurveTo(x-r*.2,y-r*.2,x,y-r);c.fill();c.stroke()}
const limb=(c,pts,w)=>{for(const[lw,col]of[[w+8,'#111'],[w,SUIT]]){c.lineWidth=lw;c.strokeStyle=col;c.beginPath();pts.forEach(([x,y],k)=>k?c.lineTo(x,y):c.moveTo(x,y));c.stroke()}c.strokeStyle='#111'}
export default(c,t,i)=>{
const ring=(a,b)=>{for(const[w,col]of[[10,'#111'],[4,'#ffd8a8']])c.lineWidth=w,c.strokeStyle=col,c.beginPath(),c.ellipse(214,212,32,9,-.35,a,b),c.stroke();c.strokeStyle='#111'}
ring(PI,T)
c.fillStyle=PL;c.lineWidth=5;c.beginPath();c.arc(214,212,18,0,T);c.fill();c.stroke()
c.save();c.beginPath();c.arc(214,212,18,0,T);c.clip();c.fillStyle=PD;c.beginPath();c.ellipse(208,206,8,5,.4,0,T);c.ellipse(222,220,5,3,.4,0,T);c.fill();c.restore()
ring(-.05,PI+.05)
c.lineWidth=3.5;for(const[k,x,y,r,col]of[[0,36,40,10,ST],[1,212,46,12,'#fff'],[2,226,118,7,ST],[3,30,150,7,'#fff'],[4,170,22,6,ST],[5,96,236,8,'#fff'],[6,56,96,5,ST]]){const s=.55+.45*sin(T*t*(k%2+1)+k*1.3);c.fillStyle=col;spark(c,x,y,r*s+2)}
const ox=124+5*sin(T*t),oy=104+7*sin(T*t+1),a=.22+.08*sin(T*t),wv=sin(2*T*t)
const bx=ox+cos(a)*-20-sin(a)*86,by=oy+sin(a)*-20+cos(a)*86
for(const[w,col]of[[9,'#111'],[4,SS]])c.lineWidth=w,c.strokeStyle=col,c.beginPath(),c.moveTo(bx,by),c.bezierCurveTo(bx-30,by+30+10*wv,30,170-20*wv,-6,190+8*wv),c.stroke()
c.strokeStyle='#111'
c.save();c.translate(ox,oy);c.rotate(a)
c.fillStyle=SS;c.lineWidth=5;c.beginPath();c.roundRect(-34,44,68,50,10);c.fill();c.stroke()
limb(c,[[-14,92],[-22,120],[-12,136]],16);limb(c,[[14,92],[26,116],[22,138]],16)
c.fillStyle=ACC;c.lineWidth=5;for(const[x,y]of[[-12,138],[22,140]])c.beginPath(),c.ellipse(x,y,12,8,0,0,T),c.fill(),c.stroke()
limb(c,[[-24,58],[-44,74],[-50,96]],15)
const wa=.15+.35*sin(2*T*t);limb(c,[[24,56],[52,48],[52+26*sin(wa),48-26*cos(wa)]],15)
c.fillStyle=SS;c.lineWidth=4.5;for(const[x,y]of[[-50,98],[52+28*sin(wa),48-28*cos(wa)]])c.beginPath(),c.arc(x,y,9,0,T),c.fill(),c.stroke()
c.fillStyle=SUIT;c.lineWidth=5;c.beginPath();c.moveTo(-26,46);c.quadraticCurveTo(0,40,26,46);c.quadraticCurveTo(34,74,26,98);c.quadraticCurveTo(0,104,-26,98);c.quadraticCurveTo(-34,74,-26,46);c.closePath();c.fill();c.stroke()
c.fillStyle=SS;c.lineWidth=4;c.beginPath();c.roundRect(-13,62,26,18,4);c.fill();c.stroke()
for(const[x,col]of[[-6,'#ff6b6b'],[0,ST],[6,'#4dabf7']])c.fillStyle=col,c.beginPath(),c.arc(x,71,2.6,0,T),c.fill()
c.fillStyle=ACC;c.beginPath();c.rect(-28,86,56,7);c.fill();c.stroke()
c.fillStyle=SS;c.lineWidth=5;c.beginPath();c.ellipse(0,46,30,9,0,0,T);c.fill();c.stroke()
c.fillStyle='#e7f5ff';c.beginPath();c.arc(0,-6,50,0,T);c.fill()
c.save();c.scale(.52,.52);c.translate(-128,-128)
c.lineWidth=7;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(200,34,214,96,198,170);c.lineTo(58,170);c.bezierCurveTo(42,96,56,34,128,34);c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
if(i==9){c.lineWidth=6;for(const x of[103,153])c.beginPath(),c.moveTo(x-15,142),c.quadraticCurveTo(x,150,x+15,142),c.stroke()}else eye(c,103,140,-1),eye(c,153,140,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,162,12,6,0,0,T),c.fill()
c.fillStyle=FR;for(const d of[-1,1])for(const[x,y]of[[-6,156],[2,153],[6,159]])c.beginPath(),c.arc(128+d*(40+x),y,2,0,T),c.fill()
c.lineWidth=4;c.fillStyle='#c92a2a';c.beginPath();c.moveTo(114,166);c.quadraticCurveTo(128,186,142,166);c.closePath();c.fill();c.stroke()
c.save();c.clip();c.fillStyle='#ff8fab';c.beginPath();c.ellipse(128,180,8,5,0,0,T);c.fill();c.restore()
c.lineWidth=7;c.fillStyle=HAIR;c.beginPath();c.moveTo(68,150)
c.bezierCurveTo(50,70,88,34,128,34);c.bezierCurveTo(168,34,206,70,188,150)
c.lineTo(178,130);c.lineTo(180,106);c.lineTo(166,114);c.lineTo(162,94);c.lineTo(148,108);c.lineTo(140,88);c.lineTo(128,106);c.lineTo(116,88);c.lineTo(108,108);c.lineTo(94,94);c.lineTo(90,112);c.lineTo(76,106);c.lineTo(78,130);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=6;for(const[a,e]of[[1.24,1.36],[1.62,1.74]])c.beginPath(),c.arc(128,100,58,PI*a,PI*e),c.stroke()
c.restore()
c.save();c.globalAlpha=.18;c.fillStyle=GL;c.beginPath();c.arc(0,-6,50,0,T);c.fill();c.restore()
c.strokeStyle='#fff';c.lineWidth=6;c.beginPath();c.arc(0,-6,40,PI*1.1,PI*1.42);c.stroke();c.beginPath();c.arc(-30,-30,0,0,T);c.lineWidth=7;c.beginPath();c.arc(0,-6,40,PI*1.52,PI*1.58);c.stroke()
c.strokeStyle='#111';c.lineWidth=6;c.beginPath();c.arc(0,-6,50,0,T);c.stroke()
c.restore()
}
+56
View File
@@ -0,0 +1,56 @@
// red-haired girl bobbing on the waves in a striped inner tube, sunglasses on her head, licking a grape popsicle that drips
const{sin,cos,PI,max,min,round}=Math,T=2*PI
export const frames=12,delay=100
const SKIN='#ffe3d1',HAIR='#e599f7',HD='#be4bdb',HL='#f8f0fc',EYE='#339af0',ED='#1864ab',RG='#38d9a9',RGD='#0ca678',TUBE='#ffd43b',WA='#74c0fc',WL='#d0ebff',POP='#9775fa',PL='#d0bfff',BL='#ffa8a8',SG='#495057',Z=.78
const cl=x=>max(0,min(1,x))
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=3;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2.5,0,T);c.fill()
c.lineWidth=7.5;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const wave=(c,t,y0,a)=>{c.moveTo(14,y0);for(let x=14;x<242;x+=19)c.quadraticCurveTo(x+9.5,y0+a*sin(x*.165-t*T)-6,x+19,y0)}
const ring=(c,lo)=>{c.beginPath();if(lo){c.ellipse(128,186,86,30,0,0,PI);c.ellipse(128,181,46,12,0,PI,0,true)}else{c.ellipse(128,186,86,30,0,0,T);c.ellipse(128,181,46,12,0,0,T,true)}c.closePath()}
export default(c,t)=>{
const dy=round(3*sin(t*T)),lk=cl((t-.45)/.15)-cl((t-.75)/.15),lick=t>=.6&&t<.75
c.lineWidth=6;c.fillStyle=WA;c.beginPath();wave(c,t,172,4);c.quadraticCurveTo(254,200,242,228);c.quadraticCurveTo(128,252,14,228);c.quadraticCurveTo(2,200,14,172);c.fill();c.stroke()
c.save();c.translate(0,dy)
const tube=lo=>{ring(c,lo);c.fillStyle=TUBE;c.fill();c.save();c.clip();c.fillStyle='#fff';for(let k=0;k<8;k+=2){c.beginPath();c.moveTo(128,186);c.arc(128,186,96,k*PI/4+.2,(k+1)*PI/4+.2);c.fill()}c.restore();ring(c,lo);c.lineWidth=6;c.stroke()}
tube(0);c.fillStyle=WA;c.beginPath();c.ellipse(128,181,46,12,0,0,T);c.fill();c.stroke()
c.fillStyle=RG;c.beginPath();c.moveTo(102,152);c.quadraticCurveTo(80,158,78,196);c.lineTo(178,196);c.quadraticCurveTo(176,158,154,152);c.closePath();c.fill();c.stroke()
c.strokeStyle=RGD;c.lineWidth=4;c.beginPath();c.moveTo(86,172);c.lineTo(170,172);c.stroke();c.strokeStyle='#111'
c.save();c.translate(128,150);c.scale(Z,Z);c.translate(-128,-186)
c.lineWidth=7.5;c.fillStyle=HD;c.beginPath();c.moveTo(128,48);c.bezierCurveTo(60,48,58,110,70,160);c.lineTo(186,160);c.bezierCurveTo(198,110,196,48,128,48);c.fill();c.stroke()
const sw=.1*sin(t*T-1)
c.save();c.translate(184,70);c.rotate(sw);c.fillStyle=HAIR;c.beginPath();c.moveTo(-6,-10);c.bezierCurveTo(40,-16,50,50,34,96);c.quadraticCurveTo(26,112,16,104);c.quadraticCurveTo(30,50,-4,14);c.closePath();c.fill();c.stroke()
c.strokeStyle=HD;c.lineWidth=4;c.beginPath();c.moveTo(8,0);c.bezierCurveTo(30,10,36,50,28,88);c.stroke();c.strokeStyle='#111';c.restore()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
if(lick){c.lineWidth=7.5;for(const x of[103,153])c.beginPath(),c.arc(x,146,13,PI*1.15,PI*1.85),c.stroke()}else eye(c,103,140,-1),eye(c,153,140,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,161,14,7,0,0,T),c.fill()
c.lineWidth=4.5;if(lick){c.fillStyle='#c92a2a';c.beginPath();c.moveTo(118,164);c.quadraticCurveTo(128,180,138,164);c.closePath();c.fill();c.stroke();c.fillStyle='#ff8fab';c.beginPath();c.ellipse(132,174,7,8,.3,0,T);c.fill();c.stroke()}
else{c.beginPath();c.arc(128,164,8,.2*PI,.8*PI);c.stroke()}
c.lineWidth=7.5;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,144)
c.bezierCurveTo(54,74,88,40,128,40);c.bezierCurveTo(168,40,202,74,186,144)
c.quadraticCurveTo(182,114,170,100);c.quadraticCurveTo(162,108,156,116);c.quadraticCurveTo(148,98,132,92);c.quadraticCurveTo(126,104,120,112)
c.quadraticCurveTo(114,98,102,96);c.quadraticCurveTo(96,108,94,116);c.quadraticCurveTo(88,104,82,102);c.quadraticCurveTo(72,118,70,144);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.3,1.42],[1.5,1.58],[1.66,1.74]])c.beginPath(),c.arc(128,104,54,PI*a,PI*e),c.stroke();c.strokeStyle='#111'
c.lineWidth=6;c.beginPath();c.moveTo(80,74);c.quadraticCurveTo(128,52,176,74);c.stroke()
c.fillStyle=SG;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*24,64,20,15,d*.12,0,T),c.fill(),c.stroke()
c.strokeStyle='#fff';c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.arc(128+d*24,64,10,PI*1.1,PI*1.5),c.stroke();c.strokeStyle='#111'
c.restore()
tube(1)
const hx=180-36*lk,hy=170-24*lk,px=hx+2,py=hy-24
for(const[a,b]of[[[96,160],[62,178]],[[160,160],[hx,hy]]])for(const[l,s]of[[24,'#111'],[13,RG]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(...a),c.lineTo(...b),c.stroke()
c.strokeStyle='#111'
c.save();c.translate(px,py);c.rotate(-.25*lk)
for(const[l,s]of[[11,'#111'],[5,'#e8c39e']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(0,4),c.lineTo(0,30),c.stroke()
c.strokeStyle='#111';c.lineWidth=5;c.fillStyle=POP;c.beginPath();c.moveTo(-11,6);c.lineTo(-11,-22);c.quadraticCurveTo(-11,-32,-2,-32);c.arc(4,-30,6,PI,0,true);c.lineTo(11,-24);c.lineTo(11,6);c.closePath();c.fill();c.stroke()
c.strokeStyle=PL;c.lineWidth=4;c.beginPath();c.moveTo(-5,-18);c.lineTo(-5,0);c.stroke();c.strokeStyle='#111';c.restore()
for(const[x,y]of[[62,178],[hx,hy]])c.lineWidth=5,c.fillStyle=SKIN,c.beginPath(),c.ellipse(x,y,10,9,0,0,T),c.fill(),c.stroke()
c.restore()
const dp=cl((t-.05)/.35);if(dp>0&&dp<1){const y=170+dy+dp*40;c.fillStyle=POP;c.lineWidth=3;c.beginPath();c.moveTo(192,y-6);c.quadraticCurveTo(197,y+2,192,y+4);c.quadraticCurveTo(187,y+2,192,y-6);c.fill();c.stroke()}
c.fillStyle=WA;c.lineWidth=6;c.beginPath();wave(c,t+.5,214,3);c.quadraticCurveTo(250,220,242,228);c.quadraticCurveTo(128,252,14,228);c.quadraticCurveTo(6,220,14,214);c.fill();c.stroke()
c.strokeStyle=WL;c.lineWidth=4;for(const[x,y]of[[50,228],[150,234],[204,226]])c.beginPath(),c.moveTo(x-12+6*sin(t*T),y),c.quadraticCurveTo(x+6*sin(t*T),y-5,x+12+6*sin(t*T),y),c.stroke();c.strokeStyle='#111'
}
+45
View File
@@ -0,0 +1,45 @@
// close-up of a girl with plum space buns blowing a bubblegum bubble that swells, pops all over her face, and gets slurped back in
const{sin,cos,PI,max,min}=Math,T=2*PI
export const frames=20,delay=80
const SKIN='#ffe3d1',HAIR='#cc5de8',HD='#9c36b5',HL='#f3d9fa',EYE='#fab005',ED='#e67700',JK='#3bc9db',GUM='#ff8cc6',GD='#f06595',BL='#ffa8a8'
const eye=(c,x,y,d,px,py)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.clip();c.beginPath();c.ellipse(x+px,y+2+py,11.5,15,0,0,T);c.fillStyle=EYE;c.fill();c.lineWidth=2.5;c.stroke()
c.fillStyle=ED;c.beginPath();c.ellipse(x+px,y-6+py,12,8,0,0,T);c.fill()
c.fillStyle='#111';c.beginPath();c.ellipse(x+px,y+3+py,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x+px-4,y-5+py,4.5,0,T);c.fill();c.beginPath();c.arc(x+px+5,y+8+py,2,0,T);c.fill();c.restore()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const blobs=(c,cs,lw)=>{c.lineWidth=lw;for(const[x,y,r]of cs)c.beginPath(),c.arc(x,y,r,0,T),c.stroke();c.fillStyle=GUM;for(const[x,y,r]of cs)c.beginPath(),c.arc(x,y,r,0,T),c.fill()}
export default(c,t)=>{
const bw=t<.6,p=t/.6,pop=t>=.6&&t<.65,stuck=t>=.65,g=stuck?min(1,max(0,(1-t)/.14)):0,sh=t>=.65&&t<.88
c.save();c.translate(128,140);c.scale(1.15,1.15);c.translate(-128,-140)
c.lineWidth=6;c.fillStyle=HAIR;for(const d of[-1,1])c.beginPath(),c.arc(128+d*50,50,22,0,T),c.fill(),c.stroke()
c.strokeStyle=HD;c.lineWidth=3;for(const d of[-1,1])c.beginPath(),c.arc(128+d*50,50,12,d<0?PI*.2:PI*.8,d<0?PI*1.6:PI*2.2,d>0),c.stroke();c.strokeStyle='#111'
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,36);c.bezierCurveTo(196,36,206,96,200,150);c.lineTo(56,150);c.bezierCurveTo(50,96,60,36,128,36);c.fill();c.stroke()
c.fillStyle=JK;c.beginPath();c.moveTo(98,190);c.quadraticCurveTo(62,198,54,256);c.lineTo(202,256);c.quadraticCurveTo(194,198,158,190);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(108,190);c.lineTo(128,212);c.lineTo(148,190);c.closePath();c.fill();c.lineWidth=5;c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,168);c.lineTo(116,194);c.lineTo(128,206);c.lineTo(140,194);c.lineTo(140,168);c.fill();c.beginPath();c.moveTo(116,168);c.lineTo(116,192);c.moveTo(140,168);c.lineTo(140,192);c.stroke()
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
if(sh||pop){c.lineWidth=5.5;c.beginPath();c.moveTo(91,131);c.lineTo(113,140);c.lineTo(91,149);c.moveTo(165,131);c.lineTo(143,140);c.lineTo(165,149);c.stroke()}
else{const q=bw?p:0;eye(c,103,140,-1,4*q,4*q);eye(c,153,140,1,-4*q,4*q)}
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,160,12,6,0,0,T),c.fill()
c.lineWidth=2.5;c.beginPath();c.moveTo(128,154);c.lineTo(127,158);c.stroke()
c.lineWidth=3.5;c.fillStyle=GUM;c.beginPath();c.ellipse(128,170,5,4,0,0,T);c.fill();c.stroke()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(68,150)
c.bezierCurveTo(52,76,88,38,128,38);c.bezierCurveTo(168,38,204,76,188,150)
c.quadraticCurveTo(184,118,176,104);c.quadraticCurveTo(172,96,166,108);c.quadraticCurveTo(160,94,150,90);c.quadraticCurveTo(144,104,136,108)
c.quadraticCurveTo(132,94,122,86);c.quadraticCurveTo(116,102,106,108);c.quadraticCurveTo(102,94,92,92);c.quadraticCurveTo(86,104,82,112)
c.quadraticCurveTo(72,126,68,150);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke()
c.strokeStyle='#111'
if(bw){const r=6+46*p**1.4+(p>.5?1.5*sin(T*t*5):0),y=170+r*.4;c.lineWidth=6;c.fillStyle=GUM;c.beginPath();c.arc(128,y,r,0,T);c.fill();c.stroke()
if(r>14){c.strokeStyle='#fff';c.lineWidth=max(3,r*.12);c.beginPath();c.arc(128,y,r*.68,PI*1.12,PI*1.42);c.stroke();c.fillStyle='#fff';c.beginPath();c.arc(128+cos(PI*1.55)*r*.68,y+sin(PI*1.55)*r*.68,r*.06+1,0,T);c.fill();c.strokeStyle='#111'}}
if(pop){c.fillStyle=GUM;c.lineWidth=6;c.beginPath();for(let j=0;j<22;j++){const a=j*PI/11,rr=j%2?44:72;c.lineTo(128+cos(a)*rr,184+sin(a)*rr)}c.closePath();c.fill();c.stroke()
for(let j=0;j<8;j++){const a=j*PI/4+.3;c.beginPath();c.arc(128+cos(a)*92,184+sin(a)*84,6,0,T);c.fill();c.stroke()}}
if(stuck&&g>0){c.save();c.translate(128,172);c.scale(g,g);c.translate(-128,-172)
blobs(c,[[100,170,20],[128,175,22],[156,170,20],[82,152,12],[174,152,13],[116,191,10],[142,190,8],[66,136,8],[192,130,7],[152,100,9],[100,104,7]],12)
c.fillStyle=GD;for(const[x,y,r]of[[118,176,4],[146,168,3],[96,164,3]])c.beginPath(),c.arc(x,y,r,0,T),c.fill()
c.restore()}
c.restore()
}
+58
View File
@@ -0,0 +1,58 @@
// tiny chef girl with green hair tossing a pancake sky high out of her pan, watching it flip, and catching it
const{sin,cos,PI,abs}=Math,T=2*PI
export const frames=20,delay=70
const SKIN='#ffe3d1',HAIR='#51cf66',HD='#2f9e44',EYE='#f59f00',ED='#d9480f',BL='#ffa8a8',TIE='#fa5252',PANT='#868e96',PAN='#495057',RIM='#adb5bd',CAKE='#e8a33d',SIDE='#ffe8cc',BUT='#ffe066'
const ds=(c,a,b,s,f)=>{for(const[l,k]of[[a,'#111'],[b,s]])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),f(),c.stroke();c.strokeStyle='#111'}
const eye=(c,x,y,d,ly)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.clip()
c.beginPath();c.ellipse(x+ly*-.4,y+2+ly,11.5,15,0,0,T);c.fillStyle=EYE;c.fill();c.lineWidth=2.5;c.stroke()
c.save();c.clip();c.fillStyle=ED;c.beginPath();c.ellipse(x+ly*-.4,y-8+ly,13,10,0,0,T);c.fill();c.restore()
c.fillStyle='#111';c.beginPath();c.ellipse(x+ly*-.4,y+3+ly,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x+ly*-.4-4,y-5+ly,4.5,0,T);c.fill();c.beginPath();c.arc(x+ly*-.4+5,y+8+ly,2,0,T);c.fill();c.restore()
c.lineWidth=7;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
export default(c,t)=>{
const u=(t-.12)/.72,air=u>0&&u<1,dy=t<.12?-9*sin(PI*t/.12):t>.84?6*sin(PI*(t-.84)/.16):0
const py=air?202-150*4*u*(1-u):202+dy,px=air?200-10*sin(PI*u):200,th=air?T*u:0,h=(202-py)/150
c.translate(110,250);c.scale(1.12,1.12);c.translate(-110,-250)
for(const d of[-1,1])ds(c,14,7,PANT,()=>{c.moveTo(100+d*11,232);c.lineTo(100+d*12,246)})
c.fillStyle=PAN;c.lineWidth=5;for(const d of[-1,1])c.beginPath(),c.ellipse(100+d*13,248,9,5,0,0,T),c.fill(),c.stroke()
ds(c,20,11,'#fff',()=>{c.moveTo(84,206);c.lineTo(70,222);c.lineTo(80,232)})
c.lineWidth=6;c.fillStyle='#fff';c.beginPath();c.moveTo(88,196);c.quadraticCurveTo(70,202,72,238);c.lineTo(128,238);c.quadraticCurveTo(130,202,112,196);c.closePath();c.fill();c.stroke()
c.fillStyle='#111';for(const x of[93,107])for(const y of[214,226])c.beginPath(),c.arc(x,y,2.5,0,T),c.fill()
c.fillStyle=TIE;c.lineWidth=4;c.beginPath();c.moveTo(90,197);c.lineTo(110,197);c.lineTo(100,210);c.closePath();c.fill();c.stroke()
c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(80,232,7,7,0,0,T);c.fill();c.stroke()
const pan=()=>{c.moveTo(169,204+dy);c.quadraticCurveTo(172,224+dy,200,224+dy);c.quadraticCurveTo(228,224+dy,231,204+dy);c.ellipse(200,204+dy,31,10,0,0,PI,true)}
for(const[l,k]of[[13,'#fff'],[6,'#111']])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),c.moveTo(140,214+dy),c.lineTo(170,207+dy),c.stroke(),c.beginPath(),pan(),c.stroke()
ds(c,12,6,'#a9744f',()=>{c.moveTo(140,214+dy);c.lineTo(170,207+dy)})
c.lineWidth=6;c.fillStyle=PAN;c.beginPath();pan();c.fill();c.stroke()
c.fillStyle=RIM;c.beginPath();c.ellipse(200,204+dy,31,10,0,0,T);c.fill();c.stroke()
c.fillStyle=PAN;c.lineWidth=3;c.beginPath();c.ellipse(200,205+dy,24,7,0,0,T);c.fill();c.stroke()
ds(c,20,11,'#fff',()=>{c.moveTo(116,206);c.lineTo(132,214);c.lineTo(140,214+dy)})
c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(140,213+dy,8,7,0,0,T);c.fill();c.stroke()
const ry=3+8*abs(cos(th)),up=cos(th)>0
c.save();c.translate(px,py);c.rotate(air?.25*sin(th):0)
c.lineWidth=4;c.fillStyle=SIDE;c.beginPath();c.ellipse(0,0,22,ry,0,0,T);c.lineTo(22,4);c.ellipse(0,4,22,ry,0,0,PI);c.lineTo(-22,0);c.fill();c.stroke()
c.fillStyle=up?CAKE:'#f2b766';c.beginPath();c.ellipse(0,0,22,ry,0,0,T);c.fill();c.stroke()
if(up){c.strokeStyle='#ffc078';c.lineWidth=2.5;c.beginPath();c.ellipse(0,0,15,ry*.65,0,0,T);c.stroke();c.strokeStyle='#111'}
if(up&&ry>6){c.fillStyle=BUT;c.lineWidth=3;c.beginPath();c.rect(-6,-ry*.45,12,ry*.7);c.fill();c.stroke()}
c.restore()
if(air&&u>.15&&u<.85)for(const d of[-1,1])ds(c,7,3,'#fff',()=>{const y=py+(u<.5?16:-16);c.moveTo(px+d*26,y);c.lineTo(px+d*30,y+(u<.5?10:-10))})
if(air&&u>.38&&u<.62)c.fillStyle='#ffd43b',c.lineWidth=3.5,[[px-34,py-6,7],[px+32,py+10,5]].forEach(([x,y,r])=>{c.beginPath();for(let k=0;k<8;k++){const a=k*PI/4,q=k%2?r*.35:r;c.lineTo(x+cos(a)*q,y+sin(a)*q)}c.closePath();c.fill();c.stroke()})
c.save();c.translate(100,150);c.scale(.62,.62);c.translate(-128,-110)
c.lineWidth=7;c.fillStyle=HD;c.beginPath();c.moveTo(128,36);c.bezierCurveTo(194,36,206,96,194,166);c.lineTo(62,166);c.bezierCurveTo(50,96,62,36,128,36);c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
eye(c,103,140,-1,-9*h);eye(c,153,140,1,-9*h)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,162,13,7,0,0,T),c.fill()
c.lineWidth=5;c.fillStyle='#c92a2a';c.beginPath();c.moveTo(116,166);c.quadraticCurveTo(128,186,140,166);c.closePath();c.fill();c.stroke()
c.lineWidth=7;c.fillStyle=HAIR;c.beginPath();c.moveTo(68,160)
c.bezierCurveTo(52,74,88,40,128,40);c.bezierCurveTo(168,40,204,74,188,160)
c.quadraticCurveTo(186,124,180,108);c.quadraticCurveTo(166,108,158,96);c.quadraticCurveTo(150,110,134,112)
c.quadraticCurveTo(140,100,138,90);c.quadraticCurveTo(118,108,94,108);c.quadraticCurveTo(100,100,100,92);c.quadraticCurveTo(88,104,76,108)
c.quadraticCurveTo(70,130,68,160);c.closePath();c.fill();c.stroke()
const hat=[()=>c.rect(80,22,96,40),()=>c.arc(94,0,30,0,T),()=>c.arc(128,-16,36,0,T),()=>c.arc(162,0,30,0,T)]
c.fillStyle='#fff';c.lineWidth=14;for(const f of hat)c.beginPath(),f(),c.stroke();for(const f of hat)c.beginPath(),f(),c.fill()
c.lineWidth=4;c.beginPath();c.moveTo(80,30);c.lineTo(176,30);for(const x of[104,128,152])c.moveTo(x,10),c.lineTo(x,24);c.stroke()
c.restore()
}
+50
View File
@@ -0,0 +1,50 @@
// little girl in a nightcap sitting on a crescent moon, swinging her legs and fishing a wriggling star up on her line
const{sin,cos,PI,max,min}=Math,T=2*PI
export const frames=12,delay=110
const SKIN='#ffe3d1',HAIR='#74c0fc',HD='#339af0',HL='#e7f5ff',EYE='#fcc419',ED='#e67700',PJ='#748ffc',PD='#4c6ef5',MOON='#ffe066',MD='#fab005',STAR='#ffd43b',BL='#ffa8a8',Z=.55
const L=w=>w/Z
const star=(c,x,y,r,a)=>{c.save();c.translate(x,y);c.rotate(a);c.beginPath();for(let k=0;k<10;k++){const rr=k%2?r*.48:r,b=k*PI/5-PI/2;c.lineTo(cos(b)*rr,sin(b)*rr)}c.closePath();c.restore();c.fill();c.stroke()}
const twinkle=(c,x,y,s)=>{if(s<.2)return;c.fillStyle='#fff';c.lineWidth=3;c.beginPath();c.moveTo(x,y-10*s);for(const[a,b]of[[1,0],[0,1],[-1,0],[0,-1]])c.quadraticCurveTo(x,y,x+a*10*s,y+b*10*s);c.fill();c.stroke()}
export default(c,t)=>{
const sw=.07*sin(t*T),len=140+8*sin(t*T*2),tx=222,ty=44,sx=tx+len*sin(sw),sy=ty+len*cos(sw),lg=sin(t*T*2)
for(const[x,y,o]of[[176,24,0],[248,120,.33],[176,226,.66]])twinkle(c,x,y,sin(PI*((t*2+o)%1)))
const cres=(R,r)=>{c.beginPath();const hy=112-(R*R-r*r+26*26)/52,hx=Math.sqrt(R*R-(hy-112)**2),a=Math.atan2(hy-112,hx),b=Math.atan2(hy-86,hx);c.arc(118,112,R,a,PI-a);c.arc(118,86,r,PI-b,b,true);c.closePath()}
c.lineWidth=6;c.fillStyle=MOON;cres(92,84);c.fill();c.stroke()
c.save();cres(89,87);c.clip();c.fillStyle=MD;c.lineWidth=4
for(const[x,y,r]of[[44,158,8],[72,186,9],[162,188,7],[190,152,6],[32,116,5]])c.beginPath(),c.arc(x,y,r,0,T),c.fill(),c.stroke()
c.restore()
c.save();c.translate(112,130);c.scale(Z,Z);c.translate(-128,-186)
c.lineWidth=L(6);c.fillStyle=HD;c.beginPath();c.moveTo(128,50);c.bezierCurveTo(60,50,52,140,62,220);c.quadraticCurveTo(70,236,92,230);c.lineTo(164,230);c.quadraticCurveTo(186,236,194,220);c.bezierCurveTo(204,140,196,50,128,50);c.fill();c.stroke()
c.restore()
for(const d of[-1,1]){const a=d*lg*.45,kx=112+d*11,fx=kx+36*sin(a),fy=172+36*cos(a)
for(const[l,s]of[[19,'#111'],[10,PJ]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(kx,170),c.lineTo(fx,fy),c.stroke()
c.strokeStyle='#111';c.lineWidth=4.5;c.fillStyle=SKIN;c.beginPath();c.ellipse(fx+d*2+3*sin(a),fy+4,7,6,a,0,T);c.fill();c.stroke()}
c.lineWidth=6;c.fillStyle=PJ;c.beginPath();c.moveTo(102,130);c.quadraticCurveTo(92,142,88,164);c.quadraticCurveTo(112,172,136,164);c.quadraticCurveTo(132,142,122,130);c.closePath();c.fill();c.stroke()
for(const d of[-1,1])c.beginPath(),c.arc(112+d*11,168,10,0,T),c.fill(),c.stroke()
c.fillStyle=STAR;c.lineWidth=2.5;for(const[x,y]of[[100,150],[122,144],[110,160]])star(c,x,y,4.5,0)
for(const[l,s]of[[9,'#111'],[4,'#a9744f']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(116,162),c.lineTo(tx,ty),c.stroke()
c.strokeStyle='#111'
for(const[l,s]of[[5,'#111'],[2,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(tx,ty),c.lineTo(sx,sy),c.stroke()
c.strokeStyle='#111';const rx=136,ry=146,ra=t*T*2,cx=rx+9*cos(ra),cy=ry+9*sin(ra);c.lineWidth=4;c.fillStyle='#ced4da';c.beginPath();c.arc(rx,ry,6,0,T);c.fill();c.stroke();c.beginPath();c.moveTo(rx,ry);c.lineTo(cx,cy);c.stroke()
for(const[a,b]of[[[100,136],[126,156]],[[120,136],[cx,cy]]])for(const[l,s]of[[17,'#111'],[8,PJ]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(...a),c.lineTo(...b),c.stroke()
c.strokeStyle='#111';c.lineWidth=4.5;c.fillStyle=SKIN;for(const[x,y]of[[126,156],[cx,cy]])c.beginPath(),c.arc(x,y,6.5,0,T),c.fill(),c.stroke()
c.save();c.translate(112,130);c.scale(Z,Z);c.translate(-128,-186)
c.lineWidth=L(6);c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
for(const[x,d]of[[103,-1],[153,1]]){c.fillStyle='#fff';c.beginPath();c.ellipse(x,140,14,17,0,0,T);c.fill();c.save();c.clip();c.fillStyle=EYE;c.beginPath();c.ellipse(x+5,140,11.5,15,0,0,T);c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x+5,130,13,9,0,0,T);c.fill();c.fillStyle='#111';c.beginPath();c.ellipse(x+6,142,5.5,7.5,0,0,T);c.fill();c.fillStyle='#fff';c.beginPath();c.arc(x+2,134,5.5,0,T);c.fill();c.restore()
c.lineWidth=L(5.5);c.beginPath();c.moveTo(x-16,134);c.quadraticCurveTo(x,120,x+16,134);c.moveTo(x+d*15,133);c.lineTo(x+d*21,128);c.stroke()}
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,162,15,8,0,0,T),c.fill()
c.lineWidth=L(3.5);c.fillStyle='#c92a2a';c.beginPath();c.moveTo(120,164);c.quadraticCurveTo(130,180,140,164);c.closePath();c.fill();c.stroke()
c.lineWidth=L(6);c.fillStyle=HAIR;c.beginPath();c.moveTo(70,150)
c.bezierCurveTo(54,74,88,42,128,42);c.bezierCurveTo(168,42,202,74,186,150)
c.quadraticCurveTo(182,116,172,104);c.quadraticCurveTo(164,110,160,118);c.quadraticCurveTo(152,100,138,96);c.quadraticCurveTo(132,108,126,114)
c.quadraticCurveTo(118,100,104,98);c.quadraticCurveTo(98,110,96,118);c.quadraticCurveTo(90,106,84,104);c.quadraticCurveTo(72,120,70,150);c.closePath();c.fill();c.stroke()
const cp=.12*sin(t*T)
c.fillStyle=PJ;c.beginPath();c.moveTo(66,92);c.bezierCurveTo(70,30,150,14,196,40);c.quadraticCurveTo(230+30*cp,60,236+40*cp,108);c.quadraticCurveTo(214,70,190,88);c.quadraticCurveTo(130,64,66,92);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(62,96);c.quadraticCurveTo(128,62,194,90);c.lineTo(192,74);c.quadraticCurveTo(128,48,64,80);c.closePath();c.fill();c.stroke()
c.fillStyle=STAR;c.beginPath();c.arc(238+40*cp,112,17,0,T);c.fill();c.stroke()
c.restore()
c.fillStyle=STAR;c.lineWidth=4.5;star(c,sx,sy+20,20,sw*3+.25*sin(t*T*4))
c.strokeStyle='#fff';c.lineWidth=3;c.beginPath();c.moveTo(sx-6,sy+12);c.lineTo(sx-3,sy+9);c.stroke();c.strokeStyle='#111'
c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.arc(sx+d*6,sy+20,2,0,T),c.fill()
c.lineWidth=2.5;c.beginPath();c.arc(sx,sy+23,3,.1*PI,.9*PI);c.stroke()
}
+42
View File
@@ -0,0 +1,42 @@
// lovestruck girl with teal braids swooning: heart eyes pulsing, hands clasped at her cheek, swaying while hearts float up
const{sin,cos,PI,max}=Math,T=2*PI
export const frames=12,delay=100
const SKIN='#ffe3d1',HAIR='#38d9a9',HD='#0ca678',HL='#c3fae8',HE='#f03e3e',TOP='#fcc2d7',BL='#ff8fab',RB='#ffd43b',MO='#c92a2a',TG='#ff8fab',HT=['#ff8fab','#f06595','#ffa8a8']
const heart=(c,x,y,s)=>{c.save();c.translate(x,y);c.scale(s,s);c.beginPath();c.moveTo(0,8);c.bezierCurveTo(-13,-1,-9,-12,0,-5);c.bezierCurveTo(9,-12,13,-1,0,8);c.restore();c.fill();c.stroke()}
const braid=(c,x,d)=>{
c.lineWidth=5;c.fillStyle=HAIR
for(let k=5;k>=0;k--)c.beginPath(),c.ellipse(x+d*k*1.5,150+k*15,13-k*.6,10,(k%2?.5:-.5),0,T),c.fill(),c.stroke()
c.fillStyle=RB;c.lineWidth=4;c.beginPath();c.ellipse(x+d*9,232,9,5,0,0,T);c.fill();c.stroke()
c.fillStyle=HAIR;c.beginPath();c.moveTo(x+d*9-6,236);c.lineTo(x+d*9,250);c.lineTo(x+d*9+6,236);c.fill();c.stroke()
}
export default(c,t)=>{
const a=.1+.07*sin(T*t),pu=1+.2*max(0,sin(4*PI*t))
c.strokeStyle='#111';c.lineWidth=4
for(const[x0,o,k]of[[30,0,0],[226,.25,1],[48,.5,2],[212,.75,0]]){const p=(t+o)%1,s=1.3*sin(PI*p);if(s>.15)c.fillStyle=HT[k],heart(c,x0+8*sin(T*(p*2+o)),236-p*210,s)}
c.lineWidth=6;c.fillStyle=TOP;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(62,198,54,250);c.lineTo(202,250);c.quadraticCurveTo(194,198,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(106,190);c.lineTo(128,214);c.lineTo(150,190);c.closePath();c.fill();c.lineWidth=5;c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,168);c.lineTo(116,194);c.lineTo(128,206);c.lineTo(140,194);c.lineTo(140,168);c.fill();c.beginPath();c.moveTo(116,168);c.lineTo(116,192);c.moveTo(140,168);c.lineTo(140,192);c.stroke()
c.save();c.translate(128,186);c.rotate(a);c.translate(-128,-186)
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,36);c.bezierCurveTo(196,36,206,96,198,150);c.lineTo(58,150);c.bezierCurveTo(50,96,60,36,128,36);c.fill();c.stroke()
braid(c,70,-1);braid(c,186,1)
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
c.lineWidth=4;c.fillStyle=HE;for(const x of[103,153])heart(c,x,142,1.75*pu)
c.fillStyle='#fff';for(const x of[103,153])c.beginPath(),c.ellipse(x-7*pu,134,3.5*pu,2.5*pu,-.6,0,T),c.fill()
c.lineWidth=5;for(const[x,d]of[[103,-1],[153,1]])c.beginPath(),c.moveTo(x+d*18,128),c.lineTo(x+d*24,123),c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,162,14,7,0,0,T),c.fill()
c.lineWidth=2.5;for(const d of[-1,1])for(const k of[-6,-1,4])c.beginPath(),c.moveTo(128+d*44+k-2,166),c.lineTo(128+d*44+k+2,158),c.stroke()
c.lineWidth=3.5;c.fillStyle=MO;c.beginPath();c.moveTo(119,166);c.quadraticCurveTo(128,180,137,166);c.quadraticCurveTo(128,170,119,166);c.fill();c.stroke()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,146)
c.bezierCurveTo(54,74,88,36,128,36);c.bezierCurveTo(168,36,202,74,186,146)
c.quadraticCurveTo(184,114,176,102);c.quadraticCurveTo(166,100,160,110);c.quadraticCurveTo(152,96,138,92)
c.quadraticCurveTo(130,104,118,108);c.quadraticCurveTo(116,96,104,90);c.quadraticCurveTo(96,104,86,108)
c.quadraticCurveTo(80,104,78,104);c.quadraticCurveTo(72,120,70,146);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a2,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a2,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle=RB;c.lineWidth=4;c.beginPath();c.moveTo(82,70);c.lineTo(100,58);c.lineTo(94,78);c.closePath();c.fill();c.stroke()
c.restore()
for(const[x,y,e]of[[92,254,140],[196,254,166]])for(const[l,s]of[[30,'#111'],[19,TOP]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(x,y),c.lineTo(e,214),c.stroke()
c.strokeStyle='#111';c.lineWidth=5;c.fillStyle='#fff';for(const x of[140,166])c.beginPath(),c.ellipse(x,214,9,7,0,0,T),c.fill(),c.stroke()
c.fillStyle=SKIN;c.beginPath();c.ellipse(160,198,13,16,.3,0,T);c.fill();c.stroke()
c.beginPath();c.ellipse(146,198,13,16,-.3,0,T);c.fill();c.stroke()
c.lineWidth=2.5;c.beginPath();for(const y of[192,199,206])c.moveTo(150,y),c.lineTo(158,y-2);c.stroke()
}
+33
View File
@@ -0,0 +1,33 @@
// coral-haired girl swaying dizzy with spinning swirl eyes, a wobbly mouth and little stars orbiting her head
const{sin,cos,PI}=Math,T=2*PI
export const frames=12,delay=80
const SKIN='#ffe3d1',HAIR='#ff8787',HD='#f06565',HL='#ffe3e3',TOP='#96f2d7',TD='#38d9a9',PIN='#ffd43b',BL='#ffa8a8',ST='#ffd43b'
const star=(c,x,y,r,a)=>{c.save();c.translate(x,y);c.rotate(a);c.beginPath();for(let k=0;k<10;k++){const rr=k%2?r*.45:r,b=k*PI/5-PI/2;c.lineTo(cos(b)*rr,sin(b)*rr)}c.closePath();c.restore();c.fill();c.stroke()}
const swirl=(c,x,y,a)=>{
c.fillStyle='#fff';c.lineWidth=5;c.beginPath();c.ellipse(x,y,15,16,0,0,T);c.fill();c.stroke()
c.lineWidth=3.5;c.beginPath();for(let th=0;th<4.6*PI;th+=.2){const r=12.5*th/(4.6*PI);c.lineTo(x+r*cos(th+a),y+r*sin(th+a))}c.stroke()
}
export default(c,t)=>{
const a=t*T,sw=.07*sin(a)
c.save();c.translate(128,262);c.rotate(sw);c.translate(-128,-262)
const orbit=back=>{c.fillStyle=ST;c.lineWidth=3.5;for(let k=0;k<3;k++){const b=a+k*T/3,s=sin(b);if(s<0==back)star(c,128+74*cos(b),30+14*s,11+3*s,b)}}
orbit(true)
c.fillStyle=TOP;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(62,198,54,262);c.lineTo(202,262);c.quadraticCurveTo(194,198,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.moveTo(128,204),c.lineTo(128+d*30,190),c.lineTo(128+d*32,208),c.closePath(),c.fill(),c.stroke()
c.strokeStyle=TD;c.lineWidth=4;for(const y of[228,246])c.beginPath(),c.moveTo(66,y),c.lineTo(190,y),c.stroke();c.strokeStyle='#111'
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,166);c.lineTo(116,192);c.lineTo(128,204);c.lineTo(140,192);c.lineTo(140,166);c.fill();c.lineWidth=5;c.beginPath();c.moveTo(116,166);c.lineTo(116,190);c.moveTo(140,166);c.lineTo(140,190);c.stroke()
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
swirl(c,103,140,-a*2);swirl(c,153,140,-a*2+PI)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,163,11,5.5,0,0,T),c.fill()
c.lineWidth=3.5;c.beginPath();c.moveTo(114,170);for(let k=1;k<=6;k++)c.quadraticCurveTo(114+k*4.7-2.35,170+(k%2?-5:5)*cos(a*2),114+k*4.7,170);c.stroke()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(62,150)
c.bezierCurveTo(48,74,88,36,128,36);c.bezierCurveTo(168,36,208,74,194,150);c.quadraticCurveTo(186,156,180,148)
c.quadraticCurveTo(186,116,178,102);c.lineTo(172,110);c.quadraticCurveTo(166,96,156,90);c.quadraticCurveTo(152,102,146,108)
c.quadraticCurveTo(138,92,124,88);c.quadraticCurveTo(122,100,116,108);c.quadraticCurveTo(108,94,98,92);c.quadraticCurveTo(94,102,88,108)
c.quadraticCurveTo(82,100,78,100);c.quadraticCurveTo(70,118,76,148);c.quadraticCurveTo(70,156,62,150);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,b]of[[1.22,1.34],[1.42,1.5],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*b),c.stroke()
for(const[w,s]of[[10,'#111'],[4.5,PIN]]){c.lineWidth=w;c.strokeStyle=s;c.beginPath();c.moveTo(160,74);c.lineTo(184,92);c.moveTo(184,74);c.lineTo(160,92);c.stroke()}
c.strokeStyle='#111'
orbit(false)
c.restore()
}
+62
View File
@@ -0,0 +1,62 @@
// kitsune girl with orange fox ears fanning six fluffy tails behind her while blue foxfire circles around
const{sin,cos,PI}=Math,T=2*PI
export const frames=12,delay=90
const SKIN='#ffe3d1',HAIR='#ff922b',HD='#e8590c',HL='#ffe8cc',TIP='#fff4e6',EYE='#94d82d',ED='#5c940d',RED='#fa5252',BL='#ffa8a8',FF='#339af0',FC='#d0ebff'
const eye=(c,x,y,d,shut)=>{
if(shut){c.lineWidth=5;c.beginPath();c.moveTo(x-15,y);c.quadraticCurveTo(x,y+8,x+15,y);c.stroke();return}
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2,0,T);c.fill()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
c.strokeStyle=RED;c.lineWidth=4;c.beginPath();c.moveTo(x+d*13,y+12);c.lineTo(x+d*20,y+5);c.stroke();c.strokeStyle='#111'
}
const tail=(c,a,L,b)=>{
c.save();c.translate(128,224);c.rotate(a)
const p=()=>{c.beginPath();c.moveTo(0,-10);c.bezierCurveTo(L*.25,-34,L*.55,-46+b*.4,L*.84,-28+b*.8);c.quadraticCurveTo(L+4,-16+b,L+6,b-4);c.quadraticCurveTo(L-2,b+18,L*.84,24+b*.8);c.bezierCurveTo(L*.55,42+b*.4,L*.25,30,0,10);c.closePath()}
c.lineWidth=6;c.fillStyle=HAIR;p();c.fill();c.save();c.clip()
const z=()=>{c.beginPath();c.moveTo(L-28,-60);for(let k=0;k<6;k++)c.quadraticCurveTo(L-20+(k%2?6:-6),-50+k*20,L-28,-40+k*20)}
z();c.lineTo(L+30,60);c.lineTo(L+30,-60);c.fillStyle=TIP;c.fill();z();c.lineWidth=3;c.stroke()
c.strokeStyle=HD;c.lineWidth=3;c.beginPath();c.moveTo(24,0);c.bezierCurveTo(L*.4,-8,L*.5,-14+b*.4,L*.66,-18+b*.6);c.moveTo(L*.3,14);c.bezierCurveTo(L*.45,18,L*.55,14+b*.4,L*.66,8+b*.6);c.stroke()
c.restore();c.lineWidth=6;p();c.stroke();c.restore()
}
const flame=(c,x,y,s,w)=>{
c.save();c.translate(x,y);c.scale(s,s)
for(const[k,f]of[[1,FF],[.55,FC]]){
c.save();c.translate(0,6*(1-k));c.scale(k,k);c.beginPath();c.moveTo(w,-36);c.bezierCurveTo(w+2,-20,14,-12,14,4);c.arc(0,4,14,0,PI);c.quadraticCurveTo(-16,-8,-w*.5-12,-22);c.quadraticCurveTo(-4,-14,-2,-12);c.quadraticCurveTo(w*.6,-22,w,-36);c.closePath();c.restore();c.fillStyle=f;c.fill();if(k==1)c.lineWidth=5/s,c.stroke()
}
c.restore()
}
export default(c,t,i)=>{
const fire=front=>{for(let k=0;k<3;k++){const a=T*t+k*T/3,s=sin(a);if(s>0==front)flame(c,128+112*cos(a),216+24*s,.75+.1*s,8*sin(2*T*t+k*2))}}
fire(false)
for(const[k,a,L]of[[0,-2.98,118],[1,-2.6,140],[2,-2.2,160],[3,-.94,160],[4,-.54,140],[5,-.16,118]]){const p=T*t-k*.7;tail(c,a+.1*sin(p),L,14*sin(p-1))}
c.save();c.translate(128,258);c.scale(.72,.72);c.translate(-128,-256)
const tw=i>=4&&i<=6?.3*sin((i-4)*PI/2):0
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(200,34,214,96,206,150);c.quadraticCurveTo(212,196,198,214);c.lineTo(58,214);c.quadraticCurveTo(44,196,50,150);c.bezierCurveTo(42,96,56,34,128,34);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(100,188);c.quadraticCurveTo(62,196,54,256);c.lineTo(202,256);c.quadraticCurveTo(194,196,156,188);c.closePath();c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,166);c.lineTo(116,192);c.lineTo(128,214);c.lineTo(140,192);c.lineTo(140,166);c.fill();c.lineWidth=5;c.beginPath();c.moveTo(116,166);c.lineTo(116,190);c.moveTo(140,166);c.lineTo(140,190);c.stroke()
c.fillStyle=RED;for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*12,190),c.lineTo(128,218),c.lineTo(128-d*30,256),c.lineTo(128-d*44,256),c.lineTo(128-d*6,206),c.lineTo(128+d*2,190),c.closePath(),c.fill(),c.stroke()
for(const[d,r]of[[-1,tw],[1,0]]){
c.save();c.translate(128+d*40,62);c.rotate(r*d)
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(d*-24,10);c.quadraticCurveTo(d*-6,-30,d*12,-54);c.quadraticCurveTo(d*30,-18,d*24,14);c.closePath();c.fill();c.stroke()
c.fillStyle=TIP;c.beginPath();c.moveTo(d*-10,6);c.quadraticCurveTo(d*2,-20,d*12,-38);c.quadraticCurveTo(d*20,-12,d*14,8);c.closePath();c.fill()
c.restore()
}
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
const sh=i==9||i==10
eye(c,103,140,-1,sh);eye(c,153,140,1,sh)
c.lineWidth=2.5;c.beginPath();c.moveTo(128,156);c.lineTo(127,159);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,163,11,5,0,0,T),c.fill()
c.lineWidth=3.5;c.fillStyle='#c92a2a';c.beginPath();c.moveTo(121,167);c.quadraticCurveTo(128,176,135,167);c.closePath();c.fill();c.stroke()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(62,176)
c.bezierCurveTo(48,74,88,36,128,36);c.bezierCurveTo(168,36,208,74,194,176)
c.quadraticCurveTo(184,140,180,104);c.quadraticCurveTo(172,100,166,110);c.quadraticCurveTo(158,96,148,92);c.quadraticCurveTo(142,104,134,110)
c.quadraticCurveTo(128,96,120,92);c.quadraticCurveTo(116,104,108,110);c.quadraticCurveTo(100,96,92,94);c.quadraticCurveTo(86,104,84,110)
c.quadraticCurveTo(80,102,76,104);c.quadraticCurveTo(70,140,62,176);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle=RED;c.lineWidth=5;c.beginPath();c.moveTo(168,74);c.lineTo(190,64);c.lineTo(186,86);c.closePath();c.fill();c.stroke()
c.restore()
fire(true)
}
+47
View File
@@ -0,0 +1,47 @@
// hime cut gamer girl in a cat ear headset mashing her controller, flames burning in her eyes, teeth gritted, sweat flying
const{sin,PI}=Math,T=2*PI
export const frames=12,delay=70
const SKIN='#ffe3d1',HAIR='#495057',HD='#343a40',HL='#adb5bd',EYE='#fa5252',ED='#c92a2a',BL='#ffa8a8',HS='#f783ac',HSD='#e64980',HOOD='#69db7c',PAD='#e9ecef',SW='#a5d8ff',LED=['#ff6b6b','#ffd43b','#69db7c','#4dabf7','#b197fc','#f783ac']
const ds=(c,a,b,s,f)=>{for(const[l,k]of[[a,'#111'],[b,s]])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),f(),c.stroke();c.strokeStyle='#111'}
const eye=(c,x,y,d,i)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,16,0,0,T);c.fill()
c.save();c.clip();c.fillStyle=EYE;c.beginPath();c.ellipse(x,y+3,11.5,14,0,0,T);c.fill();c.lineWidth=2.5;c.stroke()
c.fillStyle=ED;c.beginPath();c.ellipse(x,y+16,13,7,0,0,T);c.fill()
const f=i%3,w=[5,6.5,5.5][f],h=[13,10,15][f],k=[-2,2,0][f]
c.fillStyle='#ffd43b';c.lineWidth=2;c.beginPath();c.moveTo(x+k,y-h+3);c.quadraticCurveTo(x+w,y,x+w*.8,y+6);c.quadraticCurveTo(x,y+13,x-w*.8,y+6);c.quadraticCurveTo(x-w,y,x+k,y-h+3);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y+6,2.5,4,0,0,T);c.fill()
c.fillStyle=SKIN;c.beginPath();c.moveTo(x-20,y-24);c.lineTo(x+20,y-24);c.lineTo(x+20,y+d*-4-8);c.lineTo(x-20,y+d*4-8);c.closePath();c.fill();c.restore()
c.lineWidth=7;c.beginPath();c.moveTo(x+d*17,y-13);c.lineTo(x-d*16,y-5);c.stroke()
c.lineWidth=2.5;c.beginPath();c.moveTo(x-8,y+19);c.lineTo(x+8,y+19);c.stroke()
}
export default(c,t,i)=>{
const a=t*T,lt=i%2,rt=(i+1)%2,sw=(t*2)%1
for(const[l,k]of[[14,'#fff'],[7,'#111']])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),c.moveTo(128,30),c.bezierCurveTo(202,30,214,100,206,170),c.lineTo(212,232),c.lineTo(44,232),c.lineTo(50,170),c.bezierCurveTo(42,100,54,30,128,30),c.stroke()
c.fillStyle=HD;c.fill()
c.lineWidth=6;c.fillStyle=HOOD;c.beginPath();c.moveTo(100,188);c.quadraticCurveTo(62,196,54,250);c.lineTo(202,250);c.quadraticCurveTo(194,196,156,188);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*12,198),c.lineTo(128+d*14,226),c.stroke(),c.beginPath(),c.arc(128+d*14,229,3.5,0,T),c.fill(),c.stroke()
c.fillStyle=SKIN;c.beginPath();c.rect(116,168,24,22);c.fill()
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
eye(c,103,142,-1,i);eye(c,153,142,1,i+1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,164,12,6,0,0,T),c.fill()
c.lineWidth=4;c.fillStyle='#fff';c.beginPath();c.moveTo(112,166);c.lineTo(144,166);c.quadraticCurveTo(146,178,136,178);c.lineTo(120,178);c.quadraticCurveTo(110,178,112,166);c.fill();c.stroke()
c.lineWidth=2.5;c.beginPath();c.moveTo(112,172);c.lineTo(145,172);for(const x of[120,128,136])c.moveTo(x,166),c.lineTo(x,178);c.stroke()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(60,186);c.lineTo(60,96);c.bezierCurveTo(60,46,92,34,128,34);c.bezierCurveTo(164,34,196,46,196,96);c.lineTo(196,186);c.lineTo(178,186);c.lineTo(176,116)
c.lineTo(172,112);c.lineTo(164,116);c.lineTo(156,112);c.lineTo(148,116);c.lineTo(140,112);c.lineTo(132,116);c.lineTo(124,112);c.lineTo(116,116);c.lineTo(108,112);c.lineTo(100,116);c.lineTo(92,112);c.lineTo(84,116);c.lineTo(80,116)
c.lineTo(78,186);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[s,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,100,58,PI*s,PI*e),c.stroke()
c.strokeStyle='#111';c.lineWidth=6;c.beginPath();c.moveTo(86,114);c.lineTo(114,124);c.moveTo(142,124);c.lineTo(170,114);c.stroke()
for(const d of[-1,1]){c.fillStyle=HS;c.lineWidth=5;c.beginPath();c.moveTo(128+d*22,52);c.lineTo(128+d*46,8);c.lineTo(128+d*66,62);c.closePath();c.fill();c.stroke();c.fillStyle=LED[(i+(d>0?3:0))%6];c.lineWidth=3;c.beginPath();c.moveTo(128+d*36,48);c.lineTo(128+d*46,26);c.lineTo(128+d*55,52);c.closePath();c.fill();c.stroke()}
ds(c,14,7,HS,()=>{c.arc(128,110,72,PI*1.05,PI*1.95)})
for(const d of[-1,1]){c.fillStyle=HS;c.lineWidth=6;c.beginPath();c.ellipse(128+d*68,128,13,22,0,0,T);c.fill();c.stroke();c.fillStyle=HSD;c.beginPath();c.ellipse(128+d*72,128,6,13,0,0,T);c.fill();c.lineWidth=3;c.stroke()}
ds(c,8,3,HSD,()=>{c.moveTo(62,144);c.quadraticCurveTo(64,174,96,178)});c.fillStyle=HSD;c.lineWidth=3;c.beginPath();c.arc(98,178,5,0,T);c.fill();c.stroke()
for(const[d,o]of[[1,0],[-1,.5]]){const p=(t*2+o)%1,s=sin(PI*p);if(s>.2){const x=128+d*(70+30*p),y=92-20*p+30*p*p;c.fillStyle=SW;c.lineWidth=4;c.beginPath();c.moveTo(x,y-11*s);c.quadraticCurveTo(x+7*s,y,x,y+5*s);c.quadraticCurveTo(x-7*s,y,x,y-11*s);c.fill();c.stroke()}}
for(const d of[-1,1])ds(c,26,16,HOOD,()=>{c.moveTo(128+d*82,256);c.lineTo(128+d*64,226)})
const pad=()=>{c.moveTo(80,204);c.lineTo(176,204);c.bezierCurveTo(206,204,214,236,200,246);c.quadraticCurveTo(186,254,170,236);c.lineTo(86,236);c.quadraticCurveTo(70,254,56,246);c.bezierCurveTo(42,236,50,204,80,204)}
c.fillStyle=PAD;c.lineWidth=6;c.beginPath();pad();c.fill();c.stroke()
c.fillStyle='#868e96';c.lineWidth=3;c.beginPath();c.rect(84,212,18,6);c.rect(90,206,6,18);c.fill();c.stroke()
for(const[x,y,col,k]of[[164,206,'#4dabf7',0],[174,215,'#ff6b6b',1],[154,215,'#ffd43b',2],[164,224,'#69db7c',3]]){const pr=k%2==rt;c.fillStyle=col;c.beginPath();c.arc(x,y+(pr?1:0),pr?3:4.5,0,T);c.fill();c.stroke()}
c.lineWidth=5;c.fillStyle=SKIN
for(const[x,y,p]of[[60,236,0],[196,236,0],[96,218-4*lt+2,1],[166,218-4*rt+2,1]])c.beginPath(),p?c.ellipse(x,y,8,9,0,0,T):c.ellipse(x,y,13,15,0,0,T),c.fill(),c.stroke()
for(const d of[-1,1])for(const k of[-1,1])ds(c,7,3,'#fff',()=>{const x=128+d*(54+(i%2)*3),y=196+k*8;c.moveTo(x,y);c.lineTo(x+d*10,y+k*5)})
}
+76
View File
@@ -0,0 +1,76 @@
// mint-haired girl at a festival goldfish tub: she scoops a fish up on her paper poi, the paper tears, the fish drops back and darts away
const{sin,cos,PI,max,min,atan2,hypot}=Math,T=2*PI
export const frames=20,delay=80
const SKIN='#ffe3d1',HAIR='#63e6be',HD='#12b886',HL='#e6fcf5',EYE='#f06595',ED='#a61e4d',TEE='#d0bfff',TD='#9775fa',RIB='#ff6b6b',TUB='#4dabf7',TL='#a5d8ff',WA='#99e9f2',WL='#e3fafc',BL='#ffa8a8',POI='#f783ac',Z=.7
const cl=x=>max(0,min(1,x)),ease=x=>x*x*(3-2*x)
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+4,11.5,14,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-6,13,9,0,0,T);c.fill();c.restore()
c.lineWidth=3;c.beginPath();c.ellipse(x,y+4,11.5,14,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+6,5.5,7,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-2,5,0,T);c.fill();c.beginPath();c.arc(x+5,y+10,2.5,0,T);c.fill()
c.lineWidth=8;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const fish=(c,x,y,a,col,s=1)=>{c.save();c.translate(x,y);c.rotate(a);c.scale(s,s);c.lineWidth=3.5/s;c.fillStyle=col
c.beginPath();c.moveTo(-8,0);c.quadraticCurveTo(-18,-9,-20,-3);c.lineTo(-17,0);c.lineTo(-20,3);c.quadraticCurveTo(-18,9,-8,0);c.fill();c.stroke()
c.beginPath();c.ellipse(0,0,11,6.5,0,0,T);c.fill();c.stroke();c.fillStyle='#111';c.beginPath();c.arc(6,-2,1.6,0,T);c.fill();c.restore()}
const E=th=>[128+72*cos(th),198+14*sin(th)]
export default(c,t)=>{
const up=ease(cl((t-.3)/.12)),tear=cl((t-.42)/.06),down=ease(cl((t-.8)/.14)),sub=t<.3||t>=.94
const C=[128-6*up+6*down,214-50*up+50*down],H=[C[0]+44,C[1]-24]
let F,fa=0
if(t<.3){const th=PI-PI/2*ease(t/.3);F=E(th);const[nx,ny]=E(th-.05);fa=atan2(ny-F[1],nx-F[0])}
else if(t<.5){const dr=cl((t-.44)/.06);F=[C[0],C[1]+(214-C[1])*dr*dr];fa=-.3+dr*3}
else{const k=(t-.5)/.5,th=PI/2-1.5*PI*(1-(1-k)**2);F=E(th);const[nx,ny]=E(th-.05);fa=atan2(ny-F[1],nx-F[0])}
c.save();c.translate(128,126);c.scale(Z,Z);c.translate(-128,-186)
c.lineWidth=8.5;c.fillStyle=HAIR;for(const d of[-1,1])c.beginPath(),c.arc(128+d*50,52,26,0,T),c.fill(),c.stroke()
c.fillStyle=RIB;for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*34,70),c.lineTo(128+d*20,58),c.lineTo(128+d*22,82),c.closePath(),c.fill(),c.stroke()
c.fillStyle=HD;c.beginPath();c.moveTo(128,50);c.bezierCurveTo(62,50,58,110,68,170);c.lineTo(188,170);c.bezierCurveTo(198,110,194,50,128,50);c.fill();c.stroke()
c.fillStyle=TEE;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(58,196,44,262);c.lineTo(212,262);c.quadraticCurveTo(198,196,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.rect(116,168,24,26);c.fill();c.beginPath();c.moveTo(116,168);c.lineTo(116,190);c.moveTo(140,168);c.lineTo(140,190);c.stroke()
c.beginPath();c.moveTo(108,190);c.quadraticCurveTo(128,212,148,190);c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
const st=t>=.3&&t<.44?1:t>=.46&&t<.84?2:0
if(st==2){c.lineWidth=8;for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*39,134),c.lineTo(128+d*23,143),c.lineTo(128+d*39,152),c.stroke()}
else eye(c,103,140,-1),eye(c,153,140,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,161,14,7,0,0,T),c.fill()
c.lineWidth=5;c.fillStyle='#c92a2a';c.beginPath()
if(st==1)c.moveTo(114,164),c.quadraticCurveTo(128,188,142,164),c.closePath(),c.fill(),c.stroke()
else if(st==2)c.moveTo(112,176),c.quadraticCurveTo(116,160,128,162),c.quadraticCurveTo(140,160,144,176),c.quadraticCurveTo(128,170,112,176),c.fill(),c.stroke()
else c.moveTo(120,168),c.lineTo(136,168),c.stroke()
c.lineWidth=8.5;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,146)
c.bezierCurveTo(54,74,88,42,128,42);c.bezierCurveTo(168,42,202,74,186,146)
c.quadraticCurveTo(184,116,174,104);c.quadraticCurveTo(166,108,160,116);c.quadraticCurveTo(154,100,140,94);c.quadraticCurveTo(134,104,128,110)
c.quadraticCurveTo(122,100,112,96);c.quadraticCurveTo(104,108,98,116);c.quadraticCurveTo(92,106,84,104);c.quadraticCurveTo(72,118,70,146);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=6;for(const[a,e]of[[1.3,1.42],[1.5,1.6]])c.beginPath(),c.arc(128,104,54,PI*a,PI*e),c.stroke();c.strokeStyle='#111'
if(st==2){const w=(t*5)%1;c.fillStyle=TL;c.lineWidth=5;for(const d of[-1,1])for(const k of[0,.5]){const q=(w+k)%1,x=128+d*(40+50*q),y=144-20*q+60*q*q,r=13;c.save();c.translate(x,y);c.rotate(d*(.6-q*1.2));c.beginPath();c.moveTo(0,-r*1.6);c.quadraticCurveTo(r,0,0,r);c.quadraticCurveTo(-r,0,0,-r*1.6);c.restore();c.fill();c.stroke()}}
c.restore()
c.lineWidth=6;c.fillStyle=TUB;c.beginPath();c.moveTo(14,198);c.lineTo(24,234);c.quadraticCurveTo(128,256,232,234);c.lineTo(242,198);c.closePath();c.fill();c.stroke()
c.fillStyle=TL;c.beginPath();c.ellipse(128,198,114,36,0,0,T);c.fill();c.stroke()
c.fillStyle=WA;c.beginPath();c.ellipse(128,200,102,28,0,0,T);c.fill();c.lineWidth=4;c.stroke()
c.save();c.beginPath();c.ellipse(128,200,100,26,0,0,T);c.clip()
for(const[o,r,n,col]of[[0,.75,1,'#ff922b'],[.4,.45,-1,'#ff6b6b'],[.7,.95,1,'#fff']]){const th=(t*n+o)*T,x=128+82*r*cos(th),y=200+18*r*sin(th);fish(c,x,y,th+n*PI/2,col)}
if(t<.3||t>=.5)fish(c,F[0],F[1],fa,'#ff6b6b',1.15)
if(sub){c.strokeStyle=WL;c.lineWidth=3;const r=(t*4)%1;c.beginPath();c.ellipse(C[0]+26,C[1]-13,8+14*r,3+5*r,0,0,T);c.stroke()}
const sp=cl((t-.48)/.12);if(sp>0&&sp<1){c.strokeStyle=WL;c.lineWidth=3.5;c.beginPath();c.ellipse(F[0],206,10+30*sp,3+8*sp,0,0,T);c.stroke()}
c.restore();c.strokeStyle='#111'
if(sp>0&&sp<1){c.fillStyle=WA;c.lineWidth=3;for(const d of[-1,-.4,.4,1]){const x=F[0]+d*30*sp,y=206-40*sp*(1-sp)*(2-Math.abs(d));c.beginPath();c.arc(x,y,4,0,T);c.fill();c.stroke()}}
for(const[l,s]of[[24,'#111'],[13,TEE]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(150,150),c.quadraticCurveTo(170,150,H[0]+2,H[1]-2),c.stroke()
for(const[l,s]of[[24,'#111'],[13,TEE]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(106,150),c.quadraticCurveTo(80,150,64,176),c.stroke()
c.strokeStyle='#111';c.lineWidth=5;c.fillStyle='#fff';c.beginPath();c.moveTo(40,176);c.quadraticCurveTo(42,198,60,200);c.quadraticCurveTo(78,198,80,176);c.closePath();c.fill();c.stroke()
c.strokeStyle=TUB;c.lineWidth=3;c.beginPath();c.moveTo(44,186);c.quadraticCurveTo(60,192,76,186);c.stroke();c.strokeStyle='#111'
c.fillStyle=TL;c.beginPath();c.ellipse(60,176,20,5,0,0,T);c.fill();c.lineWidth=4;c.stroke()
c.fillStyle=SKIN;c.lineWidth=5;c.beginPath();c.ellipse(66,178,9,8,0,0,T);c.fill();c.stroke()
const hd=[C[0]+20,C[1]-11]
if(sub){for(const[l,s]of[[10,'#111'],[5,POI]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(...H),c.lineTo(C[0]+26,C[1]-13),c.stroke();c.strokeStyle='#111'}
else{
for(const[l,s]of[[10,'#111'],[5,POI]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(...H),c.lineTo(...hd),c.stroke()
c.strokeStyle='#111';c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.ellipse(C[0],C[1],21,13,0,0,T)
if(tear>0){const R=k=>.35+.25*tear+.12*sin(k*2.7);c.moveTo(C[0]+16*R(0)*1.2,C[1]);for(let k=1;k<=10;k++){const a=k*T/10;c.lineTo(C[0]+16*cos(a)*R(k)*1.2,C[1]+10*sin(a)*R(k)*1.2)}c.closePath()}
c.fill('evenodd');if(tear>0)c.lineWidth=2.5,c.stroke(),c.lineWidth=4
c.fillStyle=POI;c.beginPath();c.ellipse(C[0],C[1],21,13,0,0,T);c.ellipse(C[0],C[1],17,10,0,0,T,true);c.fill();c.stroke()
if(t>=.3&&t<.44)fish(c,F[0],F[1]-2,fa,'#ff6b6b',1.15)
else if(t>=.44&&t<.5)fish(c,F[0],F[1],fa,'#ff6b6b',1.15)
}
c.fillStyle=SKIN;c.lineWidth=5;c.beginPath();c.ellipse(H[0],H[1],10,9,0,0,T);c.fill();c.stroke()
}
+58
View File
@@ -0,0 +1,58 @@
// little band girl with messy mint hair rocking out on a red electric guitar, head bobbing, strumming hand flying, notes popping out
const{sin,cos,PI,abs}=Math,T=2*PI
export const frames=12,delay=85
const SKIN='#ffe3d1',HAIR='#a9e34b',HD='#74b816',HL='#e9fac8',EYE='#ff922b',ED='#d9480f',BL='#ffa8a8',JK='#4c6ef5',RIB='#fa5252',SK='#868e96',GT='#e03131',PG='#fff3bf',WD='#a9744f'
const ds=(c,a,b,s,f)=>{for(const[l,k]of[[a,'#111'],[b,s]])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),f(),c.stroke();c.strokeStyle='#111'}
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2,0,T);c.fill()
c.lineWidth=7;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const note=(c,x,y,s,col)=>{
ds(c,8,3,col,()=>{c.moveTo(x+6*s,y);c.lineTo(x+6*s,y-22*s);c.quadraticCurveTo(x+18*s,y-16*s,x+14*s,y-6*s)})
c.fillStyle=col;c.lineWidth=3.5;c.beginPath();c.ellipse(x,y,7*s,5*s,-.4,0,T);c.fill();c.stroke()
}
export default(c,t)=>{
const a=t*T,nod=abs(sin(2*a)),hy=196+9*cos(4*a),tap=Math.max(0,sin(2*a))
c.translate(128,250);c.scale(1.1,1.1);c.translate(-142,-250)
for(const[x,o]of[[166,0],[196,.5]]){const p=(t+o)%1,s=sin(PI*p);if(s>.2)note(c,x+8*sin(p*T),150-100*p,.5+.6*s,o?'#ffd43b':'#74c0fc')}
for(const[x,l]of[[106,0],[128,tap*5]]){ds(c,13,7,SKIN,()=>{c.moveTo(x,214);c.lineTo(x,236-l)});c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.rect(x-5,230-l,10,8);c.fill();c.stroke();c.fillStyle=WD;c.beginPath();c.ellipse(x+2,242-l,9,5,0,0,T);c.fill();c.stroke()}
c.lineWidth=5;c.fillStyle=SK;c.beginPath();c.moveTo(92,198);c.lineTo(84,220);c.lineTo(150,220);c.lineTo(142,198);c.closePath();c.fill();c.stroke()
c.beginPath();for(const x of[100,117,134])c.moveTo(x,200),c.lineTo(x-2,219);c.lineWidth=3;c.stroke()
c.lineWidth=6;c.fillStyle=JK;c.beginPath();c.moveTo(104,144);c.quadraticCurveTo(88,150,90,200);c.lineTo(144,200);c.quadraticCurveTo(146,150,130,144);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.moveTo(106,144);c.lineTo(117,162);c.lineTo(128,144);c.closePath();c.fill();c.stroke()
c.fillStyle=RIB;c.beginPath();c.moveTo(117,156);c.lineTo(109,152);c.lineTo(110,162);c.closePath();c.moveTo(117,156);c.lineTo(125,152);c.lineTo(124,162);c.closePath();c.fill();c.stroke()
ds(c,9,4,'#495057',()=>{c.moveTo(130,146);c.lineTo(94,206)})
ds(c,20,11,JK,()=>{c.moveTo(132,152);c.lineTo(154,170);c.lineTo(176,162)})
c.save();c.translate(112,196);c.rotate(-.55)
ds(c,16,9,WD,()=>{c.moveTo(14,0);c.lineTo(104,0)})
c.fillStyle=GT;c.lineWidth=5;c.beginPath();c.moveTo(102,-8);c.lineTo(122,-11);c.lineTo(124,11);c.lineTo(102,8);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.lineWidth=2.5;for(const x of[108,116])for(const d of[-1,1])c.beginPath(),c.arc(x,d*11,2.5,0,T),c.fill(),c.stroke()
const gb=()=>{c.moveTo(20,0);c.bezierCurveTo(20,-22,4,-20,-2,-14);c.bezierCurveTo(-12,-30,-44,-30,-44,0);c.bezierCurveTo(-44,30,-12,30,-2,14);c.bezierCurveTo(4,20,20,22,20,0)}
c.fillStyle=GT;c.lineWidth=6;c.beginPath();gb();c.fill();c.stroke()
c.fillStyle=PG;c.lineWidth=3;c.beginPath();c.moveTo(4,-12);c.quadraticCurveTo(-18,-16,-20,0);c.quadraticCurveTo(-18,14,4,12);c.closePath();c.fill();c.stroke()
c.fillStyle='#e9ecef';for(const x of[-28,-6])c.beginPath(),c.rect(x-3,-9,6,18),c.fill(),c.stroke()
c.strokeStyle='#fff';c.lineWidth=1.5;c.beginPath();for(const y of[-4.5,-1.5,1.5,4.5])c.moveTo(-34,y),c.lineTo(104,y);c.stroke();c.strokeStyle='#111'
c.restore()
c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(176,160,9,10,0,0,T);c.fill();c.stroke()
ds(c,20,11,JK,()=>{c.moveTo(102,152);c.lineTo(84,180);c.lineTo(98,hy)})
c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(100,hy,9,10,0,0,T);c.fill();c.stroke()
for(const d of[-1,1])ds(c,6,2.5,'#fff',()=>{c.moveTo(78,hy+d*6);c.lineTo(70,hy+d*9)})
c.save();c.translate(116,140);c.rotate(.08*nod-.04);c.translate(0,2*nod);c.scale(.62,.62);c.translate(-128,-180)
c.lineWidth=7;c.fillStyle=HD;c.beginPath();c.moveTo(128,36);c.bezierCurveTo(196,36,210,92,200,140);c.lineTo(208,160);c.lineTo(188,154);c.lineTo(190,172);c.lineTo(66,172);c.lineTo(68,154);c.lineTo(48,160);c.lineTo(56,140);c.bezierCurveTo(46,92,60,36,128,36);c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
eye(c,103,140,-1);eye(c,153,140,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,162,13,7,0,0,T),c.fill()
c.lineWidth=5;c.fillStyle='#c92a2a';c.beginPath();c.moveTo(112,164);c.quadraticCurveTo(128,186,144,164);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.lineWidth=2.5;c.beginPath();c.moveTo(134,166);c.lineTo(140,166);c.lineTo(137,172);c.closePath();c.fill();c.stroke()
c.lineWidth=7;c.fillStyle=HAIR;c.beginPath();c.moveTo(66,154)
c.bezierCurveTo(48,74,88,34,128,34);c.bezierCurveTo(170,34,210,74,190,154)
c.lineTo(184,124);c.lineTo(176,128);c.lineTo(170,104);c.lineTo(158,114);c.lineTo(150,92);c.lineTo(138,110)
c.lineTo(128,90);c.lineTo(118,112);c.lineTo(104,94);c.lineTo(98,114);c.lineTo(84,104);c.lineTo(80,128);c.lineTo(72,124);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=6;for(const[s,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*s,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle='#ffd43b';c.lineWidth=5;c.beginPath();c.rect(162,70,22,9);c.fill();c.stroke()
c.restore()
}
+38
View File
@@ -0,0 +1,38 @@
// fluffy light-brown haired girl getting head pats, squishing down with happy ^^ eyes while flowers and sparkles float up
const{sin,cos,PI,max,min}=Math,T=2*PI
export const frames=12,delay=80
const SKIN='#ffe3d1',HAIR='#d4a373',HD='#b07d4f',HL='#f3dcc0',TOP='#a5d8ff',TD='#74c0fc',RIB='#f06595',BL='#ff8fab',MO='#c92a2a',TG='#ff8fab',HAND='#f8d0b0',SL='#748ffc'
const flower=(c,x,y,r,a,f)=>{c.save();c.translate(x,y);c.rotate(a);c.fillStyle=f;c.lineWidth=3.5;c.beginPath();for(let k=0;k<5;k++){const b=k*T/5;c.moveTo(cos(b)*r*1.5+r*.75,sin(b)*r*1.5);c.arc(cos(b)*r*1.5,sin(b)*r*1.5,r*.75,0,T)}c.stroke();c.fill();c.fillStyle='#ffd43b';c.beginPath();c.arc(0,0,r*.7,0,T);c.fill();c.stroke();c.restore()}
export default(c,t)=>{
c.translate(128,256);c.scale(.88,.88);c.translate(-128,-256)
const p=(t*2)%1,h=(1+cos(T*p))/2,yb=50-28*h,q=max(0,yb-34)/110,a=t*T
for(const[x,y,r,o,f]of[[36,120,7,0,'#ffc9de'],[220,110,7,.5,'#fff3bf'],[28,200,6,.25,'#d3f9d8'],[228,190,6,.75,'#ffc9de']])flower(c,x+4*sin(a+o*T),y-6*sin(2*a+o*T),r,a*(o>.4?-1:1),f)
const sq=f=>{c.save();c.translate(128,186);c.scale(1+.4*q,1-q);c.translate(-128,-186);f();c.restore()}
sq(()=>{c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,30);c.bezierCurveTo(198,30,214,90,204,150);c.quadraticCurveTo(212,168,196,176);c.lineTo(60,176);c.quadraticCurveTo(44,168,52,150);c.bezierCurveTo(42,90,58,30,128,30);c.fill();c.stroke()})
c.fillStyle=TOP;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(62,198,54,256);c.lineTo(202,256);c.quadraticCurveTo(194,198,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.moveTo(128,198),c.quadraticCurveTo(128+d*36,192,128+d*34,210),c.quadraticCurveTo(128+d*20,220,128,206),c.closePath(),c.fill(),c.lineWidth=5,c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,166);c.lineTo(116,190);c.lineTo(128,200);c.lineTo(140,190);c.lineTo(140,166);c.fill();c.beginPath();c.moveTo(116,166);c.lineTo(116,188);c.moveTo(140,166);c.lineTo(140,188);c.stroke()
c.fillStyle=RIB;for(const d of[-1,1])c.beginPath(),c.moveTo(128,214),c.lineTo(128+d*16,206),c.lineTo(128+d*14,224),c.closePath(),c.fill(),c.stroke()
c.beginPath();c.arc(128,215,4.5,0,T);c.fill();c.stroke()
sq(()=>{
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
c.lineWidth=6;for(const x of[103,153])c.beginPath(),c.arc(x,146,13,PI*1.1,PI*1.9),c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,160,14,7,0,0,T),c.fill()
c.lineWidth=2.5;for(const d of[-1,1])for(const k of[-6,0,6])c.beginPath(),c.moveTo(128+d*42+k-2,164),c.lineTo(128+d*42+k+2,157),c.stroke()
c.fillStyle=MO;c.lineWidth=3.5;c.beginPath();c.moveTo(118,164);c.quadraticCurveTo(128,168,138,164);c.quadraticCurveTo(136,180,128,180);c.quadraticCurveTo(120,180,118,164);c.fill();c.stroke()
c.save();c.clip();c.fillStyle=TG;c.beginPath();c.ellipse(128,181,7,5,0,0,T);c.fill();c.restore()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(64,152)
c.bezierCurveTo(46,72,88,32,128,32);c.bezierCurveTo(168,32,210,72,192,152);c.quadraticCurveTo(184,158,180,150);c.quadraticCurveTo(188,130,180,112)
c.quadraticCurveTo(178,100,170,106);c.quadraticCurveTo(164,92,152,98);c.quadraticCurveTo(144,86,134,98);c.quadraticCurveTo(124,88,114,98)
c.quadraticCurveTo(104,88,96,100);c.quadraticCurveTo(86,94,84,108);c.quadraticCurveTo(76,108,76,118);c.quadraticCurveTo(68,132,76,150);c.quadraticCurveTo(70,158,64,152);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,b]of[[1.22,1.34],[1.42,1.5],[1.62,1.74]])c.beginPath(),c.arc(128,100,58,PI*a,PI*b),c.stroke()
c.strokeStyle='#111'
})
for(const[w,s]of[[40,'#111'],[29,SL]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(262,yb-110),c.lineTo(184,yb-26),c.stroke()
c.strokeStyle='#111';c.lineWidth=5;c.fillStyle=HAND
c.beginPath();c.ellipse(170,yb-4,9,15,.6,0,T);c.fill();c.stroke()
c.beginPath();c.moveTo(186,yb-44);c.quadraticCurveTo(150,yb-50,112,yb-36);c.quadraticCurveTo(92,yb-28,96,yb-12);c.quadraticCurveTo(100,yb+2,120,yb);c.quadraticCurveTo(160,yb+4,184,yb-10);c.fill();c.stroke()
c.lineWidth=3;c.beginPath();for(const k of[0,1,2])c.moveTo(98+k*2,yb-30+k*8),c.lineTo(128+k*3,yb-30+k*8);c.stroke()
c.fillStyle='#fff';c.lineWidth=3.5
for(const[x,y,o]of[[56,64,0],[204,58,.33],[196,150,.66],[44,166,.5]]){const r=11*max(0,sin(T*((t*2+o)%1)));if(r>2){c.beginPath();c.moveTo(x,y-r);c.quadraticCurveTo(x+r*.2,y-r*.2,x+r,y);c.quadraticCurveTo(x+r*.2,y+r*.2,x,y+r);c.quadraticCurveTo(x-r*.2,y+r*.2,x-r,y);c.quadraticCurveTo(x-r*.2,y-r*.2,x,y-r);c.fill();c.stroke()}}
}
+54
View File
@@ -0,0 +1,54 @@
// magenta haired idol singing into her mic with her eyes closed, side ponytail bouncing to the beat, notes floating up, fans waving glow sticks
const{sin,cos,PI,abs}=Math,T=2*PI
export const frames=12,delay=90
const SKIN='#ffe3d1',HAIR='#e64980',HD='#c2255c',HL='#ffdeeb',BL='#ffa8a8',DR='#3bc9db',BOW='#ffd43b',MIC='#ced4da',GRIP='#f06595'
const ds=(c,a,b,s,f)=>{for(const[l,k]of[[a,'#111'],[b,s]])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),f(),c.stroke();c.strokeStyle='#111'}
const note=(c,x,y,s,col,two)=>{
ds(c,8,3,col,()=>{c.moveTo(x+6*s,y);c.lineTo(x+6*s,y-24*s);if(two)c.lineTo(x+22*s,y-28*s),c.lineTo(x+22*s,y-4*s);else c.quadraticCurveTo(x+18*s,y-18*s,x+14*s,y-8*s)})
c.fillStyle=col;c.lineWidth=3.5;for(const o of two?[0,16]:[0])c.beginPath(),c.ellipse(x+o*s,y+(o?-4*s:0),7*s,5*s,-.4,0,T),c.fill(),c.stroke()
}
const spark=(c,x,y,r)=>{c.beginPath();c.moveTo(x,y-r);for(const[a,b]of[[1,0],[0,1],[-1,0],[0,-1]])c.quadraticCurveTo(x+(a+b)*r*.15,y+(b-a)*r*.15,x+a*r,y+b*r);c.fill();c.stroke()}
export default(c,t)=>{
const a=t*T,op=abs(sin(2*a))
for(const[x,s,o]of[[34,1,0],[62,-1,.5]]){const p=(t+o)%1,y=150-110*p,sc=sin(PI*p);if(sc>.2)note(c,x+10*sin(p*T*2)*s,y,.6+.6*sc,['#ffd43b','#66d9e8'][o?1:0],!o)}
c.fillStyle='#fff';for(const[x,y,o]of[[30,60,0],[226,52,.33],[214,120,.66]]){const r=9*sin(PI*((t*2+o)%1));if(r>2)c.lineWidth=3.5,spark(c,x,y,r)}
const head=f=>f()
head(()=>{
c.save();c.translate(180,64);c.rotate(.12+.18*sin(2*a+.8));c.scale(.9,.9)
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(-6,-4);c.bezierCurveTo(44,-20,70,50,56,120);c.quadraticCurveTo(48,142,30,146);c.quadraticCurveTo(44,96,0,20);c.closePath();c.fill();c.stroke()
c.strokeStyle=HD;c.lineWidth=3;c.beginPath();c.moveTo(14,6);c.bezierCurveTo(40,20,52,70,44,118);c.stroke();c.strokeStyle='#111'
c.restore()
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(196,34,206,96,198,156);c.lineTo(58,156);c.bezierCurveTo(50,96,60,34,128,34);c.fill();c.stroke()
})
c.lineWidth=6;c.fillStyle=DR;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(62,198,54,250);c.lineTo(202,250);c.quadraticCurveTo(194,198,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.lineWidth=4;for(let k=0;k<5;k++)c.beginPath(),c.arc(104+k*12,196,7,0,PI),c.fill(),c.stroke()
c.fillStyle=SKIN;c.lineWidth=5;c.beginPath();c.rect(116,168,24,22);c.fill();c.beginPath();c.moveTo(116,168);c.lineTo(116,189);c.moveTo(140,168);c.lineTo(140,189);c.stroke()
c.fillStyle=BOW;for(const d of[-1,1])c.beginPath(),c.moveTo(128,226),c.quadraticCurveTo(128+d*24,204,128+d*28,224),c.quadraticCurveTo(128+d*22,242,128,226),c.fill(),c.stroke()
c.beginPath();c.arc(128,226,6,0,T);c.fill();c.stroke()
head(()=>{
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
for(const d of[-1,1]){const x=128+d*25;c.lineWidth=6;c.beginPath();c.arc(x,148,13,PI*1.15,PI*1.85);c.moveTo(x+d*12,140);c.lineTo(x+d*18,135);c.moveTo(x+d*13,145);c.lineTo(x+d*20,144);c.stroke()}
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,162,13,7,0,0,T),c.fill()
c.lineWidth=2.5;for(const d of[-1,1])for(const k of[-5,0,5])c.beginPath(),c.moveTo(128+d*44+k-2,165),c.lineTo(128+d*44+k+2,159),c.stroke()
c.lineWidth=3.5;c.fillStyle='#c92a2a';c.beginPath();c.ellipse(128,169,7+op,3+6*op,0,0,T);c.fill();c.stroke()
c.save();c.clip();c.fillStyle='#ff8fab';c.beginPath();c.ellipse(128,176,6,4,0,0,T);c.fill();c.restore()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,150)
c.bezierCurveTo(54,74,88,36,128,36);c.bezierCurveTo(168,36,202,74,186,150)
c.quadraticCurveTo(184,118,176,104);c.quadraticCurveTo(170,98,164,104);c.quadraticCurveTo(160,94,148,90);c.quadraticCurveTo(144,102,134,108)
c.quadraticCurveTo(130,96,120,90);c.quadraticCurveTo(114,102,104,108);c.quadraticCurveTo(100,96,92,94);c.quadraticCurveTo(86,104,82,110)
c.quadraticCurveTo(76,124,70,150);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle=BOW;c.lineWidth=4;c.beginPath();for(let k=0;k<10;k++){const r=k%2?5:11,b=k*PI/5-PI/2;c.lineTo(176+cos(b)*r,62+sin(b)*r)}c.closePath();c.fill();c.stroke()
})
for(const[l,k]of[[30,'#111'],[19,DR]])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),c.moveTo(66,250),c.lineTo(78,226),c.lineTo(96,224),c.stroke()
c.strokeStyle='#111';ds(c,16,9,GRIP,()=>{c.moveTo(100,234);c.lineTo(108,196)})
c.lineWidth=5;c.fillStyle=MIC;c.beginPath();c.arc(110,190,13,0,T);c.fill();c.stroke()
c.save();c.clip();c.strokeStyle='#868e96';c.lineWidth=2;c.beginPath();for(let k=-12;k<=12;k+=6)c.moveTo(97,190+k),c.lineTo(123,190+k),c.moveTo(110+k,177),c.lineTo(110+k,203);c.stroke();c.restore()
c.lineWidth=5;c.beginPath();c.arc(110,190,13,0,T);c.stroke()
c.fillStyle=SKIN;c.beginPath();c.ellipse(100,224,12,13,.2,0,T);c.fill();c.stroke()
for(const[x,d,col,o]of[[18,1,'#ff8fab',0],[238,-1,'#66d9e8',2.2]]){
const r=d*(.45+.3*sin(2*a+o)),ex=x+sin(r)*80,ey=270-cos(r)*80,hx=x+sin(r)*22,hy=270-cos(r)*22
for(const[l,k]of[[20,'#111'],[13,col],[5,'#fff']])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),c.moveTo(hx,hy),c.lineTo(ex,ey),c.stroke()
ds(c,20,13,'#868e96',()=>{c.moveTo(x,270);c.lineTo(hx,hy)})
}
}
+50
View File
@@ -0,0 +1,50 @@
// girl with peach double buns hugging a gray tabby kitten to her cheek, both nuzzling, the kitten purring and kneading while hearts float up
const{sin,cos,PI}=Math,T=2*PI
export const frames=16,delay=80
const SKIN='#ffe3d1',HAIR='#ffb4a2',HD='#f08c7a',HL='#ffe3dc',SW='#b2f2bb',SWD='#69db7c',CAT='#adb5bd',CD='#868e96',CW='#f8f9fa',PINK='#ff8fab',BL='#ffa8a8',HT='#f06595'
const heart=(c,x,y,s)=>{c.save();c.translate(x,y);c.scale(s,s);c.beginPath();c.moveTo(0,8);c.bezierCurveTo(-13,-1,-9,-12,0,-5);c.bezierCurveTo(9,-12,13,-1,0,8);c.restore();c.fill();c.stroke()}
const line=(c,pts,w,col)=>{for(const[lw,s]of[[w+8,'#111'],[w,col]]){c.lineWidth=lw;c.strokeStyle=s;c.beginPath();pts.forEach(([x,y],k)=>k?c.lineTo(x,y):c.moveTo(x,y));c.stroke()}c.strokeStyle='#111'}
export default(c,t)=>{
const n=sin(2*T*t),tilt=.12+.05*n
c.fillStyle=HT;c.lineWidth=4;for(const[x0,o]of[[150,0],[200,.5]]){const p=(t+o)%1,s=1.3*sin(PI*p);if(s>.15)heart(c,x0+8*sin(p*T),96-p*80,s)}
c.lineWidth=6;c.fillStyle=SW;c.beginPath();c.moveTo(60,214);c.quadraticCurveTo(30,222,24,260);c.lineTo(200,260);c.quadraticCurveTo(190,224,150,214);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(82,212);c.quadraticCurveTo(104,236,128,212);c.lineTo(104,206);c.closePath();c.fill();c.lineWidth=5;c.stroke()
c.save();c.translate(104,200);c.rotate(tilt);c.translate(-104,-200)
c.save();c.translate(104,138);c.scale(.95,.95);c.translate(-128,-128)
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(196,34,208,96,200,150);c.lineTo(56,150);c.bezierCurveTo(48,96,60,34,128,34);c.fill();c.stroke()
for(const d of[-1,1]){const x=128+d*42;c.fillStyle=HAIR;c.beginPath();c.arc(x,34,22,0,T);c.fill();c.stroke();c.strokeStyle=HD;c.lineWidth=4;c.beginPath();c.arc(x,34,12,PI*.2,PI*1.5);c.arc(x+2,32,5,PI*1.5,PI*3,false);c.stroke();c.strokeStyle='#111';c.lineWidth=5;c.fillStyle=SWD;c.beginPath();c.ellipse(x-d*6,56,12,6,-d*.5,0,T);c.fill();c.stroke();c.lineWidth=6}
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
c.lineWidth=6;for(const x of[103,153])c.beginPath(),c.moveTo(x-15,146),c.quadraticCurveTo(x,128,x+15,146),c.stroke()
for(const x of[103,153])c.beginPath(),c.moveTo(x+(x<128?-15:15),146),c.lineTo(x+(x<128?-20:20),142),c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,163,14,7,0,0,T),c.fill()
c.lineWidth=2.5;for(const d of[-1,1])for(const k of[-6,0,6])c.beginPath(),c.moveTo(128+d*42+k-2,166),c.lineTo(128+d*42+k+2,159),c.stroke()
c.lineWidth=3.5;c.fillStyle='#c92a2a';c.beginPath();c.moveTo(116,166);c.quadraticCurveTo(128,184,140,166);c.closePath();c.fill();c.stroke()
c.save();c.clip();c.fillStyle=PINK;c.beginPath();c.ellipse(128,180,8,5,0,0,T);c.fill();c.restore()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(68,150)
c.bezierCurveTo(50,74,88,36,128,36);c.bezierCurveTo(168,36,206,74,188,150)
c.quadraticCurveTo(186,118,178,104);c.quadraticCurveTo(170,100,164,110);c.quadraticCurveTo(156,96,146,92);c.quadraticCurveTo(140,104,132,110)
c.quadraticCurveTo(126,96,118,92);c.quadraticCurveTo(112,104,104,110);c.quadraticCurveTo(96,96,88,96);c.quadraticCurveTo(82,104,80,110);c.quadraticCurveTo(70,118,68,150);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke()
c.strokeStyle='#111';c.restore();c.restore()
c.save();c.translate(210,200);c.rotate(.35*sin(T*t+1))
for(const[w,col]of[[18,'#111'],[10,CAT]])c.lineWidth=w,c.strokeStyle=col,c.beginPath(),c.moveTo(0,0),c.bezierCurveTo(26,-6,30,-40,14,-56),c.stroke()
c.strokeStyle=CD;c.lineWidth=10;c.beginPath();c.moveTo(18,-18);c.lineTo(22,-26);c.moveTo(22,-40);c.lineTo(19,-47);c.stroke();c.strokeStyle='#111';c.restore()
c.fillStyle=CAT;c.lineWidth=5;c.beginPath();c.ellipse(186,200,30,28,-.2,0,T);c.fill();c.stroke()
c.fillStyle=CW;c.beginPath();c.ellipse(180,208,15,17,-.2,0,T);c.fill()
c.save();c.translate(178,150);c.rotate(-.18-.08*n);c.translate(3*n,0);c.scale(1.12,1.12)
c.fillStyle=CAT;c.lineWidth=5;for(const d of[-1,1])c.beginPath(),c.moveTo(d*12,-22),c.lineTo(d*26,-40+(d>0?2*n:0)),c.lineTo(d*30,-10),c.closePath(),c.fill(),c.stroke()
c.fillStyle=PINK;for(const d of[-1,1])c.beginPath(),c.moveTo(d*16,-20),c.lineTo(d*25,-32),c.lineTo(d*26,-14),c.closePath(),c.fill()
c.fillStyle=CAT;c.beginPath();c.ellipse(0,0,34,28,0,0,T);c.fill();c.stroke()
c.save();c.clip();c.fillStyle=CD;for(const x of[-9,0,9])c.beginPath(),c.moveTo(x-4,-30),c.lineTo(x,-16),c.lineTo(x+4,-30),c.fill()
c.fillStyle=CW;c.beginPath();c.ellipse(0,14,18,13,0,0,T);c.fill();c.restore()
c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.moveTo(d*20,0),c.quadraticCurveTo(d*13,-7,d*6,0),c.stroke()
c.fillStyle=PINK;c.lineWidth=2.5;c.beginPath();c.moveTo(-4,6);c.lineTo(4,6);c.lineTo(0,10);c.closePath();c.fill();c.stroke()
c.lineWidth=3;c.beginPath();c.moveTo(0,10);c.quadraticCurveTo(-3,15,-7,12);c.moveTo(0,10);c.quadraticCurveTo(3,15,7,12);c.stroke()
c.lineWidth=2;c.beginPath();for(const d of[-1,1])for(const y of[8,13])c.moveTo(d*14,y),c.lineTo(d*30,y+(y-10)*1.4);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(d*20,10,5,3,0,0,T),c.fill()
c.restore()
for(const[k,x]of[[0,152],[1,166]]){const y=170+5*sin(4*T*t+k*PI);c.fillStyle=CW;c.lineWidth=4;c.beginPath();c.ellipse(x,y,8,7,0,0,T);c.fill();c.stroke();c.lineWidth=2;c.beginPath();c.moveTo(x-2,y-6);c.lineTo(x-2,y-2);c.moveTo(x+2,y-6);c.lineTo(x+2,y-2);c.stroke()}
line(c,[[70,240],[124,222],[148,206]],12,SW);c.fillStyle=SKIN;c.lineWidth=4;c.beginPath();c.ellipse(156,204,11,10,-.4,0,T);c.fill();c.stroke()
line(c,[[194,256],[214,232],[212,216]],12,SW);c.fillStyle=SKIN;c.lineWidth=4;c.beginPath();c.ellipse(210,210,10,11,.3,0,T);c.fill();c.stroke()
c.lineWidth=4;for(const k of[0,1]){if(sin(4*T*t+k*PI)>0)for(const r of[k?20:12])c.beginPath(),c.arc(212,140,r+8,-.55,.55),c.stroke()}
}
+53
View File
@@ -0,0 +1,53 @@
// plum-haired girl tucked into a kotatsu peeling a mikan strip by strip, tea steaming beside her
const{sin,cos,PI,max,min}=Math,T=2*PI
export const frames=20,delay=80
const SKIN='#ffe3d1',HAIR='#be4bdb',HD='#862e9c',HL='#f3d9fa',EYE='#fcc419',ED='#e67700',SW='#96f2d7',SD='#38d9a9',WOOD='#d9a066',WD='#a9744f',QU='#ff8787',QD='#fa5252',MI='#ff922b',MD='#e8590c',PITH='#ffe8cc',BL='#ffa8a8',Z=.74
const cl=x=>max(0,min(1,x)),ease=x=>x*x*(3-2*x)
const eye=(c,x,y,d,bl)=>{
c.lineWidth=7;c.beginPath();c.moveTo(x-17,y-4);c.quadraticCurveTo(x,bl?y+4:y+10,x+17,y-4);c.moveTo(x+d*16,y-4);c.lineTo(x+d*23,y-9);c.stroke()
if(!bl)for(const k of[-8,0,8])c.lineWidth=4,c.beginPath(),c.moveTo(x+k,y+(k?5:7)),c.lineTo(x+k*1.3,y+(k?11:13)),c.stroke()
}
export default(c,t)=>{
const mx=128,my=176,r=27,pa=cl(t/.55),pb=cl((t-.55)/.15),pc=ease(cl((t-.55)/.45))
const E=pa<1?[mx+14+34*pa,my-r-6+40*pa]:[mx+48-34*pc,my+6-(r+12)*pc]
c.save();c.translate(128,152);c.scale(Z,Z);c.translate(-128,-186)
c.lineWidth=7;c.fillStyle=HAIR;c.beginPath();c.arc(128,40,30,0,T);c.fill();c.stroke()
c.strokeStyle=HD;c.lineWidth=4;c.beginPath();c.arc(128,40,18,PI*.9,PI*2.1);c.stroke();c.beginPath();c.arc(124,46,10,PI*1.1,PI*2.2);c.stroke()
for(const[l,s]of[[11,'#111'],[5,WD]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(92,22),c.lineTo(168,52),c.stroke()
c.strokeStyle='#111';c.lineWidth=7;c.fillStyle=HAIR;c.beginPath();c.moveTo(128,50);c.bezierCurveTo(60,50,56,120,66,176);c.quadraticCurveTo(78,180,84,160);c.lineTo(172,160);c.quadraticCurveTo(178,180,190,176);c.bezierCurveTo(200,120,196,50,128,50);c.fill();c.stroke()
c.fillStyle=SW;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(58,196,44,250);c.lineTo(212,250);c.quadraticCurveTo(198,196,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.rect(116,168,24,26);c.fill();c.beginPath();c.moveTo(116,168);c.lineTo(116,190);c.moveTo(140,168);c.lineTo(140,190);c.stroke()
c.fillStyle=SW;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(128,204,156,190);c.lineTo(156,200);c.quadraticCurveTo(128,214,100,200);c.closePath();c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
const bl=t>=.8&&t<.85
eye(c,103,140,-1,bl);eye(c,153,140,1,bl)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,160,13,7,0,0,T),c.fill()
c.lineWidth=4;c.beginPath();c.moveTo(118,166);c.quadraticCurveTo(123,172,128,166);c.quadraticCurveTo(133,172,138,166);c.stroke()
c.lineWidth=7;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,140)
c.bezierCurveTo(54,74,88,46,128,46);c.bezierCurveTo(168,46,202,74,186,140)
c.quadraticCurveTo(182,112,170,100);c.quadraticCurveTo(162,108,158,116);c.quadraticCurveTo(152,98,138,92);c.quadraticCurveTo(132,104,126,112)
c.quadraticCurveTo(118,96,104,94);c.quadraticCurveTo(98,106,96,116);c.quadraticCurveTo(90,104,84,102);c.quadraticCurveTo(72,116,70,140);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.28,1.4],[1.48,1.56],[1.64,1.74]])c.beginPath(),c.arc(128,104,50,PI*a,PI*e),c.stroke()
c.strokeStyle='#111';c.restore()
c.lineWidth=6;c.fillStyle=QU;c.beginPath();c.moveTo(22,196);c.quadraticCurveTo(8,226,6,248);c.quadraticCurveTo(68,240,128,248);c.quadraticCurveTo(188,240,250,248);c.quadraticCurveTo(248,226,234,196);c.closePath();c.fill();c.stroke()
c.save();c.clip();c.fillStyle=QD;for(let x=-2;x<9;x++)for(let y=0;y<2;y++)c.beginPath(),c.arc(18+x*30+(y%2)*15,220+y*20,5,0,T),c.fill();c.restore()
c.fillStyle=WOOD;c.beginPath();c.moveTo(40,170);c.lineTo(216,170);c.lineTo(240,198);c.lineTo(16,198);c.closePath();c.fill();c.stroke()
c.fillStyle=WD;c.beginPath();c.rect(16,198,224,9);c.fill();c.stroke()
c.fillStyle=MI;c.lineWidth=4;for(let k=0;k<5;k++){const a=k*T/5+.3,px=202,py=186;c.beginPath();c.moveTo(px,py);c.quadraticCurveTo(px+cos(a-.6)*22,py+sin(a-.6)*11,px+cos(a)*24,py+sin(a)*12);c.quadraticCurveTo(px+cos(a+.6)*22,py+sin(a+.6)*11,px,py);c.fill();c.stroke()}
c.fillStyle=PITH;c.beginPath();c.ellipse(202,186,7,4,0,0,T);c.fill();c.stroke()
for(const k of[0,1]){const p=(t*2+k*.5)%1,y=164-p*36,w=sin(PI*p);if(w>.2)for(const[l,s]of[[4+5*w,'#111'],[4*w,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(56+k*10,y),c.quadraticCurveTo(56+k*10+6*sin(p*T+k*3),y-8,56+k*10-5*sin(p*T),y-16),c.stroke()}
c.strokeStyle='#111';c.lineWidth=5;c.fillStyle='#fff9db';c.beginPath();c.moveTo(48,170);c.lineTo(50,192);c.quadraticCurveTo(60,198,70,192);c.lineTo(72,170);c.quadraticCurveTo(60,176,48,170);c.fill();c.stroke()
c.fillStyle='#69db7c';c.beginPath();c.ellipse(60,170,12,4,0,0,T);c.fill();c.stroke()
c.strokeStyle='#4dabf7';c.lineWidth=3;c.beginPath();c.moveTo(50,182);c.quadraticCurveTo(60,187,71,182);c.stroke();c.strokeStyle='#111'
for(const[a,b]of[[[92,166],[mx-r-4,my+6]],[[164,166],E]])for(const[l,s]of[[26,'#111'],[15,SW]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(...a),c.quadraticCurveTo(a[0],b[1],(a[0]+b[0]*2)/3,(a[1]+b[1]*2)/3+4),c.stroke()
c.strokeStyle='#111'
c.lineWidth=5;c.fillStyle=MI;c.beginPath();c.arc(mx,my,r,0,T);c.fill();c.stroke()
c.save();c.beginPath();c.arc(mx,my,r-2.5,0,T);c.clip();const sh=48*pc,len=2*r*(pa<1?pa:1)*.9
if(len>2){c.fillStyle=PITH;c.beginPath();c.roundRect(mx-8+sh,my-r-4,20,len+4,8);c.fill();c.strokeStyle='#ffc078';c.lineWidth=2.5;c.beginPath();c.moveTo(mx+2+sh,my-r);c.lineTo(mx+2+sh,my-r+len);c.stroke()}
c.fillStyle=MD;for(const[x,y]of[[-13,5],[10,13],[-5,-10],[15,-6],[-17,-8],[0,16],[16,6]])if(!(len>2&&x+mx>mx-10+sh&&x+mx<mx+14+sh))c.beginPath(),c.arc(mx+x,my+y,1.6,0,T),c.fill()
c.restore();c.strokeStyle='#111';c.lineWidth=4;c.fillStyle='#51cf66';c.beginPath();c.ellipse(mx-7,my-r-2,10,5,-.4,0,T);c.fill();c.stroke()
if(pb<1&&t>.02){const[ex,ey]=pa<1?E:[mx+48+(200-mx-48)*pb,my+6+(184-my-6)*pb],[ax,ay]=pa<1?[mx+3,my-r+3]:[ex-34*(1-pb),ey-10*(1-pb)],s=1-pb*.5;for(const[l,st]of[[16*s,'#111'],[8*s,MI]])c.lineWidth=l,c.strokeStyle=st,c.beginPath(),c.moveTo(ax,ay),c.quadraticCurveTo((ax+ex)/2+16,(ay+ey)/2-14,ex,ey),c.stroke()}
c.strokeStyle='#111';c.lineWidth=5;c.fillStyle=SKIN
c.beginPath();c.ellipse(mx-r-4,my+6,10,11,0,0,T);c.fill();c.stroke()
c.beginPath();c.ellipse(E[0]+2,E[1]+2,10,9,0,0,T);c.fill();c.stroke()
}
+40
View File
@@ -0,0 +1,40 @@
// chestnut-haired schoolgirl confessing with her head bowed and eyes squeezed shut, holding out a trembling love letter sealed with a heart
const{sin,PI,max}=Math,T=2*PI
export const frames=16,delay=70
const SKIN='#ffe3d1',HAIR='#b5703f',HD='#8a4f2a',HL='#ecc19a',BOW='#fa5252',UNI='#4c6ef5',BL='#ff8fab',HT='#f03e3e',PAPER='#fff9db'
const heart=(c,x,y,s)=>{c.save();c.translate(x,y);c.scale(s,s);c.beginPath();c.moveTo(0,8);c.bezierCurveTo(-13,-1,-9,-12,0,-5);c.bezierCurveTo(9,-12,13,-1,0,8);c.restore();c.fill();c.stroke()}
export default(c,t,i)=>{
const j=i%2?1.5:-1.5,bl=1+.15*sin(2*T*t),p=1+.3*max(0,sin(4*T*t))
c.lineWidth=6
c.fillStyle=HD;c.beginPath();c.moveTo(128,46);c.bezierCurveTo(204,46,214,124,208,214);c.lineTo(48,214);c.bezierCurveTo(42,124,52,46,128,46);c.fill();c.stroke()
c.fillStyle=UNI;c.beginPath();c.moveTo(100,196);c.quadraticCurveTo(62,204,54,250);c.lineTo(202,250);c.quadraticCurveTo(194,204,156,196);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(100,196);c.quadraticCurveTo(80,200,74,214);c.lineTo(128,226);c.lineTo(182,214);c.quadraticCurveTo(176,200,156,196);c.closePath();c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,176);c.lineTo(116,198);c.lineTo(128,212);c.lineTo(140,198);c.lineTo(140,176);c.fill();c.lineWidth=5;c.stroke()
c.save();c.translate(0,8);c.lineWidth=6
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
c.lineWidth=5.5;c.beginPath();c.moveTo(91,131);c.lineTo(113,140);c.lineTo(91,149);c.moveTo(165,131);c.lineTo(143,140);c.lineTo(165,149);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,158,15*bl,8*bl,0,0,T),c.fill()
c.lineWidth=2.5;for(const d of[-1,1])for(const k of[-8,-3,2,7])c.beginPath(),c.moveTo(128+d*42+k-2,162),c.lineTo(128+d*42+k+2,154),c.stroke()
c.lineWidth=3.5;c.beginPath();c.moveTo(119,170);for(let k=1;k<=6;k++)c.lineTo(119+k*3,k%2?173:169);c.stroke()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(68,156)
c.bezierCurveTo(52,78,88,46,128,46);c.bezierCurveTo(168,46,204,78,188,156)
c.quadraticCurveTo(186,120,178,104);c.quadraticCurveTo(168,104,160,114);c.quadraticCurveTo(156,98,146,92);c.quadraticCurveTo(138,106,128,112)
c.quadraticCurveTo(126,96,116,88);c.quadraticCurveTo(108,104,98,110);c.quadraticCurveTo(94,98,88,96);c.quadraticCurveTo(82,106,80,114)
c.quadraticCurveTo(70,128,68,156);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle=BOW;c.lineWidth=5
for(const d of[-1,1])c.beginPath(),c.moveTo(128,46),c.quadraticCurveTo(128+d*14,24,128+d*32,32),c.quadraticCurveTo(128+d*34,52,128,46),c.fill(),c.stroke()
c.beginPath();c.ellipse(128,46,7,8,0,0,T);c.fill();c.stroke()
c.restore()
for(const d of[-1,1])for(const[l,s]of[[30,'#111'],[19,UNI]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(128+d*76,252),c.lineTo(128+d*60+j,216),c.stroke()
c.strokeStyle='#111'
c.save();c.translate(j,0)
c.lineWidth=6;c.fillStyle=PAPER;c.beginPath();c.roundRect(68,186,120,62,6);c.fill();c.stroke()
c.lineWidth=4;c.beginPath();c.moveTo(72,190);c.lineTo(128,220);c.lineTo(184,190);c.stroke()
c.fillStyle=HT;heart(c,128,222,1.5)
c.lineWidth=5;c.fillStyle=SKIN;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*60,212,12,15,0,0,T),c.fill(),c.stroke(),c.beginPath(),c.ellipse(128+d*50,202,6,9,-d*.4,0,T),c.fill(),c.stroke()
c.restore()
for(const[l,s]of[[8,'#111'],[3.5,'#fff']]){c.lineWidth=l;c.strokeStyle=s;for(const d of[-1,1])for(const k of[0,1])c.beginPath(),c.arc(128+d*(80+k*8)+j,210,10+k*5,d<0?PI*.75:-PI*.25,d<0?PI*1.25:PI*.25),c.stroke()}
c.strokeStyle='#111';c.lineWidth=4;c.fillStyle=HT;heart(c,222,62,1.5*p)
c.fillStyle='#ff8fab';for(const[x0,o]of[[228,0],[28,.5]]){const q=(t+o)%1,s=1.1*sin(PI*q);if(s>.15)heart(c,x0+6*sin(q*T*2),186-q*90,s)}
}
+55
View File
@@ -0,0 +1,55 @@
// café maid with slate twin buns doing "moe moe kyun": heart hands wiggle, then a pink heart beam zaps the omurice's ketchup heart
const{sin,cos,PI,max}=Math,T=2*PI
export const frames=20,delay=80
const SKIN='#ffe3d1',HAIR='#c9a27e',HD='#9c7650',HL='#f0dfc8',EYE='#f03e3e',ED='#a51111',DRESS='#f783ac',BOW='#e03131',BL='#ffa8a8',MO='#c92a2a',TG='#ff8fab',BEAM='#f06595',EGG='#ffd43b',KET='#e03131',RIM='#74c0fc'
const ease=x=>x<=0?0:x>=1?1:x*x*(3-2*x)
const hp=(c,x,y,s)=>{c.save();c.translate(x,y);c.scale(s,s);c.beginPath();c.moveTo(0,8);c.bezierCurveTo(-13,-1,-9,-12,0,-5);c.bezierCurveTo(9,-12,13,-1,0,8);c.restore()}
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2,0,T);c.fill()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const spark=(c,x,y,r)=>{c.beginPath();c.moveTo(x,y-r);for(const[px,py,qx,qy]of[[r,0,r*.18,-r*.18],[0,r,r*.18,r*.18],[-r,0,-r*.18,r*.18],[0,-r,-r*.18,-r*.18]])c.quadraticCurveTo(x+qx,y+qy,x+px,y+py);c.fill();c.stroke()}
export default(c,t)=>{
const k=ease((t-.35)/.08)-ease((t-.7)/.1),wg=t<.35?5*sin(2*T*t/.35):0,ky=k>.5,hx=124+wg+8*k,hy=196+4*k,hs=1.9+.25*k
const hit=t>=.58&&t<.9,kp=hit?1+.35*sin(PI*(t-.58)/.32):1
c.save();c.translate(-14,0)
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,36);c.bezierCurveTo(198,36,212,110,206,214);c.quadraticCurveTo(196,224,184,214);c.lineTo(72,214);c.quadraticCurveTo(60,224,50,214);c.bezierCurveTo(44,110,58,36,128,36);c.fill();c.stroke()
c.fillStyle=DRESS;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(62,198,54,256);c.lineTo(202,256);c.quadraticCurveTo(194,198,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(102,256);c.lineTo(106,204);c.quadraticCurveTo(128,212,150,204);c.lineTo(154,256);c.fill();c.stroke()
c.fillStyle=DRESS;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*46,206,19,15,d*.4,0,T),c.fill(),c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,168);c.lineTo(116,194);c.quadraticCurveTo(128,204,140,194);c.lineTo(140,168);c.fill();c.lineWidth=5;c.beginPath();c.moveTo(116,168);c.lineTo(116,192);c.moveTo(140,168);c.lineTo(140,192);c.stroke()
c.fillStyle=BOW;for(const d of[-1,1])c.beginPath(),c.moveTo(128,200),c.lineTo(128+d*16,192),c.lineTo(128+d*16,208),c.closePath(),c.fill(),c.stroke()
c.beginPath();c.arc(128,200,5,0,T);c.fill();c.stroke()
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
eye(c,103,140,-1)
if(ky){c.lineWidth=5;c.beginPath();c.moveTo(166,130);c.lineTo(146,141);c.lineTo(166,151);c.stroke()}else eye(c,153,140,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,161,12,6,0,0,T),c.fill()
c.lineWidth=2.5;for(const d of[-1,1])for(const j of[-5,0,5])c.beginPath(),c.moveTo(128+d*42+j-2,164),c.lineTo(128+d*42+j+2,158),c.stroke()
c.lineWidth=3.5;c.fillStyle=MO;c.beginPath();c.moveTo(119,165);c.quadraticCurveTo(128,(ky?184:177),137,165);c.closePath();c.fill();c.stroke()
c.save();c.clip();c.fillStyle=TG;c.beginPath();c.ellipse(128,ky?180:175,6,4,0,0,T);c.fill();c.restore()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(68,154)
c.bezierCurveTo(52,76,88,40,128,40);c.bezierCurveTo(168,40,204,76,188,154)
c.quadraticCurveTo(186,118,178,104);c.quadraticCurveTo(170,102,164,110);c.quadraticCurveTo(158,96,148,92);c.quadraticCurveTo(142,104,134,110)
c.quadraticCurveTo(130,98,122,92);c.quadraticCurveTo(116,104,106,110);c.quadraticCurveTo(102,98,94,96);c.quadraticCurveTo(88,104,82,112)
c.quadraticCurveTo(70,126,68,154);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.28,1.38],[1.62,1.72]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle='#fff';c.lineWidth=4
for(let j=0;j<7;j++){const a=PI*(1.2+j*.6/6);c.beginPath();c.arc(128+cos(a)*64,108+sin(a)*64,8,0,T);c.fill();c.stroke()}
for(const[l,s]of[[20,'#111'],[12,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.arc(128,108,58,PI*1.18,PI*1.82),c.stroke()
c.strokeStyle='#111'
for(const[x,y]of[[76,256],[180,256]])for(const[l,s]of[[24,'#111'],[14,SKIN]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(x,y),c.lineTo(hx+(x<128?-14:14)+14,hy+12),c.stroke()
c.strokeStyle='#111';c.restore()
for(const[l,s]of[[16,'#111'],[9,SKIN]])c.lineWidth=l,c.strokeStyle=s,hp(c,hx,hy,hs),c.stroke()
c.strokeStyle='#111'
const ox=206,oy=228
c.lineWidth=6;c.fillStyle='#fff';c.beginPath();c.ellipse(ox,oy+6,46,15,0,0,T);c.fill();c.stroke()
c.strokeStyle=RIM;c.lineWidth=3;c.beginPath();c.ellipse(ox,oy+6,38,10,0,0,T);c.stroke();c.strokeStyle='#111'
c.lineWidth=6;c.fillStyle=EGG;c.beginPath();c.moveTo(ox-36,oy+6);c.bezierCurveTo(ox-34,oy-26,ox+34,oy-26,ox+36,oy+6);c.quadraticCurveTo(ox,oy+14,ox-36,oy+6);c.fill();c.stroke()
c.fillStyle=KET;c.lineWidth=3.5;hp(c,ox,oy-7,.95*kp);c.fill();c.stroke()
if(t>=.4&&t<.66){const p=(t-.4)/.26;c.fillStyle=BEAM;c.lineWidth=4;for(let j=0;j<3;j++){const q=p*1.3-j*.15;if(q>0&&q<1){const x=hx+20+(ox-hx-20)*q,y=hy-2+(oy-14-hy+2)*q;hp(c,x,y,1.2+.6*q);c.fill();c.stroke();c.fillStyle='#fff';c.beginPath();c.arc(x-5*(1.2+.6*q),y-3*(1.2+.6*q),2.5,0,T);c.fill();c.fillStyle=BEAM}}}
if(hit){c.fillStyle='#fff3bf';c.lineWidth=3.5;for(const[x,y,o]of[[176,196,0],[238,198,.33],[210,182,.66]]){const s=sin(PI*(((t-.58)/.32*2+o)%1));if(s>.1)spark(c,x,y,11*s)}}
}
+56
View File
@@ -0,0 +1,56 @@
// red haired girl sprawled over a manga, eyes following the panels, flipping a page and gasping at every turn
const{sin,cos,PI,min}=Math,T=2*PI
export const frames=16,delay=90
const SKIN='#ffe3d1',HAIR='#a68a7b',HD='#7d6355',HL='#e6d5cc',EYE='#20c997',ED='#087f5b',BL='#ffa8a8',TEE='#fff',STR='#74c0fc',COV='#ffd43b',INK='#495057'
const ds=(c,a,b,s,f)=>{for(const[l,k]of[[a,'#111'],[b,s]])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),f(),c.stroke();c.strokeStyle='#111'}
const eye=(c,x,y,d,g,lx)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,g?18:15,0,0,T);c.fill()
c.save();c.clip()
if(g){c.fillStyle=EYE;c.beginPath();c.arc(x,y,6,0,T);c.fill();c.lineWidth=2.5;c.stroke();c.fillStyle='#111';c.beginPath();c.arc(x,y,2.5,0,T);c.fill()}
else{c.beginPath();c.ellipse(x+lx,y+6,11.5,14,0,0,T);c.fillStyle=EYE;c.fill();c.lineWidth=2.5;c.stroke();c.save();c.clip();c.fillStyle=ED;c.beginPath();c.ellipse(x+lx,y-3,14,8,0,0,T);c.fill();c.restore();c.fillStyle='#111';c.beginPath();c.ellipse(x+lx,y+8,5.5,7,0,0,T);c.fill();c.fillStyle='#fff';c.beginPath();c.arc(x+lx-4,y+2,4,0,T);c.fill()}
c.restore()
c.lineWidth=7;c.beginPath();c.moveTo(x-16,y-(g?8:4));c.quadraticCurveTo(x,y-(g?24:14),x+16,y-(g?8:4));c.moveTo(x+d*15,y-(g?9:5));c.lineTo(x+d*21,y-(g?14:10));c.stroke()
}
const panels=(c,a,b,cc,d)=>{ // a,b: spine far/near, cc,d: outer far/near corner
const L=(p,q,s)=>[p[0]+(q[0]-p[0])*s,p[1]+(q[1]-p[1])*s],Q=(u,v)=>L(L(a,cc,u),L(b,d,u),v)
c.strokeStyle=INK;c.lineWidth=2;c.beginPath()
for(const[u0,v0,u1,v1]of[[.12,.1,.88,.42],[.12,.52,.46,.9],[.56,.52,.88,.9]]){for(const[u,v]of[[u0,v0],[u1,v0],[u1,v1],[u0,v1],[u0,v0]])c.lineTo(...Q(u,v));c.moveTo(...Q(u0,v0))}
c.stroke();c.strokeStyle='#111'
}
export default(c,t)=>{
const a=t*T,u=(t*2)%1,fl=u<.375,g=u>=.375&&u<.625,ph=fl?PI*min(1,u/.3):0,lx=g||fl?0:-5+10*((u-.625)/.375)
c.lineWidth=6;c.fillStyle=TEE;c.beginPath();c.moveTo(66,200);c.quadraticCurveTo(64,152,100,146);c.lineTo(156,146);c.quadraticCurveTo(192,152,190,200);c.closePath();c.fill();c.stroke()
c.save();c.clip();c.strokeStyle=STR;c.lineWidth=6;c.beginPath();for(let y=156;y<200;y+=13)c.moveTo(60,y),c.lineTo(196,y);c.stroke();c.restore()
c.beginPath();c.moveTo(66,200);c.quadraticCurveTo(64,152,100,146);c.lineTo(156,146);c.quadraticCurveTo(192,152,190,200);c.lineWidth=6;c.stroke()
for(const d of[-1,1])ds(c,22,14,TEE,()=>{c.moveTo(128+d*52,166);c.lineTo(128+d*86,206)})
c.save();c.translate(128,174);c.scale(.78,.78);c.translate(-128,-186)
c.lineWidth=7;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(198,34,210,96,200,146);c.quadraticCurveTo(212,154,216,168);c.quadraticCurveTo(196,168,186,156);c.lineTo(70,156);c.quadraticCurveTo(60,168,40,168);c.quadraticCurveTo(44,154,56,146);c.bezierCurveTo(46,96,58,34,128,34);c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
eye(c,103,140,-1,g,lx);eye(c,153,140,1,g,lx)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,162,13,7,0,0,T),c.fill()
c.lineWidth=2.5;for(const d of[-1,1])for(const k of[-5,0,5])c.beginPath(),c.moveTo(128+d*44+k-2,165),c.lineTo(128+d*44+k+2,159),c.stroke()
c.lineWidth=4.5;c.fillStyle='#c92a2a';c.beginPath()
if(g)c.ellipse(128,170,7,9,0,0,T),c.fill(),c.stroke();else c.moveTo(121,167),c.quadraticCurveTo(128,173,135,167),c.stroke()
c.lineWidth=7;c.fillStyle=HAIR;c.beginPath();c.moveTo(66,160)
c.bezierCurveTo(50,80,88,36,128,36);c.bezierCurveTo(168,36,206,80,190,160)
c.quadraticCurveTo(188,124,180,106);c.quadraticCurveTo(170,108,162,100);c.quadraticCurveTo(156,90,144,88);c.quadraticCurveTo(144,102,136,108)
c.quadraticCurveTo(128,100,124,90);c.quadraticCurveTo(116,104,104,108);c.quadraticCurveTo(102,98,94,92);c.quadraticCurveTo(88,104,78,108)
c.quadraticCurveTo(68,126,66,160);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=6;for(const[s,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*s,PI*e),c.stroke()
for(const r of[.5,-.5])ds(c,12,6,'#ffd43b',()=>{c.moveTo(66+10*r,82-16*r);c.lineTo(86-10*r,72+16*r)})
c.restore()
if(g){const s=1+.3*sin(PI*(u-.375)/.25);ds(c,13*s,7*s,'#ffd43b',()=>{c.moveTo(128,16);c.lineTo(128,34+4*s)});c.fillStyle='#ffd43b';c.lineWidth=4;c.beginPath();c.arc(128,47+4*s,4.5*s,0,T);c.fill();c.stroke()
for(const d of[-1,1])ds(c,7,3,'#fff',()=>{c.moveTo(128+d*22,26);c.lineTo(128+d*32,16)})}
const sf=[128,186],sn=[128,240],Rf=[184,186],Rn=[208,240],Lf=[72,186],Ln=[48,240]
c.fillStyle=COV;c.lineWidth=6;c.beginPath();c.moveTo(66,182);c.lineTo(190,182);c.lineTo(216,246);c.lineTo(40,246);c.closePath();c.fill();c.stroke()
for(const[f,n]of[[Lf,Ln],[Rf,Rn]]){c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.moveTo(...sf);c.lineTo(...f);c.lineTo(...n);c.lineTo(...sn);c.closePath();c.fill();c.stroke();panels(c,sf,sn,f,n)}
if(fl){
const cf=[128+56*cos(ph),186-34*sin(ph)],cn=[128+80*cos(ph),240-48*sin(ph)],lag=.35*sin(ph),bf=[128+56*cos(ph-lag)*.6,186-34*sin(ph-lag)*.6],bn=[128+80*cos(ph-lag)*.6,240-48*sin(ph-lag)*.6]
c.fillStyle='#f8f9fa';c.lineWidth=4;c.beginPath();c.moveTo(...sf);c.quadraticCurveTo(...bf,...cf);c.lineTo(...cn);c.quadraticCurveTo(...bn,...sn);c.closePath();c.fill();c.stroke()
if(ph<PI/2)panels(c,sf,sn,cf,cn)
for(const d of[0,1])ds(c,6,2.5,'#fff',()=>{c.moveTo(cn[0]+18-d*6,cn[1]-20+d*14);c.lineTo(cn[0]+28-d*6,cn[1]-26+d*14)})
}
const hr=fl&&ph<PI/2?[128+80*cos(ph)+6,240-48*sin(ph)-4]:[202,232]
ds(c,20,13,SKIN,()=>{c.moveTo(42,206);c.lineTo(56,232)});ds(c,20,13,SKIN,()=>{c.moveTo(214,206);c.lineTo(...hr)})
c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(56,234,9,9,0,0,T);c.fill();c.stroke();c.beginPath();c.ellipse(hr[0],hr[1]+2,9,9,0,0,T);c.fill();c.stroke()
}
+52
View File
@@ -0,0 +1,52 @@
// hime-cut girl with slate hair pushes her red glasses up with one finger, the lenses flash white and a glint star pops
const{sin,cos,PI,max,min}=Math,T=2*PI
export const frames=16,delay=80
const SKIN='#ffe3d1',HAIR='#5c636a',HD='#495057',HL='#ced4da',EYE='#f59f00',ED='#d9480f',VEST='#e9d8a6',RIB='#e03131',FR='#e03131',BL='#ffa8a8'
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2,0,T);c.fill()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
c.lineWidth=2.5;c.beginPath();c.moveTo(x-8,y+18);c.lineTo(x+8,y+18);c.stroke()
}
const glint=(c,x,y,r,a)=>{c.save();c.translate(x,y);c.rotate(a);c.beginPath();for(let k=0;k<8;k++){const rr=k%2?r*.28:r,b=k*PI/4;c.lineTo(cos(b)*rr,sin(b)*rr)}c.closePath();c.restore();c.fill();c.stroke()}
const ez=(t,a,b)=>{const x=min(1,max(0,(t-a)/(b-a)));return x*x*(3-2*x)}
export default(c,t)=>{
const r=ez(t,.15,.35)-ez(t,.8,.97),gy=-5*(ez(t,.35,.45)-ez(t,.8,.9)),fl=t>=.45&&t<.82
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(198,34,212,96,206,150);c.lineTo(210,256);c.lineTo(46,256);c.lineTo(50,150);c.bezierCurveTo(44,96,58,34,128,34);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(100,188);c.quadraticCurveTo(62,196,54,256);c.lineTo(202,256);c.quadraticCurveTo(194,196,156,188);c.closePath();c.fill();c.stroke()
c.fillStyle=VEST;c.beginPath();c.moveTo(94,192);c.lineTo(128,240);c.lineTo(162,192);c.quadraticCurveTo(192,206,198,256);c.lineTo(58,256);c.quadraticCurveTo(64,206,94,192);c.fill();c.lineWidth=5;c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,166);c.lineTo(116,192);c.lineTo(128,206);c.lineTo(140,192);c.lineTo(140,166);c.fill();c.beginPath();c.moveTo(116,166);c.lineTo(116,190);c.moveTo(140,166);c.lineTo(140,190);c.stroke()
c.fillStyle=RIB;for(const d of[-1,1])c.beginPath(),c.moveTo(128,214),c.lineTo(128+d*20,204),c.lineTo(128+d*18,226),c.closePath(),c.fill(),c.stroke()
c.beginPath();c.arc(128,215,5,0,T);c.fill();c.stroke()
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
eye(c,103,140,-1);eye(c,153,140,1)
c.lineWidth=2.5;c.beginPath();c.moveTo(128,156);c.lineTo(127,159);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,163,11,5.5,0,0,T),c.fill()
c.lineWidth=3.5;c.beginPath()
if(fl)c.moveTo(116,168),c.quadraticCurveTo(126,173,136,163);else c.moveTo(121,168),c.quadraticCurveTo(128,172,135,168)
c.stroke()
c.save();c.translate(0,gy)
const lens=x=>{c.beginPath();c.roundRect(x-21,121,42,38,12)}
for(const x of[103,153]){lens(x);c.fillStyle=fl?'#fff':'rgba(208,235,255,.35)';c.fill()}
if(fl){c.strokeStyle='#a5d8ff';c.lineWidth=5;for(const x of[103,153]){c.save();lens(x);c.clip();c.beginPath();c.moveTo(x-6,160);c.lineTo(x+22,124);c.moveTo(x-18,154);c.lineTo(x+4,126);c.stroke();c.restore()}}
for(const[w,s]of[[8,'#111'],[3,FR]]){c.lineWidth=w;c.strokeStyle=s;for(const x of[103,153])lens(x),c.stroke();c.beginPath();c.moveTo(124,137);c.quadraticCurveTo(128,133,132,137);c.moveTo(82,132);c.lineTo(73,128);c.moveTo(174,132);c.lineTo(183,128);c.stroke()}
c.strokeStyle='#111';c.restore()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(64,204);c.lineTo(66,150)
c.bezierCurveTo(52,74,88,36,128,36);c.bezierCurveTo(168,36,204,74,190,150);c.lineTo(192,204);c.lineTo(172,204);c.lineTo(174,122)
c.lineTo(176,110);for(let x=168;x>84;x-=12)c.lineTo(x,112+(x%24?0:-4));c.lineTo(80,110);c.lineTo(82,122);c.lineTo(84,204);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,b]of[[1.22,1.34],[1.42,1.5],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*b),c.stroke()
c.strokeStyle=HD;c.lineWidth=3;for(const x of[74,182])c.beginPath(),c.moveTo(x,150),c.lineTo(x,198),c.stroke()
c.strokeStyle='#111'
const hx=192,hy=142+gy+120*(1-r)
if(r>0){
for(const[w,s]of[[34,'#111'],[23,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(232,hy+120),c.lineTo(hx+8,hy+30),c.stroke()
c.strokeStyle='#111';c.lineWidth=5;c.fillStyle=SKIN
for(const y of[-17,15])c.beginPath(),c.ellipse(hx-12,hy+y,12,5.5,y<0?.1:-.1,0,T),c.fill(),c.stroke()
c.beginPath();c.roundRect(hx-10,hy-16,24,34,10);c.fill();c.stroke()
c.lineWidth=2.5;c.beginPath();c.moveTo(hx-10,hy-4);c.lineTo(hx-2,hy-4);c.moveTo(hx-10,hy+5);c.lineTo(hx-2,hy+5);c.stroke()
}
if(fl){const p=(t-.45)/.37;c.fillStyle='#fff9db';c.lineWidth=3.5;glint(c,84,122+gy,4+14*sin(PI*p),p*2)}
}
+64
View File
@@ -0,0 +1,64 @@
// mermaid with sea green hair lifts her purple tail out of the water and slaps it down, splash and ripples, bubbles rising
const{sin,cos,PI,min,max}=Math,T=2*PI
export const frames=20,delay=70
const SKIN='#ffe3d1',HAIR='#38d9a9',HD='#0ca678',HL='#c3fae8',EYE='#f06595',ED='#a61e4d',TL='#9775fa',TD='#6741d9',FIN='#d0bfff',SH='#faa2c1',SEA='#4dabf7',SL='#d0ebff',BL='#ffa8a8',STAR='#ffd43b'
const ease=x=>x<.5?2*x*x:1-2*(1-x)**2
const eye=(c,x,y,d,shut)=>{
if(shut){c.lineWidth=6;c.beginPath();c.moveTo(x-14,y+4);c.quadraticCurveTo(x,y-12,x+14,y+4);c.stroke();return}
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2,0,T);c.fill()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const star=(c,x,y,r,a)=>{c.save();c.translate(x,y);c.rotate(a);c.beginPath();for(let k=0;k<10;k++){const rr=k%2?r*.5:r,b=k*PI/5-PI/2;c.lineTo(cos(b)*rr,sin(b)*rr)}c.closePath();c.restore();c.fill();c.stroke()}
const tail=(c,r,b,dy)=>{
c.save();c.beginPath();c.rect(0,0,256,230);c.clip();c.translate(140,214+dy);c.rotate(r)
const e=b*1.3,p=()=>{c.beginPath();c.moveTo(-17,8);c.bezierCurveTo(-19,-30,-11+b,-60,-6+e,-82);c.quadraticCurveTo(-24+e,-86,-38+e,-112);c.quadraticCurveTo(-14+e,-108,e,-94);c.quadraticCurveTo(14+e,-108,38+e,-112);c.quadraticCurveTo(24+e,-86,6+e,-82);c.bezierCurveTo(11+b,-60,19,-30,17,8);c.closePath()}
c.lineWidth=6;c.fillStyle=TL;p();c.fill();c.save();c.clip()
c.fillStyle=FIN;c.beginPath();c.rect(-60,-140,120,54+0);c.fill()
c.strokeStyle=TD;c.lineWidth=3;for(const y of[-14,-34,-54])c.beginPath(),c.arc(b*(-y/90)-7,y,7,.15*PI,.85*PI),c.arc(b*(-y/90)+7,y,7,.15*PI,.85*PI),c.stroke()
c.beginPath();for(const d of[-1,1])c.moveTo(e,-92),c.quadraticCurveTo(e+d*14,-100,e+d*28,-106);c.stroke()
c.restore();c.strokeStyle='#111';c.lineWidth=6;p();c.stroke()
c.lineWidth=4;c.beginPath();c.moveTo(-6+e,-84);c.lineTo(6+e,-84);c.stroke()
c.restore();c.restore()
}
export default(c,t,i)=>{
const ts=.02,tu=.4,tw=.55,te=.66,u=t<te?-1:(t-te)/(1-te),p=(t-tw)/(te-tw)
const dy=t<ts?110:t<tu?110*(1-(t-ts)/(tu-ts))**2:t<tw?0:t<te?48*p*p:48+62*min(1,u*4)
const r=t<tw?.2:t<te?.2+.8*p*p:1,b=t<tu?-12:t<tw?-12*cos(2*PI*(t-tu)/(tw-tu)):14
if(dy<110)tail(c,r,b,dy)
c.save();c.translate(80,118);c.scale(.62,.62);c.translate(-128,-128)
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(200,34,214,96,206,150);c.bezierCurveTo(224,196,198,226,216,300);c.lineTo(40,300);c.bezierCurveTo(58,226,32,196,50,150);c.bezierCurveTo(42,96,56,34,128,34);c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,166);c.lineTo(116,190);c.quadraticCurveTo(70,194,66,236);c.lineTo(64,300);c.lineTo(192,300);c.lineTo(190,236);c.quadraticCurveTo(186,194,140,190);c.lineTo(140,166);c.fill();c.stroke()
c.lineWidth=5;c.beginPath();c.moveTo(92,236);c.lineTo(94,300);c.moveTo(164,236);c.lineTo(162,300);c.stroke()
c.fillStyle=SH;c.beginPath();c.moveTo(94,226);c.quadraticCurveTo(128,236,162,226);c.lineTo(162,250);c.quadraticCurveTo(128,258,94,250);c.closePath();c.fill();c.stroke()
for(const x of[110,146]){c.fillStyle='#fff';c.beginPath();c.moveTo(x,250);c.lineTo(x-12,232);c.quadraticCurveTo(x,218,x+12,232);c.closePath();c.fill();c.lineWidth=4;c.stroke();c.lineWidth=2.5;c.beginPath();for(const k of[-6,0,6])c.moveTo(x,248),c.lineTo(x+k,228);c.stroke()}
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
const joy=u>=0&&u<.55,bl=i==5
eye(c,103,140,-1,joy||bl);eye(c,153,140,1,joy||bl)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,161,12,6,0,0,T),c.fill()
c.lineWidth=3.5;c.fillStyle='#c92a2a';c.beginPath()
if(joy)c.moveTo(116,164),c.quadraticCurveTo(128,184,140,164),c.closePath(),c.fill();else c.arc(128,164,7,.15*PI,.85*PI)
c.stroke()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(56,250)
c.bezierCurveTo(68,200,40,170,52,120);c.bezierCurveTo(56,64,90,36,128,36);c.bezierCurveTo(166,36,200,64,204,120);c.bezierCurveTo(216,170,188,200,200,250)
c.quadraticCurveTo(182,232,184,206);c.bezierCurveTo(190,170,176,140,180,104);c.quadraticCurveTo(172,100,166,110);c.quadraticCurveTo(158,96,148,92);c.quadraticCurveTo(142,104,134,110)
c.quadraticCurveTo(128,96,120,92);c.quadraticCurveTo(116,104,108,110);c.quadraticCurveTo(100,96,92,94);c.quadraticCurveTo(86,104,84,110)
c.quadraticCurveTo(80,102,76,104);c.bezierCurveTo(80,140,66,170,72,206);c.quadraticCurveTo(74,232,56,250);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle=STAR;c.lineWidth=4;star(c,176,70,14,.3)
c.restore()
c.lineWidth=6;c.fillStyle=SEA;const sea=()=>{c.beginPath();c.moveTo(12,210);for(let k=0;k<6;k++)c.quadraticCurveTo(31+k*39,200,50+k*39,210);c.quadraticCurveTo(248,212,246,226);c.bezierCurveTo(240,252,16,252,10,226);c.quadraticCurveTo(8,212,12,210);c.closePath()}
sea();c.fill();c.save();c.clip()
c.strokeStyle=SL;c.lineWidth=4;c.beginPath();for(let k=0;k<6;k++)c.moveTo(18+k*39,220),c.quadraticCurveTo(31+k*39,214,44+k*39,220);c.stroke()
c.fillStyle=SL;c.strokeStyle='#111';c.lineWidth=2.5;for(const[x,o,s]of[[40,0,4],[64,.4,3],[118,.7,5],[196,.2,3.5],[226,.55,4.5]]){const p=(t+o)%1;c.beginPath();c.arc(x+3*sin(p*T*2),246-34*p,s,0,T);c.fill();c.stroke()}
if(u>=0){c.strokeStyle=SL;c.lineWidth=4;for(const k of[0,1]){const v=u-k*.25;if(v>0&&v<.7)c.beginPath(),c.ellipse(222,214,14+70*v,4+10*v,0,0,T),c.stroke()}}
c.restore();c.strokeStyle='#111';c.lineWidth=6;sea();c.stroke()
if(u>=0){
c.fillStyle='#a5d8ff';c.lineWidth=3.5
for(const[vx,vy,s]of[[-70,-150,6],[-40,-190,5],[-10,-210,7],[20,-180,5],[50,-160,6],[75,-120,4],[-90,-110,4]]){const x=222+vx*u,y=200+vy*u+260*u*u;if(y<206)c.beginPath(),c.moveTo(x,y-s*1.6),c.quadraticCurveTo(x+s,y,x,y+s),c.quadraticCurveTo(x-s,y,x,y-s*1.6),c.fill(),c.stroke()}
const h=46*sin(PI*min(1,u*2.4));if(h>4){c.fillStyle=SL;c.lineWidth=5;c.beginPath();c.moveTo(196,208);for(const[x,y]of[[200,-.7],[206,-.3],[212,-1],[220,-.4],[228,-.95],[236,-.35],[242,-.6]])c.lineTo(x,208+y*h);c.lineTo(248,208);c.closePath();c.fill();c.stroke()}
}
}
+36
View File
@@ -0,0 +1,36 @@
// raspberry-haired girl asleep on her folded arms at a desk, a sleep bubble swelling and shrinking from her nose as Z's float up
const{sin,cos,PI,max}=Math,T=2*PI
export const frames=16,delay=90
const SKIN='#ffe3d1',HAIR='#d6336c',HD='#a61e4d',HL='#ffc9de',CARD='#fff3bf',CD='#fcc419',DESK='#e8b07a',DD='#c47f45',BL='#ffa8a8',BUB='rgba(165,216,255,.55)',ZC='#91a7ff'
const zed=(c,x,y,s)=>{c.save();c.translate(x,y);c.scale(s,s);c.rotate(-.15);for(const[w,st]of[[10,'#111'],[4.5,ZC]]){c.lineWidth=w;c.strokeStyle=st;c.beginPath();c.moveTo(-8,-8);c.lineTo(8,-8);c.lineTo(-8,8);c.lineTo(8,8);c.stroke()}c.restore();c.strokeStyle='#111'}
export default(c,t)=>{
const r=4+13*(1-cos(T*t))/2
c.lineWidth=6;c.fillStyle=CARD;c.beginPath();c.moveTo(96,214);c.quadraticCurveTo(120,150,186,142);c.quadraticCurveTo(240,146,244,214);c.closePath();c.fill();c.stroke()
const head=f=>{c.save();c.translate(124,132);c.rotate(-.75);c.translate(-128,-115);f();c.restore()}
head(()=>{
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(200,34,214,100,206,160);c.quadraticCurveTo(208,186,194,198);c.lineTo(62,198);c.quadraticCurveTo(48,186,50,160);c.bezierCurveTo(42,100,56,34,128,34);c.fill();c.stroke()
})
c.fillStyle=DESK;c.beginPath();c.roundRect(6,212,244,30,8);c.fill();c.stroke()
c.strokeStyle=DD;c.lineWidth=4;c.beginPath();c.moveTo(18,230);c.lineTo(238,230);c.stroke();c.strokeStyle='#111'
c.fillStyle='#fff';c.lineWidth=5;c.beginPath();c.moveTo(150,214);c.lineTo(160,198);c.lineTo(246,198);c.lineTo(240,214);c.closePath();c.fill();c.stroke()
c.strokeStyle='#a5d8ff';c.lineWidth=2.5;for(const x of[180,200,220])c.beginPath(),c.moveTo(x,202),c.lineTo(x-3,210),c.stroke();c.strokeStyle='#111'
c.lineWidth=6;c.fillStyle=CARD;for(const[x,w]of[[96,62],[158,58]])c.beginPath(),c.roundRect(x-w,186,w*2,30,15),c.fill(),c.stroke()
c.strokeStyle=CD;c.lineWidth=4;for(const x of[44,212])c.beginPath(),c.moveTo(x,190),c.lineTo(x,212),c.stroke();c.strokeStyle='#111'
head(()=>{
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
c.lineWidth=5;for(const x of[103,153]){c.beginPath();c.arc(x,136,13,PI*.15,PI*.85);c.stroke();c.beginPath();c.moveTo(x+(x<128?-12:12),140);c.lineTo(x+(x<128?-17:17),137);c.stroke()}
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,160,12,6,0,0,T),c.fill()
c.lineWidth=3.5;c.fillStyle='#c92a2a';c.beginPath();c.ellipse(124,172,5,4,0,0,T);c.fill();c.stroke()
c.fillStyle='#d0ebff';c.lineWidth=3;c.beginPath();c.moveTo(119,173);c.quadraticCurveTo(112,180,114,186);c.quadraticCurveTo(118,190,120,184);c.quadraticCurveTo(121,178,119,173);c.fill();c.stroke()
c.fillStyle=BUB;c.lineWidth=4;c.beginPath();c.arc(131+r*.82,157+r*.39,r,0,T);c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=3;c.beginPath();c.arc(131+r*.82,157+r*.39,r*.62,PI*1.15,PI*1.5);c.stroke();c.strokeStyle='#111'
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(66,160)
c.bezierCurveTo(48,74,88,36,128,36);c.bezierCurveTo(168,36,208,74,190,160)
c.quadraticCurveTo(186,124,178,104);c.quadraticCurveTo(170,106,164,114);c.quadraticCurveTo(158,98,148,94);c.quadraticCurveTo(142,106,134,110)
c.quadraticCurveTo(128,96,118,92);c.quadraticCurveTo(114,104,106,110);c.quadraticCurveTo(100,98,92,98);c.quadraticCurveTo(88,106,84,114)
c.quadraticCurveTo(78,106,76,106);c.quadraticCurveTo(68,128,66,160);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,b]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*b),c.stroke()
c.strokeStyle='#111'
})
for(const o of[0,1/3,2/3]){const p=(t+o)%1;zed(c,176+30*p+6*sin(p*T*2),88-70*p,.6+.8*sin(PI*p))}
}
+68
View File
@@ -0,0 +1,68 @@
// masked kunoichi pops out of a smoke puff, throws a spinning shuriken that zips off to the right, then vanishes in smoke again
const{sin,cos,PI,min,max}=Math,T=2*PI
export const frames=20,delay=70
const SKIN='#ffe3d1',HAIR='#495057',HD='#343a40',HL='#adb5bd',EYE='#ff922b',ED='#d9480f',GI='#3b5bdb',GD='#364fc7',SC='#e03131',WR='#e9ecef',MET='#ced4da',SM='#f1f3f5'
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y+2,14,15,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+3,11.5,13.5,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-6,13,9,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x,y+3,11.5,13.5,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+4,5,7,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-3,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+9,2,0,T);c.fill()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-6);c.lineTo(x+16,y-6);c.moveTo(x+d*15,y-6);c.lineTo(x+d*21,y-11);c.stroke()
}
const star=(c,x,y,a)=>{
c.save();c.translate(x,y);c.rotate(a);c.fillStyle=MET;c.lineWidth=4;c.beginPath()
for(let k=0;k<4;k++){const b=k*PI/2;c.lineTo(15*cos(b),15*sin(b));c.lineTo(5*cos(b+PI/4),5*sin(b+PI/4))}
c.closePath();c.fill();c.stroke();c.fillStyle='#868e96';c.beginPath();c.arc(0,0,3,0,T);c.fill();c.stroke();c.restore()
}
const smoke=(c,x,y,s,g)=>{
const P=[[0,0,1],[-30,-22,.8],[30,-24,.85],[-30,30,.8],[32,28,.8],[0,-50,.72],[0,54,.72],[-46,4,.6],[46,2,.6],[0,-28,.8],[0,30,.8],[-18,0,.8],[18,0,.8]].map(([dx,dy,r])=>[x+dx*g,y+dy*g*1.3,r*40*s]).filter(p=>p[2]>7)
c.fillStyle='#111';for(const[px,py,r]of P)c.beginPath(),c.arc(px,py,r+3.5,0,T),c.fill()
c.fillStyle=SM;for(const[px,py,r]of P)c.beginPath(),c.arc(px,py,r,0,T),c.fill()
c.strokeStyle='#ced4da';c.lineWidth=3;for(const[px,py,r]of P)if(r>12)c.beginPath(),c.arc(px-r*.2,py-r*.2,r*.55,PI*.9,PI*1.4),c.stroke()
c.strokeStyle='#111'
}
export default(c,t,i)=>{
const on=t>.06&&t<.94,w=t<.22?0:t<.3?(t-.22)/.08:t<.36?1-((t-.3)/.06)**2*1:0
const a=t<.22?.3:t<.3?.3+2.4*w:t<.36?2.7-2.85*((t-.3)/.06):-.15,hx=124+36*cos(a),hy=142+36*sin(a),fly=t>=.35
if(on){
const sw=k=>5*sin(T*t*2-k)
c.lineWidth=4
for(const[w,col]of[[16,'#111'],[9,SC]])c.lineWidth=w,c.strokeStyle=col,c.beginPath(),c.moveTo(100,130),c.quadraticCurveTo(76,128+sw(0),56,136+sw(1)),c.quadraticCurveTo(40,142+sw(2),26,136+sw(3)),c.stroke()
c.strokeStyle='#111'
c.save();c.translate(110,90);c.scale(.58,.58);c.translate(-128,-128)
c.lineWidth=6;c.fillStyle=HAIR;c.save();c.translate(150,40);c.rotate(-.3+.12*sin(T*t*2))
c.beginPath();c.moveTo(-10,0);c.bezierCurveTo(-30,-60,40,-80,70,-50);c.quadraticCurveTo(50,-56,40,-40);c.quadraticCurveTo(62,-30,64,-4);c.quadraticCurveTo(40,-30,10,10);c.closePath();c.fill();c.stroke();c.restore()
c.fillStyle=SC;c.beginPath();c.ellipse(152,40,12,16,.5,0,T);c.fill();c.stroke()
c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(200,34,212,96,204,150);c.lineTo(52,150);c.bezierCurveTo(44,96,56,34,128,34);c.fill();c.stroke()
c.restore()
for(const[x0,x1]of[[100,92],[120,132]]){for(const[lw,col]of[[20,'#111'],[12,GI]])c.lineWidth=lw,c.strokeStyle=col,c.beginPath(),c.moveTo(x0+(x0<110?2:-2),176),c.lineTo(x1,214),c.stroke()
c.strokeStyle='#111';c.lineWidth=4;c.fillStyle=WR;c.beginPath();c.moveTo(x1-9,206);c.lineTo(x1+9,206);c.lineTo(x1+10,222);c.quadraticCurveTo(x1+18,224,x1+16,230);c.lineTo(x1-10,230);c.closePath();c.fill();c.stroke()}
c.lineWidth=4;c.fillStyle=GI;c.beginPath();c.moveTo(94,134);c.lineTo(126,134);c.quadraticCurveTo(134,156,134,184);c.lineTo(86,184);c.quadraticCurveTo(86,156,94,134);c.closePath();c.fill();c.stroke()
c.fillStyle=GD;c.beginPath();c.moveTo(110,134);c.lineTo(126,134);c.lineTo(104,166);c.closePath();c.fill();c.stroke()
c.fillStyle=SC;c.beginPath();c.rect(86,166,48,9);c.fill();c.stroke()
for(const[w,col]of[[14,'#111'],[7,GI]])c.lineWidth=w,c.strokeStyle=col,c.beginPath(),c.moveTo(96,142),c.lineTo(80,158),c.lineTo(90,170),c.stroke()
c.strokeStyle='#111';c.lineWidth=4;c.fillStyle=SKIN;c.beginPath();c.arc(92,170,6,0,T);c.fill();c.stroke()
c.fillStyle=SC;c.lineWidth=4;c.beginPath();c.ellipse(110,132,20,7,0,0,T);c.fill();c.stroke()
c.save();c.translate(110,90);c.scale(.58,.58);c.translate(-128,-128)
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
if(i==14){c.lineWidth=6;for(const x of[103,153])c.beginPath(),c.moveTo(x-15,142),c.quadraticCurveTo(x,148,x+15,142),c.stroke()}else eye(c,103,140,-1),eye(c,153,140,1)
c.fillStyle=GI;c.beginPath();c.moveTo(75,154);c.quadraticCurveTo(128,150,181,154);c.bezierCurveTo(176,170,156,184,128,186);c.bezierCurveTo(100,184,80,170,75,154);c.closePath();c.fill();c.stroke()
c.strokeStyle=GD;c.lineWidth=4;c.beginPath();c.moveTo(118,164);c.quadraticCurveTo(128,170,138,164);c.stroke();c.strokeStyle='#111'
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,140)
c.bezierCurveTo(54,74,88,36,128,36);c.bezierCurveTo(168,36,202,74,186,140)
c.quadraticCurveTo(184,118,178,104);c.lineTo(166,116);c.lineTo(160,100);c.lineTo(146,114);c.lineTo(138,98);c.lineTo(124,114);c.lineTo(116,98);c.lineTo(104,114);c.lineTo(96,100);c.lineTo(86,114);c.lineTo(78,104);c.quadraticCurveTo(72,118,70,140);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.24,1.36],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle=SC;c.beginPath();c.moveTo(66,80);c.quadraticCurveTo(128,62,190,80);c.lineTo(188,96);c.quadraticCurveTo(128,80,68,96);c.closePath();c.fill();c.stroke()
c.fillStyle=MET;c.lineWidth=5;c.beginPath();c.moveTo(106,72);c.lineTo(150,72);c.lineTo(150,90);c.lineTo(106,90);c.closePath();c.fill();c.stroke()
c.lineWidth=3.5;c.beginPath();c.moveTo(122,76);c.lineTo(134,86);c.moveTo(134,76);c.lineTo(122,86);c.stroke()
c.restore()
for(const[w,col]of[[14,'#111'],[7,GI]])c.lineWidth=w,c.strokeStyle=col,c.beginPath(),c.moveTo(124,142),c.lineTo(hx,hy),c.stroke()
c.strokeStyle='#111';c.lineWidth=4;c.fillStyle=SKIN;c.beginPath();c.arc(hx,hy,6.5,0,T);c.fill();c.stroke()
if(!fly)star(c,hx+4,hy-6,a)
if(t>.31&&t<.42){c.lineWidth=3.5;for(const r of[44,51])c.beginPath(),c.arc(124,142,r,-.1,1.4),c.stroke()}
}
if(fly){const p=(t-.35)/.2;if(p<1){const x=160+130*p*p*.3+130*p*.7,y=134-8*p;for(const k of[0,1,2]){const l=34+k*8;for(const[w,col]of[[8,'#111'],[3,'#fff']])c.lineWidth=w,c.strokeStyle=col,c.beginPath(),c.moveTo(x-20-l,y-8+k*8),c.lineTo(x-20,y-8+k*8),c.stroke()}c.strokeStyle='#111';star(c,x,y,T*t*6)}}
const s=t<.18?1-t/.18:t>.82?(t-.82)/.18:0
if(s>0)smoke(c,110,136,s,t<.5?.75+.35*(1-s):.5+.5*s)
}
+56
View File
@@ -0,0 +1,56 @@
// ojou-sama with golden drill curls laughing "ohohoho" behind the back of her hand, curls bouncing, sparkles and rose petals drifting
const{sin,cos,PI,abs}=Math,T=2*PI
export const frames=12,delay=100
const SKIN='#ffe3d1',HAIR='#fcc419',HD='#f08c00',HL='#fff3bf',DRESS='#e64980',DD='#a61e4d',BL='#ffa8a8',ROSE='#e03131',RD='#a51111',LEAF='#40c057',MO='#c92a2a',TG='#ff8fab',GEM='#4dabf7'
const drill=(c,x,y,d,s)=>{
const n=5,cx=k=>x+d*k*1.5,cy=k=>y+k*s
c.lineWidth=5;c.fillStyle=HAIR;c.beginPath();c.moveTo(cx(4)-8,cy(4)+6);c.lineTo(cx(4)+d*3,cy(4)+28);c.lineTo(cx(4)+8,cy(4)+6);c.fill();c.stroke()
for(let k=n-1;k>=0;k--){
const rx=25-k*3,ry=14-k*.8
c.strokeStyle='#111';c.lineWidth=5;c.fillStyle=HAIR;c.beginPath();c.ellipse(cx(k),cy(k),rx,ry,d*.3,0,T);c.fill();c.stroke()
c.strokeStyle=HD;c.lineWidth=3;c.beginPath();c.ellipse(cx(k),cy(k)+2,rx*.62,ry*.45,d*.3,.15*PI,.85*PI);c.stroke()
c.strokeStyle=HL;c.lineWidth=3.5;c.beginPath();c.ellipse(cx(k),cy(k)-1,rx*.7,ry*.55,d*.3,1.15*PI,1.45*PI);c.stroke()
}
c.strokeStyle='#111'
}
const spark=(c,x,y,r)=>{c.beginPath();for(let k=0;k<8;k++){const a=k*PI/4,rr=k%2?r*.3:r;c.lineTo(x+cos(a)*rr,y+sin(a)*rr)}c.closePath();c.fill();c.stroke()}
export default(c,t)=>{
const h=abs(sin(3*PI*t)),hl=abs(sin(3*PI*t-.7)),o=.35+.65*h
c.lineWidth=3;c.fillStyle=ROSE
for(const[x0,o2,r]of[[24,0,1],[232,.5,-1]]){const p=(t+o2)%1,x=x0+12*sin(T*(p+o2)),y=-16+p*280;c.save();c.translate(x,y);c.rotate(r*T*p+o2*6);c.beginPath();c.moveTo(0,-9);c.quadraticCurveTo(9,0,0,9);c.quadraticCurveTo(-9,0,0,-9);c.fill();c.stroke();c.restore()}
c.lineWidth=6;c.fillStyle=DRESS;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(62,198,54,250);c.lineTo(202,250);c.quadraticCurveTo(194,198,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.rect(116,166,24,28);c.fill();c.lineWidth=5;c.beginPath();c.moveTo(116,166);c.lineTo(116,190);c.moveTo(140,166);c.lineTo(140,190);c.stroke()
c.fillStyle='#fff';c.lineWidth=5;for(const d of[-1,1])c.beginPath(),c.moveTo(128,190),c.quadraticCurveTo(128+d*22,182,128+d*30,192),c.quadraticCurveTo(128+d*20,206,128,198),c.fill(),c.stroke()
for(const[y,r]of[[236,13],[222,15],[208,16]])c.beginPath(),c.ellipse(128,y,r,9,0,0,T),c.fill(),c.stroke()
c.fillStyle=GEM;c.beginPath();c.moveTo(128,190);c.lineTo(136,198);c.lineTo(128,208);c.lineTo(120,198);c.closePath();c.fill();c.stroke()
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,38);c.bezierCurveTo(200,38,214,100,206,150);c.lineTo(50,150);c.bezierCurveTo(42,100,56,38,128,38);c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
for(const[x,d]of[[103,-1],[153,1]]){
c.lineWidth=6;c.beginPath();c.moveTo(x-15,143);c.quadraticCurveTo(x,129,x+15,143);c.moveTo(x+d*15,143);c.lineTo(x+d*22,139);c.moveTo(x+d*11,136);c.lineTo(x+d*17,130);c.stroke()
c.lineWidth=3.5;c.beginPath();c.moveTo(x-12,118);c.quadraticCurveTo(x,110,x+12,116);c.stroke()
}
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,158,12,6,0,0,T),c.fill()
c.lineWidth=2.5;c.beginPath();c.moveTo(128,152);c.lineTo(127,156);c.stroke()
c.lineWidth=3.5;c.fillStyle=MO;c.beginPath();c.moveTo(124,163);c.lineTo(150,163);c.quadraticCurveTo(149,172+8*o,137,172+8*o);c.quadraticCurveTo(125,170+6*o,124,163);c.closePath();c.fill();c.stroke()
c.save();c.clip();c.fillStyle=TG;c.beginPath();c.ellipse(138,174+8*o,8,5,0,0,T);c.fill();c.restore()
for(const d of[-1,1])drill(c,128+d*76,134,d,22+5*hl)
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(56,134)
c.bezierCurveTo(36,64,84,38,128,38);c.bezierCurveTo(172,38,220,64,200,134)
c.quadraticCurveTo(190,116,180,102);c.bezierCurveTo(168,84,140,90,128,62)
c.bezierCurveTo(116,90,88,84,76,102);c.quadraticCurveTo(66,116,56,134);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.2,1.32],[1.68,1.8]])c.beginPath(),c.arc(128,104,60,PI*a,PI*e),c.stroke()
c.strokeStyle=HD;c.lineWidth=3;for(const d of[-1,1])c.beginPath(),c.moveTo(128,66),c.bezierCurveTo(128+d*10,86,128+d*36,84,128+d*46,96),c.stroke()
c.strokeStyle='#111';c.lineWidth=4;c.fillStyle=LEAF
for(const a of[.4,1.6])c.beginPath(),c.ellipse(176+cos(a)*14,64+sin(a)*10,10,5,a,0,T),c.fill(),c.stroke()
c.fillStyle=ROSE;c.lineWidth=5;c.beginPath();c.arc(176,62,12,0,T);c.fill();c.stroke()
c.strokeStyle=RD;c.lineWidth=3;c.beginPath();c.arc(176,62,7,.2,PI*1.6);c.moveTo(178,61);c.arc(176,62,3,0,PI*1.4);c.stroke();c.strokeStyle='#111'
for(const[l,s]of[[30,'#111'],[19,DRESS]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(84,252),c.lineTo(98,200),c.stroke()
c.strokeStyle='#111';c.lineWidth=5;c.fillStyle='#fff';c.beginPath();c.ellipse(98,198,14,8,-.3,0,T);c.fill();c.stroke()
c.save();c.translate(108,180);c.rotate(-.75);c.fillStyle=SKIN
c.beginPath();c.moveTo(-12,-8);c.lineTo(12,-10);c.quadraticCurveTo(24,-9,23,-2);c.quadraticCurveTo(24,5,12,7);c.lineTo(-8,10);c.quadraticCurveTo(-16,2,-12,-8);c.fill();c.stroke()
c.lineWidth=2.5;c.beginPath();c.moveTo(10,-4);c.lineTo(20,-4);c.moveTo(10,2);c.lineTo(19,3);c.stroke()
c.lineWidth=5;c.beginPath();c.ellipse(0,13,4,9,-.9,0,T);c.fill();c.stroke()
c.restore()
c.fillStyle=HL;c.lineWidth=3.5
for(const[x,y,o2]of[[30,44,0],[226,34,.33],[128,16,.66],[230,128,.5]]){const s=sin(T*(t*2+o2));if(s>.1)spark(c,x,y,12*s)}
}
+48
View File
@@ -0,0 +1,48 @@
// green-haired girl soaking shoulder-deep in a rocky hot spring, towel folded on her head, steam drifting up and a rubber duck bobbing
const{sin,cos,PI,max,min}=Math,T=2*PI
export const frames=12,delay=110
const SKIN='#ffe3d1',SK2='#ffd0b8',HAIR='#2f9e44',HD='#2b8a3e',HL='#b2f2bb',WA='#99e9f2',WL='#e3fafc',ROCK='#ced4da',RD='#adb5bd',BL='#ff8fab',TW='#fff',TS='#74c0fc',WOOD='#d9a066',WD='#a9744f',Z=.8
const rock=(c,x,y,a,b)=>{c.fillStyle=ROCK;c.beginPath();c.ellipse(x,y,a,b,0,0,T);c.fill();c.stroke();c.strokeStyle=RD;c.lineWidth=3;c.beginPath();c.ellipse(x+a*.2,y+b*.25,a*.55,b*.4,0,.2,PI*.9);c.stroke();c.strokeStyle='#111';c.lineWidth=6}
const steam=(c,t,l)=>{for(const[x,o]of l){const p=(t+o)%1,y=200-p*130,w=sin(PI*p);if(w>.15)for(const[lw,s]of[[4+6*w,'#111'],[5*w,'#fff']])c.lineWidth=lw,c.strokeStyle=s,c.beginPath(),c.moveTo(x+6*sin(p*T*2+o*9),y),c.quadraticCurveTo(x+10*sin(p*T*2+o*9+1.5),y-10,x+6*sin(p*T*2+o*9+3),y-22),c.stroke()}c.strokeStyle='#111'}
export default(c,t)=>{
c.lineWidth=6
for(const[x,y,a,b]of[[30,162,26,18],[76,146,28,18],[180,146,28,18],[226,162,26,18],[128,140,30,16]])rock(c,x,y,a,b)
c.fillStyle=WOOD;c.beginPath();c.moveTo(12,122);c.lineTo(16,144);c.quadraticCurveTo(32,150,48,144);c.lineTo(52,122);c.fill();c.stroke()
c.fillStyle='#e8c39e';c.beginPath();c.ellipse(32,122,20,6,0,0,T);c.fill();c.stroke()
c.strokeStyle=WD;c.lineWidth=4;for(const y of[130,138])c.beginPath(),c.moveTo(14,y),c.quadraticCurveTo(32,y+5,50,y),c.stroke();c.strokeStyle='#111'
c.lineWidth=6;c.fillStyle=WA;c.beginPath();c.ellipse(128,196,122,48,0,0,T);c.fill();c.stroke()
steam(c,t,[[38,0],[92,.5],[168,.25],[220,.75]])
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(114,178);c.quadraticCurveTo(112,190,90,194);c.quadraticCurveTo(72,198,70,210);c.lineTo(186,210);c.quadraticCurveTo(184,198,166,194);c.quadraticCurveTo(144,190,142,178);c.closePath();c.fill();c.stroke()
c.save();c.translate(128,182);c.scale(Z,Z);c.translate(-128,-186)
c.lineWidth=7.5;c.fillStyle=HD;c.beginPath();c.moveTo(128,50);c.bezierCurveTo(62,50,58,120,70,170);c.lineTo(186,170);c.bezierCurveTo(198,120,194,50,128,50);c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
for(const x of[103,153]){c.lineWidth=7;c.beginPath();c.arc(x,136,15,PI*.15,PI*.85);c.stroke()}
const bl=1+.15*sin(T*t)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,158,16*bl,8*bl,0,0,T),c.fill()
c.lineWidth=3;for(const d of[-1,1])for(const k of[-7,0,7])c.beginPath(),c.moveTo(128+d*44+k-2,162),c.lineTo(128+d*44+k+2,154),c.stroke()
c.lineWidth=4.5;c.beginPath();c.moveTo(117,166);c.quadraticCurveTo(122,172,128,167);c.quadraticCurveTo(134,172,139,166);c.stroke()
c.lineWidth=7.5;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,150)
c.bezierCurveTo(54,74,88,40,128,40);c.bezierCurveTo(168,40,202,74,186,150)
c.quadraticCurveTo(184,118,174,104);c.quadraticCurveTo(166,110,160,118);c.quadraticCurveTo(156,100,144,94);c.quadraticCurveTo(138,106,130,112)
c.quadraticCurveTo(124,98,112,94);c.quadraticCurveTo(104,108,98,116);c.quadraticCurveTo(92,106,84,104);c.quadraticCurveTo(72,120,70,150);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.3,1.42],[1.5,1.58]])c.beginPath(),c.arc(128,104,54,PI*a,PI*e),c.stroke();c.strokeStyle='#111'
c.save();c.translate(130,46);c.rotate(-.12)
c.lineWidth=7.5;c.fillStyle=TW;c.beginPath();c.roundRect(-46,-16,92,30,8);c.fill();c.stroke()
c.strokeStyle=TS;c.lineWidth=5;for(const x of[-30,30])c.beginPath(),c.moveTo(x,-12),c.lineTo(x,10),c.stroke()
c.strokeStyle='#ced4da';c.lineWidth=4;c.beginPath();c.moveTo(-40,0);c.lineTo(40,0);c.stroke();c.restore()
c.restore()
c.save();c.beginPath();c.ellipse(128,196,119,45,0,0,T);c.clip()
c.fillStyle=WA;c.beginPath();c.moveTo(0,204);for(let x=0;x<=256;x+=16)c.quadraticCurveTo(x+8,204+3*sin(x*.2),x+16,204);c.lineTo(256,256);c.lineTo(0,256);c.fill()
c.strokeStyle=WL;c.lineWidth=4;for(const k of[0,.5]){const r=(t+k)%1;c.beginPath();c.ellipse(128,206,56+40*r,8+8*r,0,PI*.05,PI*.95);c.stroke()}
c.restore()
c.strokeStyle='#111';c.lineWidth=6;c.beginPath();c.ellipse(128,196,122,48,0,0,PI);c.stroke()
for(const[x,y,a,b]of[[16,214,18,14],[238,212,20,15]])rock(c,x,y,a,b)
const dy=3*sin(T*t*2),dx=6*sin(T*t)
c.save();c.translate(206+dx,192+dy);c.rotate(.08*sin(T*t*2+1))
c.lineWidth=5;c.fillStyle='#ffd43b';c.beginPath();c.moveTo(-18,0);c.quadraticCurveTo(-20,14,0,14);c.quadraticCurveTo(18,14,20,-2);c.quadraticCurveTo(12,2,6,0);c.closePath();c.fill();c.stroke()
c.beginPath();c.arc(-6,-10,10,0,T);c.fill();c.stroke()
c.fillStyle='#ff922b';c.beginPath();c.moveTo(-15,-12);c.quadraticCurveTo(-26,-10,-22,-5);c.quadraticCurveTo(-18,-4,-14,-7);c.fill();c.stroke()
c.fillStyle='#111';c.beginPath();c.arc(-8,-12,2.2,0,T);c.fill();c.restore()
c.strokeStyle=WL;c.lineWidth=3;c.beginPath();c.ellipse(206+dx,206,22,4,0,0,T);c.stroke();c.strokeStyle='#111'
steam(c,t,[[60,.15],[196,.6]])
}
+48
View File
@@ -0,0 +1,48 @@
// chibi girl in a yellow raincoat and red boots jumping into a puddle, splash flying out, rain falling
const{sin,cos,PI,max,min}=Math,T=2*PI
export const frames=16,delay=80
const SKIN='#ffe3d1',HAIR='#ffc078',HD='#f08c00',EYE='#40c057',ED='#2b8a3e',COAT='#ffd43b',CD='#fab005',BOOT='#ff6b6b',WA='#a5d8ff',WL='#e7f5ff',BL='#ffa8a8',Z=.7
const cl=x=>max(0,min(1,x))
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=3;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2.5,0,T);c.fill()
c.lineWidth=8;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const rain=(c,t,l)=>{for(const[x,o,n]of l){const y=((t*n+o)%1)*300-40;for(const[w,s]of[[7,'#111'],[3,WA]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(x-y*.2,y),c.lineTo(x-y*.2-6,y+22),c.stroke()}c.strokeStyle='#111'}
const drop=(c,x,y,r,a)=>{c.save();c.translate(x,y);c.rotate(a);c.beginPath();c.moveTo(0,-r*1.8);c.quadraticCurveTo(r*1.1,-r*.2,r,r*.3);c.arc(0,r*.3,r,0,PI);c.quadraticCurveTo(-r*1.1,-r*.2,0,-r*1.8);c.restore();c.fill();c.stroke()}
export default(c,t,i)=>{
const air=cl((t-.12)/.42),h=28*sin(PI*air),up=air>0&&air<1,sq=t<.12?.1*sin(PI*t/.12):t>.54&&t<.74?.13*sin(PI*(t-.54)/.2):0,q=cl((t-.54)/.42)
rain(c,t,[[60,.1,1],[150,.6,1],[250,.35,1],[200,.85,1]])
c.lineWidth=6;c.fillStyle=WA;c.beginPath();c.ellipse(128,228,98,19,0,0,T);c.fill();c.stroke()
c.fillStyle=WL;c.beginPath();c.ellipse(94,222,26,5,0,0,T);c.fill()
if(q>0&&q<1){c.strokeStyle=WL;c.lineWidth=3;for(const k of[0,.3]){const r=cl(q*1.4-k);if(r>0&&r<1)c.globalAlpha=1,c.beginPath(),c.ellipse(128,228,40+48*r,7+10*r,0,0,T),c.stroke()}c.strokeStyle='#111'}
c.save();c.translate(128,228-h);c.scale(1+sq,1-sq)
c.fillStyle=BOOT;c.lineWidth=6
for(const d of[-1,1])c.beginPath(),c.moveTo(d*6,-26),c.lineTo(d*6,-2),c.quadraticCurveTo(d*6,2,d*12,2),c.lineTo(d*28,2),c.quadraticCurveTo(d*32,-6,d*24,-8),c.lineTo(d*24,-26),c.closePath(),c.fill(),c.stroke()
const a=up?.5+.5*sin(PI*air):0,ar=d=>[d*(36+14*a),-56-58*a]
for(const d of[-1,1]){const[x,y]=ar(d);for(const[w,s]of[[24,'#111'],[13,COAT]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(d*18,-86),c.lineTo(x,y),c.stroke()}
c.strokeStyle='#111';c.lineWidth=6;c.fillStyle=COAT;c.beginPath();c.moveTo(-22,-92);c.quadraticCurveTo(-30,-60,-42,-30);c.quadraticCurveTo(0,-18,42,-30);c.quadraticCurveTo(30,-60,22,-92);c.closePath();c.fill();c.stroke()
c.strokeStyle=CD;c.lineWidth=4;c.beginPath();c.moveTo(0,-88);c.lineTo(0,-26);c.stroke();c.strokeStyle='#111';c.lineWidth=3;c.fillStyle='#fff'
for(const y of[-72,-52])c.beginPath(),c.arc(-8,y,4,0,T),c.fill(),c.stroke()
for(const d of[-1,1]){const[x,y]=ar(d);c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.arc(x,y,10,0,T);c.fill();c.stroke()}
c.save();c.translate(0,-86);c.scale(Z,Z);c.translate(-128,-186)
c.lineWidth=8;c.fillStyle=COAT;c.beginPath();c.ellipse(128,112,72,76,0,0,T);c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
const happy=t>.52&&t<.8
if(happy){c.lineWidth=7;for(const x of[103,153])c.beginPath(),c.arc(x,146,13,PI*1.15,PI*1.85),c.stroke()}else eye(c,103,140,-1),eye(c,153,140,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,161,13,7,0,0,T),c.fill()
c.lineWidth=4.5;c.fillStyle='#c92a2a';c.beginPath()
if(up||happy)c.moveTo(116,165),c.quadraticCurveTo(128,186,140,165),c.closePath(),c.fill(),c.stroke();else c.arc(128,164,8,.2*PI,.8*PI),c.stroke()
c.lineWidth=8;c.fillStyle=HAIR;c.beginPath();c.moveTo(76,130);c.quadraticCurveTo(74,90,96,78);c.lineTo(160,78);c.quadraticCurveTo(182,90,180,130)
c.quadraticCurveTo(172,108,160,104);c.quadraticCurveTo(152,114,146,120);c.quadraticCurveTo(138,104,124,102);c.quadraticCurveTo(116,114,110,120)
c.quadraticCurveTo(104,106,94,106);c.quadraticCurveTo(82,112,76,130);c.closePath();c.fill();c.stroke()
c.fillStyle=COAT;c.beginPath();c.moveTo(62,118);c.bezierCurveTo(60,40,196,40,194,118);c.quadraticCurveTo(186,84,128,82);c.quadraticCurveTo(70,84,62,118);c.fill();c.stroke()
c.strokeStyle=CD;c.lineWidth=5;c.beginPath();c.arc(128,118,58,PI*1.2,PI*1.8);c.stroke();c.strokeStyle='#111'
c.restore();c.restore()
if(q>0&&q<1){c.fillStyle=WA;c.lineWidth=4;for(const[vx,vy]of[[-1.7,.9],[-1.2,1.3],[-.6,1.7],[.6,1.6],[1.2,1.25],[1.8,.95]]){const x=128+vx*64*q+(vx<0?-26:26),y=228-vy*130*q+170*q*q,r=9*(1-q*.5);if(y<230)drop(c,x,y,r,-vx*.5)}}
if(q>0&&q<.45){const k=sin(PI*q/.45);c.fillStyle=WA;c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*18,232),c.quadraticCurveTo(128+d*28,226-18*k,128+d*(32+8*k),226-36*k),c.quadraticCurveTo(128+d*40,222-12*k,128+d*(48+10*k),224-26*k),c.quadraticCurveTo(128+d*54,224-6*k,128+d*(62+14*k),228-14*k),c.quadraticCurveTo(128+d*60,238,128+d*40,238),c.closePath(),c.fill(),c.stroke()}
rain(c,t,[[100,.45,1],[210,.05,1],[30,.7,1]])
}
+44
View File
@@ -0,0 +1,44 @@
// girl with ginger space buns slurping a big bowl of ramen, noodles zipping up into her puffed cheeks, steam curling up
const{sin,PI}=Math,T=2*PI
export const frames=16,delay=70
const SKIN='#ffe3d1',HAIR='#3bc9db',HD='#1098ad',HL='#c5f6fa',BL='#ffa8a8',TOP='#74c0fc',BOWL='#fa5252',BR='#ffc078',ND='#ffe066',WOOD='#e0a96d',NORI='#2f9e44',ONI='#8ce99a'
const ds=(c,a,b,s,f)=>{for(const[l,k]of[[a,'#111'],[b,s]])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),f(),c.stroke();c.strokeStyle='#111'}
export default(c,t)=>{
const pf=4+3*sin(4*T*t)
c.lineWidth=6;c.fillStyle=TOP;c.beginPath();c.moveTo(102,146);c.quadraticCurveTo(50,154,38,226);c.lineTo(218,226);c.quadraticCurveTo(206,154,154,146);c.closePath();c.fill();c.stroke()
ds(c,30,19,TOP,()=>{c.moveTo(206,218);c.lineTo(194,172)})
c.save();c.translate(128,26);c.scale(.82,.82);c.translate(-128,-40)
c.lineWidth=7;c.fillStyle=HAIR
for(const d of[-1,1])c.beginPath(),c.arc(128+d*54,50,27,0,T),c.fill(),c.stroke()
c.strokeStyle=HD;c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.arc(128+d*54,50,14,0,4.4),c.stroke()
c.strokeStyle='#111';c.lineWidth=7;c.fillStyle=HD;c.beginPath();c.moveTo(128,36);c.bezierCurveTo(194,36,206,96,196,154);c.lineTo(60,154);c.bezierCurveTo(50,96,62,36,128,36);c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70-pf,152,100-pf,184,128,186);c.bezierCurveTo(156+pf,184,186+pf,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
for(const d of[-1,1]){const x=128+d*25;c.lineWidth=6;c.beginPath();c.arc(x,148,13,PI*1.15,PI*1.85);c.moveTo(x+d*12,140);c.lineTo(x+d*18,135);c.stroke()}
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,162,13,7,0,0,T),c.fill()
c.lineWidth=2.5;for(const d of[-1,1])for(const k of[-5,0,5])c.beginPath(),c.moveTo(128+d*44+k-2,165),c.lineTo(128+d*44+k+2,159),c.stroke()
c.lineWidth=4;c.fillStyle='#c92a2a';c.beginPath();c.ellipse(128,170,7,8,0,0,T);c.fill();c.stroke()
c.lineWidth=7;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,146)
c.bezierCurveTo(54,74,88,36,128,36);c.bezierCurveTo(168,36,202,74,186,146)
c.quadraticCurveTo(186,116,178,102);c.quadraticCurveTo(170,104,164,112);c.quadraticCurveTo(160,98,150,92);c.quadraticCurveTo(144,104,136,110)
c.quadraticCurveTo(132,96,124,90);c.quadraticCurveTo(118,102,110,108);c.quadraticCurveTo(106,96,96,94);c.quadraticCurveTo(90,104,86,112)
c.quadraticCurveTo(80,104,78,102);c.quadraticCurveTo(70,120,70,146);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=6;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke()
c.restore()
c.fillStyle=NORI;c.lineWidth=5;c.beginPath();c.moveTo(56,196);c.lineTo(50,154);c.lineTo(80,150);c.lineTo(86,196);c.fill();c.stroke()
c.lineWidth=6;c.fillStyle=BOWL;c.beginPath();c.moveTo(32,196);c.quadraticCurveTo(36,250,98,252);c.lineTo(158,252);c.quadraticCurveTo(220,250,224,196);c.fill();c.stroke()
c.save();c.clip();c.strokeStyle='#fff';c.lineWidth=4;c.beginPath();for(let x=24;x<240;x+=12)c.lineTo(x,x%24?236:228);c.stroke();c.restore()
c.strokeStyle='#111';c.beginPath();c.moveTo(32,196);c.quadraticCurveTo(36,250,98,252);c.lineTo(158,252);c.quadraticCurveTo(220,250,224,196);c.stroke()
c.fillStyle='#fff';c.beginPath();c.ellipse(128,196,96,20,0,0,T);c.fill();c.stroke()
c.fillStyle=BR;c.lineWidth=4;c.beginPath();c.ellipse(128,197,84,13,0,0,T);c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.ellipse(84,197,15,7,0,0,T);c.fill();c.stroke()
c.strokeStyle='#f06595';c.lineWidth=2.5;c.beginPath();c.ellipse(84,197,8,3.5,0,0,PI*1.6);c.stroke();c.strokeStyle='#111'
c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.ellipse(172,197,17,8,0,0,T);c.fill();c.stroke()
c.fillStyle='#ff922b';c.lineWidth=3;c.beginPath();c.ellipse(172,197,8,4,0,0,T);c.fill();c.stroke()
c.fillStyle=ONI;c.lineWidth=2.5;for(const[x,y]of[[108,203],[146,204],[198,193]])c.beginPath(),c.ellipse(x,y,4,2.5,0,0,T),c.fill(),c.stroke()
const st=[[100,1.1],[114,.4],[128,2.2],[142,1.6],[156,3]].map(([xb,ph],k)=>[...Array(25)].map((_,j)=>{const s=j/24,xt=128+(k-2)*1.8,xm=128+(xb-128)*.18;return[(1-s)**2*xb+2*(1-s)*s*xm+s*s*xt+5*(1-s*.7)*sin(T*(s*1.6-2*t)+ph),200-62*s]}))
for(const[l,k]of[[10,'#111'],[5,ND]]){c.lineWidth=l;c.strokeStyle=k;for(const p of st){c.beginPath();for(const[x,y]of p)c.lineTo(x,y);c.stroke()}}
for(const d of[-1,1])ds(c,9,4,WOOD,()=>{c.moveTo(192,160+d*4);c.lineTo(118,170+d*7)})
c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(194,166,13,14,.3,0,T);c.fill();c.stroke()
for(const[x,o]of[[42,0],[214,.5]]){const p=(t+o)%1,y=184-46*p,w=7*sin(PI*p);if(w>1)ds(c,w+5,w,'#fff',()=>{for(let j=0;j<=10;j++)c.lineTo(x+5*sin(j/10*T+p*T),y-j*2.6)})}
const sl=sin(4*T*t)>0;if(sl)for(const d of[-1,1])ds(c,7,3,'#fff',()=>{c.moveTo(128+d*16,146);c.lineTo(128+d*22,140)})
}
+47
View File
@@ -0,0 +1,47 @@
// silver-haired girl in the spring wind: long hair and hair ribbon streaming sideways while cherry petals drift past
const{sin,cos,PI}=Math,T=2*PI
export const frames=12,delay=100
const SKIN='#ffe3d1',HAIR='#dee2e6',HD='#adb5bd',HL='#fff',EYE='#f06595',ED='#a61e4d',COAT='#4c6ef5',CD='#364fc7',RB='#ff6b6b',BL='#ffa8a8',PET='#ffc9de'
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2,0,T);c.fill()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const petal=(c,x,y,a,s)=>{c.save();c.translate(x,y);c.rotate(a);c.scale(s,s);c.beginPath();c.moveTo(0,-9);c.quadraticCurveTo(11,-4,6,7);c.lineTo(0,4);c.lineTo(-6,7);c.quadraticCurveTo(-11,-4,0,-9);c.restore();c.fill();c.stroke()}
const petals=(c,t,l)=>{c.fillStyle=PET;c.lineWidth=3;for(const[o,y,n,s]of l){const p=(t*n+o)%1;petal(c,-20+p*296,y+12*sin(p*T*2+o*9),p*T*n+o*7,s)}}
export default(c,t)=>{
const w=k=>sin(T*t-k*1.1),tip=k=>[238+6*cos(T*t-k*1.1)+k*3,74+46*k+9*w(k)]
petals(c,t,[[.1,40,1,1],[.55,96,1,.8],[.8,214,2,1.1]])
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(96,188);c.bezierCurveTo(68,170,64,150,66,120);c.bezierCurveTo(62,70,86,36,128,36)
let[x,y]=tip(0);c.bezierCurveTo(170,34,200,y-24+4*w(0),x,y)
for(let k=1;k<4;k++){const[nx,ny]=tip(k),vx=x-44,vy=(y+ny)/2+6*w(k-.5);c.bezierCurveTo(x-10,y+8,vx+22,vy-10,vx,vy);c.bezierCurveTo(vx+12,vy+2,nx-24,ny-14,nx,ny);[x,y]=[nx,ny]}
c.bezierCurveTo(x-14,y+12,150,214,96,188);c.fill();c.stroke()
c.strokeStyle=HD;c.lineWidth=3;for(const k of[0,1,2,3]){const[a,b]=tip(k);c.beginPath();c.moveTo(186,b-6-8*k*.3);c.bezierCurveTo(200,b-10,a-30,b-6,a-12,b-1);c.stroke()}c.strokeStyle='#111'
c.lineWidth=6;c.fillStyle=COAT;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(62,198,54,250);c.lineTo(202,250);c.quadraticCurveTo(194,198,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(104,190);c.lineTo(128,226);c.lineTo(152,190);c.closePath();c.fill();c.lineWidth=5;c.stroke()
c.strokeStyle=CD;c.lineWidth=4;c.beginPath();c.moveTo(128,226);c.lineTo(128,250);c.stroke();c.strokeStyle='#111'
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,168);c.lineTo(116,192);c.lineTo(128,208);c.lineTo(140,192);c.lineTo(140,168);c.fill();c.beginPath();c.moveTo(116,168);c.lineTo(116,190);c.moveTo(140,168);c.lineTo(140,190);c.stroke()
c.fillStyle=RB;for(const d of[-1,1])c.beginPath(),c.moveTo(128,212),c.lineTo(128+d*16,203),c.lineTo(128+d*16,221),c.closePath(),c.fill(),c.stroke()
c.beginPath();c.arc(128,212,5,0,T);c.fill();c.stroke()
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
eye(c,103,140,-1);eye(c,153,140,1)
c.lineWidth=2.5;c.beginPath();c.moveTo(128,156);c.lineTo(127,159);c.stroke()
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,161,12,6,0,0,T),c.fill()
c.lineWidth=3.5;c.beginPath();c.arc(128,163,7,.2*PI,.8*PI);c.stroke()
const b=2*sin(T*t)
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(72,140)
c.bezierCurveTo(56,74,88,36,128,36);c.bezierCurveTo(168,36,204,74,190,150)
c.quadraticCurveTo(186,118,180+b,102);c.quadraticCurveTo(172,104,166+b,114);c.quadraticCurveTo(162,98,152+b,92);c.quadraticCurveTo(146,104,140+b,112)
c.quadraticCurveTo(134,96,126+b,90);c.quadraticCurveTo(120,102,114+b,110);c.quadraticCurveTo(108,96,98+b,94);c.quadraticCurveTo(92,104,90+b,112)
c.quadraticCurveTo(82,102,80,100);c.quadraticCurveTo(72,116,72,140);c.closePath();c.fill();c.stroke()
c.strokeStyle=HD;c.lineWidth=5;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke();c.strokeStyle='#111'
const rt=(k,o)=>[180+k*18,60+o+k*(4+o*.4)+(k?6:0)*sin(T*t*2-k*1.2)]
for(const o of[-6,10])for(const[l,s]of[[15,'#111'],[8,RB]]){c.lineWidth=l;c.strokeStyle=s;c.beginPath();c.moveTo(...rt(0,o));for(let k=1;k<4;k++){const[a,e]=rt(k,o),[f,g]=rt(k+1,o);c.quadraticCurveTo(a,e,(a+f)/2,(e+g)/2)}c.stroke()}
c.strokeStyle='#111';c.lineWidth=5;c.fillStyle=RB
for(const d of[-1,1])c.beginPath(),c.moveTo(176,58),c.quadraticCurveTo(176+d*8,30,176+d*22,44),c.quadraticCurveTo(176+d*18,66,176,58),c.fill(),c.stroke()
c.beginPath();c.arc(176,58,6,0,T);c.fill();c.stroke()
petals(c,t,[[.3,150,1,1.2],[.7,24,2,.9],[0,232,1,.9],[.45,60,2,1]])
}
+66
View File
@@ -0,0 +1,66 @@
// silver haired girl with low pigtails posing for a selfie with a peace sign, the bunny phone flashes and she squints, sparkles after
const{sin,cos,PI,max}=Math,T=2*PI
export const frames=16,delay=80
const SKIN='#ffe3d1',HAIR='#d0bfff',HD='#9775fa',HL='#f3f0ff',EYE='#f06595',ED='#a61e4d',BL='#ffa8a8',SWT='#fff3bf',HRT='#ff8787',CASE='#faa2c1',SCR='#cc5de8'
const ds=(c,a,b,s,f)=>{for(const[l,k]of[[a,'#111'],[b,s]])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),f(),c.stroke();c.strokeStyle='#111'}
const eye=(c,x,y,d,sq)=>{
if(sq){c.lineWidth=6;c.beginPath();c.moveTo(x-d*14,y-10);c.lineTo(x+d*10,y);c.lineTo(x-d*14,y+10);c.stroke();return}
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2,0,T);c.fill()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const spark=(c,x,y,r)=>{c.beginPath();c.moveTo(x,y-r);for(const[a,b]of[[1,0],[0,1],[-1,0],[0,-1]])c.quadraticCurveTo(x+(a+b)*r*.15,y+(b-a)*r*.15,x+a*r,y+b*r);c.fill();c.stroke()}
const heart=(c,x,y,s)=>{c.save();c.translate(x,y);c.scale(s,s);c.beginPath();c.moveTo(0,8);c.bezierCurveTo(-13,-1,-9,-12,0,-5);c.bezierCurveTo(9,-12,13,-1,0,8);c.restore();c.fill();c.stroke()}
export default(c,t)=>{
const fl=t>=.5&&t<.625,af=t>=.625,pb=-3*max(0,sin(4*T*t))
const head=f=>{c.save();c.translate(128,186);c.rotate(.12);c.translate(-128,-186);f();c.restore()}
head(()=>{
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(196,34,206,96,198,160);c.lineTo(58,160);c.bezierCurveTo(50,96,60,34,128,34);c.fill();c.stroke()
for(const d of[-1,1]){c.save();c.translate(128+d*66,150);c.rotate(-d*.12)
c.fillStyle=HAIR;c.beginPath();c.moveTo(-10,-6);c.bezierCurveTo(d*30-6,10,d*26,60,d*14,92);c.quadraticCurveTo(d*6,104,-d*4,96);c.bezierCurveTo(d*8,60,-d*16,20,-10,-6);c.fill();c.stroke()
c.strokeStyle=HD;c.lineWidth=3;c.beginPath();c.moveTo(d*8,16);c.quadraticCurveTo(d*18,50,d*10,84);c.stroke();c.strokeStyle='#111'
c.fillStyle=SCR;c.lineWidth=5;c.beginPath();c.ellipse(0,0,13,9,d*.4,0,T);c.fill();c.stroke();c.lineWidth=6;c.restore()}
})
c.lineWidth=6;c.fillStyle=SWT;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(62,198,54,250);c.lineTo(202,250);c.quadraticCurveTo(194,198,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle=HRT;c.lineWidth=4;heart(c,128,226,1.3)
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,168);c.lineTo(116,192);c.quadraticCurveTo(128,204,140,192);c.lineTo(140,168);c.fill();c.lineWidth=5;c.beginPath();c.moveTo(116,168);c.lineTo(116,190);c.moveTo(140,168);c.lineTo(140,190);c.stroke()
head(()=>{
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
eye(c,103,140,-1,fl);eye(c,153,140,1,fl)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,162,13,7,0,0,T),c.fill()
c.lineWidth=2.5;for(const d of[-1,1])for(const k of[-5,0,5])c.beginPath(),c.moveTo(128+d*44+k-2,165),c.lineTo(128+d*44+k+2,159),c.stroke()
c.lineWidth=4;c.fillStyle='#c92a2a';c.beginPath();c.moveTo(116,165);c.quadraticCurveTo(128,184,140,165);c.closePath();c.fill();c.stroke()
c.save();c.clip();c.fillStyle='#ff8fab';c.beginPath();c.ellipse(128,178,7,5,0,0,T);c.fill();c.restore()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,150)
c.bezierCurveTo(54,74,88,36,128,36);c.bezierCurveTo(168,36,202,74,186,150)
c.quadraticCurveTo(184,118,178,104);c.quadraticCurveTo(172,108,164,112);c.quadraticCurveTo(160,98,150,92);c.quadraticCurveTo(144,104,136,110)
c.quadraticCurveTo(132,96,124,90);c.quadraticCurveTo(118,102,110,108);c.quadraticCurveTo(106,96,96,94);c.quadraticCurveTo(90,104,84,110)
c.quadraticCurveTo(80,104,78,104);c.quadraticCurveTo(72,124,70,150);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[s,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*s,PI*e),c.stroke()
c.strokeStyle='#111'
})
ds(c,30,19,SWT,()=>{c.moveTo(184,232);c.lineTo(210,170);c.lineTo(204,112)})
c.save();c.translate(196,72);c.rotate(.1)
c.fillStyle=CASE;c.lineWidth=5;for(const d of[-1,1])c.beginPath(),c.ellipse(d*10,-48,6,15,d*.2,0,T),c.fill(),c.stroke()
c.beginPath();c.roundRect(-22,-40,44,80,9);c.fill();c.stroke()
c.fillStyle='#495057';c.lineWidth=3;c.beginPath();c.roundRect(-16,-34,16,20,5);c.fill();c.stroke()
c.fillStyle='#fff';for(const y of[-29,-19])c.beginPath(),c.arc(-8,y,3.5,0,T),c.fill(),c.stroke()
c.fillStyle=fl?'#ffd43b':'#fff';c.beginPath();c.arc(8,-28,3.5,0,T);c.fill();c.stroke()
c.fillStyle='#fff';c.lineWidth=4;heart(c,0,10,1.1)
c.restore()
c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(206,112,13,12,0,0,T);c.fill();c.stroke()
if(fl){const r=t<.5625?1:.75;c.fillStyle='#fff9db';c.lineWidth=5;c.beginPath();for(let k=0;k<16;k++){const q=k%2?16*r:44*r,b=k*PI/8;c.lineTo(206+cos(b)*q,45+sin(b)*q)}c.closePath();c.fill();c.stroke()
c.fillStyle='#ffd43b';c.lineWidth=4;c.beginPath();c.arc(206,45,12*r,0,T);c.fill();c.stroke()}
if(af){const p=(t-.625)/.375,s=sin(PI*p);c.fillStyle='#ffd43b';c.lineWidth=3.5
for(const[x,y,o]of[[150,26,0],[238,104,.25],[236,22,.45]]){const q=p*1.5-o;if(q>0&&q<1)spark(c,x,y,11*sin(PI*q))}
if(s>.2)c.fillStyle=HRT,c.lineWidth=4,heart(c,168,92-46*p,.5+.7*s)}
for(const[l,k]of[[30,'#111'],[19,SWT]])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),c.moveTo(70,250),c.lineTo(56,212),c.lineTo(62,176+pb),c.stroke()
c.strokeStyle='#111'
const hx=62,hy=164+pb
for(const[fx,fy]of[[-12,-32],[6,-34]])ds(c,14,7,SKIN,()=>{c.moveTo(hx,hy);c.lineTo(hx+fx,hy+fy)})
c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(hx,hy+4,13,12,0,0,T);c.fill();c.stroke()
c.beginPath();c.ellipse(hx+8,hy+2,5,8,.6,0,T);c.fill();c.stroke()
}
+68
View File
@@ -0,0 +1,68 @@
// girl with teal twin braids walking her shiba inu on a red leash, both trotting along, the shiba's curly tail wagging
const{sin,cos,PI,abs,max,hypot,sqrt}=Math,T=2*PI
export const frames=16,delay=70
const SKIN='#ffe3d1',HAIR='#a61e4d',HD='#7a1638',HL='#fcc2d7',EYE='#a9744f',ED='#5c3d2e',SW='#fcc419',SWD='#f08c00',SK='#4263eb',SHOE='#a9744f',DOG='#ffa94d',DD='#e8590c',CR='#fff4e6',RED='#fa5252',BL='#ffa8a8'
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.clip();c.beginPath();c.ellipse(x+4,y+2,11.5,15,0,0,T);c.fillStyle=EYE;c.fill();c.lineWidth=2.5;c.stroke()
c.fillStyle=ED;c.beginPath();c.ellipse(x+4,y-8,13,10,0,0,T);c.fill();c.fillStyle='#111';c.beginPath();c.ellipse(x+6,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x+1,y-5,4.5,0,T);c.fill();c.beginPath();c.arc(x+10,y+8,2,0,T);c.fill();c.restore()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const ik=(hx,hy,fx,fy,L)=>{const dx=fx-hx,dy=fy-hy,d=hypot(dx,dy),k=sqrt(max(0,L*L-d*d/4));return[hx+dx/2+dy/d*k,hy+dy/2-dx/d*k]}
const line=(c,pts,w,col)=>{for(const[lw,s]of[[w+8,'#111'],[w,col]]){c.lineWidth=lw;c.strokeStyle=s;c.beginPath();pts.forEach(([x,y],k)=>k?c.lineTo(x,y):c.moveTo(x,y));c.stroke()}c.strokeStyle='#111'}
export default(c,t,i)=>{
const g=2*T*t,d4=4*T*t,gb=-3*abs(sin(g)),db=-2*abs(sin(d4))
c.fillStyle='#dee2e6';c.beginPath();c.ellipse(80,232,34,5,0,0,T);c.ellipse(194,232,40,5,0,0,T);c.fill()
const hip=[80,176+gb],hx=118,hy=150+gb,cx=208,cy=178+db
for(const s of[1,0]){const ph=g+s*PI,f=[hip[0]+14*sin(ph),228-6*max(0,cos(ph))],k=ik(hip[0],hip[1],f[0],f[1]-4,27);line(c,[hip,k,[f[0],f[1]-4]],8,s?'#fff':'#fff')
c.fillStyle=SHOE;c.lineWidth=4;c.beginPath();c.ellipse(f[0]+4,f[1]-1,10,6,0,0,T);c.fill();c.stroke()}
line(c,[[74,132+gb],[66+8*sin(g),150+gb],[64+12*sin(g),166+gb]],8,SW)
c.fillStyle=SKIN;c.lineWidth=4;c.beginPath();c.arc(64+12*sin(g),168+gb,6,0,T);c.fill();c.stroke()
c.translate(0,gb)
c.fillStyle=SK;c.lineWidth=5;c.beginPath();c.moveTo(62,164);c.lineTo(98,164);c.lineTo(108,190);c.lineTo(52,190);c.closePath();c.fill();c.stroke()
c.strokeStyle='#364fc7';c.lineWidth=3;c.beginPath();c.moveTo(72,168);c.lineTo(68,188);c.moveTo(88,168);c.lineTo(92,188);c.stroke();c.strokeStyle='#111'
c.fillStyle=SW;c.lineWidth=5;c.beginPath();c.moveTo(66,126);c.lineTo(94,126);c.quadraticCurveTo(102,146,100,168);c.lineTo(60,168);c.quadraticCurveTo(58,146,66,126);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.moveTo(80,128),c.lineTo(80+d*12,124),c.lineTo(80+d*10,134),c.closePath(),c.fill(),c.stroke()
c.strokeStyle=SWD;c.lineWidth=3;c.beginPath();c.moveTo(62,160);c.lineTo(98,160);c.stroke();c.strokeStyle='#111'
c.translate(0,-gb)
const lx=(hx+cx)/2,ly=max(hy,cy)+26
for(const[w,col]of[[8,'#111'],[3.5,RED]])c.lineWidth=w,c.strokeStyle=col,c.beginPath(),c.moveTo(hx,hy),c.quadraticCurveTo(lx,ly,cx,cy),c.stroke()
c.strokeStyle='#111'
line(c,[[90,132+gb],[104,142+gb],[hx-4,hy-2]],8,SW)
c.fillStyle=SKIN;c.lineWidth=4;c.beginPath();c.arc(hx,hy,6.5,0,T);c.fill();c.stroke()
c.save();c.translate(0,gb)
c.save();c.translate(82,90);c.scale(.5,.5);c.translate(-128,-128)
for(const d of[-1,1]){const sw=d*4+6*sin(g+d);c.lineWidth=8;c.fillStyle=HAIR;for(let k=0;k<4;k++){const y=164+k*22;c.beginPath();c.ellipse(128+d*62+sw*k/3,y,15-k*1.5,13,0,0,T);c.fill();c.stroke()}
c.fillStyle=RED;c.beginPath();c.ellipse(128+d*62+sw,250,9,6,0,0,T);c.fill();c.stroke();c.fillStyle=HAIR;c.beginPath();c.moveTo(128+d*56+sw,254);c.lineTo(128+d*62+sw,272);c.lineTo(128+d*70+sw,254);c.closePath();c.fill();c.stroke()}
c.lineWidth=8;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
if(i==11){c.lineWidth=7;for(const x of[107,157])c.beginPath(),c.moveTo(x-15,142),c.quadraticCurveTo(x,150,x+15,142),c.stroke()}else eye(c,107,140,-1),eye(c,157,140,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(134+d*42,162,12,6,0,0,T),c.fill()
c.lineWidth=5;c.beginPath();c.arc(136,163,9,.15*PI,.85*PI);c.stroke()
c.lineWidth=8;c.fillStyle=HAIR;c.beginPath();c.moveTo(68,150)
c.bezierCurveTo(50,74,88,36,128,36);c.bezierCurveTo(168,36,206,74,188,150)
c.quadraticCurveTo(186,118,178,104);c.quadraticCurveTo(170,100,164,110);c.quadraticCurveTo(156,96,146,92);c.quadraticCurveTo(140,104,132,110)
c.quadraticCurveTo(126,96,118,92);c.quadraticCurveTo(112,104,104,110);c.quadraticCurveTo(96,96,88,96);c.quadraticCurveTo(82,104,80,110);c.quadraticCurveTo(70,118,68,150);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=6;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke()
c.restore();c.restore()
c.translate(0,db)
const leg=(x,ph)=>{const fx=x+7*sin(ph),fy=228-5*max(0,cos(ph))-db;line(c,[[x,192],[fx,fy-4]],8,DOG);c.fillStyle=CR;c.lineWidth=4;c.beginPath();c.ellipse(fx+2,fy-2,7,5,0,0,T);c.fill();c.stroke()}
leg(168,d4+PI);leg(204,d4)
c.save();c.translate(160,176);c.rotate(.25*sin(d4))
for(const[w,col]of[[20,'#111'],[11,DOG]])c.lineWidth=w,c.strokeStyle=col,c.beginPath(),c.arc(-4,-12,10,.3*PI,2.1*PI),c.stroke()
c.strokeStyle=CR;c.lineWidth=11;c.beginPath();c.arc(-4,-12,10,1.7*PI,2.1*PI);c.stroke();c.strokeStyle='#111';c.restore()
c.fillStyle=DOG;c.lineWidth=5;const body=()=>{c.beginPath();c.moveTo(160,190);c.bezierCurveTo(156,166,176,164,196,166);c.quadraticCurveTo(214,166,220,180);c.quadraticCurveTo(222,202,204,204);c.lineTo(170,204);c.quadraticCurveTo(160,202,160,190);c.closePath()}
body();c.fill();c.save();c.clip();c.fillStyle=CR;c.beginPath();c.ellipse(198,206,30,9,0,0,T);c.ellipse(218,192,8,14,0,0,T);c.fill();c.restore();body();c.stroke()
leg(176,d4);leg(212,d4+PI)
c.fillStyle=DOG;c.lineWidth=5;for(const x of[218,234]){c.beginPath();c.moveTo(x-8,160);c.lineTo(x,138);c.lineTo(x+8,158);c.closePath();c.fill();c.stroke()}
c.fillStyle=CR;for(const x of[218,234])c.beginPath(),c.moveTo(x-4,158),c.lineTo(x,146),c.lineTo(x+4,158),c.closePath(),c.fill()
const head=()=>{c.beginPath();c.moveTo(208,170);c.bezierCurveTo(206,146,240,142,244,160);c.quadraticCurveTo(256,164,252,176);c.quadraticCurveTo(246,188,228,186);c.quadraticCurveTo(210,186,208,170);c.closePath()}
c.fillStyle=DOG;head();c.fill();c.save();c.clip();c.fillStyle=CR;c.beginPath();c.ellipse(238,180,18,9,0,0,T);c.fill();c.restore();head();c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(250,168,3.5,3,0,0,T);c.fill()
c.lineWidth=3.5;c.beginPath();c.arc(230,162,5,1.15*PI,1.85*PI);c.stroke()
c.fillStyle='#ff8fab';c.lineWidth=3;c.beginPath();c.moveTo(240,178);c.quadraticCurveTo(242,192+2*sin(d4),248,180);c.closePath();c.fill();c.stroke()
c.lineWidth=3;c.beginPath();c.moveTo(250,172);c.quadraticCurveTo(246,178,240,177);c.stroke()
c.fillStyle=BL;c.beginPath();c.ellipse(224,174,4,2.5,0,0,T);c.fill()
c.fillStyle=RED;c.lineWidth=4;c.beginPath();c.moveTo(206,166);c.lineTo(214,164);c.lineTo(216,190);c.lineTo(208,190);c.closePath();c.fill();c.stroke()
c.fillStyle='#ffd43b';c.beginPath();c.arc(212,194,4,0,T);c.fill();c.stroke()
}
+44
View File
@@ -0,0 +1,44 @@
// shy girl with platinum hime-cut hair peeking out from behind a shoji door, leaning out to blink at you, then hiding again
const{sin,PI}=Math,T=2*PI
export const frames=20,delay=80
const SKIN='#ffe3d1',HAIR='#f1f3f5',HD='#ced4da',HL='#fff',EYE='#9775fa',ED='#6741d9',WOOD='#c98a52',PAPER='#fff9f0',BL='#ffa8a8',DRESS='#a5d8ff',RB='#f783ac'
const ease=x=>x<=0?0:x>=1?1:x*x*(3-2*x)
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2,0,T);c.fill()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
c.lineWidth=2.5;c.beginPath();c.moveTo(x-8,y+18);c.lineTo(x+8,y+18);c.stroke()
}
export default(c,t,i)=>{
const s=ease((t-.06)/.24)-ease((t-.72)/.2),bk=i==11
c.save();c.beginPath();c.rect(64,0,192,256);c.clip();c.translate(-90+112*s,0);c.translate(128,200);c.rotate(.2*s);c.translate(-128,-200)
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,40);c.bezierCurveTo(200,40,212,110,206,250);c.lineTo(50,250);c.bezierCurveTo(44,110,56,40,128,40);c.fill();c.stroke()
c.fillStyle=DRESS;c.beginPath();c.moveTo(100,192);c.quadraticCurveTo(66,200,60,256);c.lineTo(196,256);c.quadraticCurveTo(190,200,156,192);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(102,192);c.quadraticCurveTo(110,214,128,206);c.quadraticCurveTo(146,214,154,192);c.closePath();c.fill();c.lineWidth=5;c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,168);c.lineTo(116,194);c.quadraticCurveTo(128,204,140,194);c.lineTo(140,168);c.fill();c.beginPath();c.moveTo(116,168);c.lineTo(116,192);c.moveTo(140,168);c.lineTo(140,192);c.stroke()
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
if(bk){c.lineWidth=5;for(const x of[103,153])c.beginPath(),c.moveTo(x-14,142),c.quadraticCurveTo(x,149,x+14,142),c.stroke()}
else{eye(c,103,140,-1);eye(c,153,140,1)}
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*40,161,12,6,0,0,T),c.fill()
c.lineWidth=2.5;for(const d of[-1,1])for(const k of[-5,0,5])c.beginPath(),c.moveTo(128+d*40+k-2,164),c.lineTo(128+d*40+k+2,158),c.stroke()
c.lineWidth=3.5;c.beginPath();c.moveTo(123,168);c.quadraticCurveTo(128,165,133,168);c.stroke()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(62,184);c.bezierCurveTo(46,76,86,40,128,40);c.bezierCurveTo(170,40,210,76,194,184)
c.lineTo(176,184);c.quadraticCurveTo(180,140,174,110)
for(let x=160;x>=92;x-=17)c.lineTo(x+8,114),c.lineTo(x,108)
c.lineTo(82,110);c.quadraticCurveTo(76,140,80,184);c.closePath();c.fill();c.stroke()
c.strokeStyle=HD;c.lineWidth=4;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,58,PI*a,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle=RB;c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.moveTo(184,80),c.lineTo(184+d*12,70),c.lineTo(184+d*12,92),c.closePath(),c.fill(),c.stroke()
c.beginPath();c.arc(184,81,5,0,T);c.fill();c.stroke()
c.restore()
c.lineWidth=6;c.fillStyle=WOOD;c.beginPath();c.roundRect(10,4,110,248,6);c.fill();c.stroke()
c.fillStyle=PAPER;c.lineWidth=4;c.beginPath();c.rect(24,18,82,220);c.fill();c.stroke()
c.strokeStyle=WOOD;c.lineWidth=5;c.beginPath()
for(const x of[51,79])c.moveTo(x,20),c.lineTo(x,236)
for(let y=62;y<238;y+=44)c.moveTo(26,y),c.lineTo(104,y)
c.stroke();c.strokeStyle='#111'
c.fillStyle=SKIN;c.lineWidth=4;for(const y of[150,164,178])c.beginPath(),c.ellipse(114,y,9,6.5,0,0,T),c.fill(),c.stroke()
if(s>.98){c.fillStyle=BL;c.lineWidth=3.5;for(const[x,y,a]of[[218,52,-.5],[230,76,0],[224,100,.5]]){c.beginPath();c.ellipse(x,y,7,3.5,a,0,T);c.fill();c.stroke()}}
}
+64
View File
@@ -0,0 +1,64 @@
// skater girl with a gold side ponytail and a backwards cap rolls along and pops an ollie, wheels spinning, speed lines streaming behind
const{sin,cos,PI,min,max,hypot,sqrt}=Math,T=2*PI
export const frames=16,delay=70
const SKIN='#ffe3d1',HAIR='#fab005',HD='#e67700',HL='#fff3bf',EYE='#12b886',ED='#087f5b',CAP='#fa5252',HOOD='#3bc9db',HOD='#1098ad',SHO='#4263eb',DECK='#845ef7',DL='#d0bfff',WH='#fff',BL='#ffa8a8'
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x+3,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x+3,y-8,13,10,0,0,T);c.fill();c.restore()
c.save();c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.clip();c.lineWidth=2.5;c.beginPath();c.ellipse(x+3,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x+5,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x,y-5,4.5,0,T);c.fill();c.beginPath();c.arc(x+9,y+8,2,0,T);c.fill();c.restore()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const ik=(hx,hy,fx,fy,L)=>{const dx=fx-hx,dy=fy-hy,d=hypot(dx,dy),k=sqrt(max(0,L*L-d*d/4));return[hx+dx/2+dy/d*k,hy+dy/2-dx/d*k]}
const line=(c,pts,w,col)=>{for(const[lw,s]of[[w+8,'#111'],[w,col]]){c.lineWidth=lw;c.strokeStyle=s;c.beginPath();pts.forEach(([x,y],k)=>k?c.lineTo(x,y):c.moveTo(x,y));c.stroke()}c.strokeStyle='#111'}
export default(c,t,i)=>{
const p=(t-.3)/.45,air=p>=0&&p<=1,h=air?46*sin(PI*p):0
const ang=air?(p<.3?-.42*sin(PI*p/.3):.12*sin(PI*(p-.3)/.7)):0
const cr=t<.2?0:t<.3?10*(t-.2)/.1:t<.75?10:t<.9?10*(1-(t-.75)/.15):0
const cx=124,cy=212-h,oy=12-h+cr
c.save();c.beginPath();c.rect(0,0,96,256);c.clip()
for(const[k,y]of[[0,140],[1,160],[2,180],[3,200]]){const x=((k*97-t*512)%256+256)%256-60;line(c,[[x,y],[x+46,y]],3,'#fff')}
c.restore()
c.fillStyle='#ced4da';c.beginPath();c.ellipse(cx,236,56*(1-h/110),6*(1-h/110),0,0,T);c.fill()
const B=(x,y)=>[cx+x*cos(ang)-y*sin(ang),cy+x*sin(ang)+y*cos(ang)]
c.save();c.translate(cx,cy);c.rotate(ang)
c.fillStyle='#adb5bd';c.lineWidth=4;for(const x of[-38,38])c.beginPath(),c.rect(x-8,3,16,6),c.fill(),c.stroke()
for(const x of[-38,38]){c.fillStyle=WH;c.lineWidth=4;c.beginPath();c.arc(x,15,8,0,T);c.fill();c.stroke();const a=-T*t*4;c.lineWidth=3;c.beginPath();c.moveTo(x+3*cos(a),15+3*sin(a));c.lineTo(x+7*cos(a),15+7*sin(a));c.stroke()}
c.fillStyle=DECK;c.lineWidth=5;c.beginPath();c.moveTo(-48,-4);c.lineTo(44,-4);c.quadraticCurveTo(54,-6,60,-14);c.quadraticCurveTo(66,-6,60,0);c.quadraticCurveTo(54,5,44,5);c.lineTo(-44,5);c.quadraticCurveTo(-54,5,-60,0);c.quadraticCurveTo(-66,-6,-60,-14);c.quadraticCurveTo(-54,-6,-48,-4);c.closePath();c.fill();c.stroke()
c.strokeStyle=DL;c.lineWidth=3;c.beginPath();c.moveTo(-36,1);c.lineTo(36,1);c.stroke();c.strokeStyle='#111'
c.restore()
const bf=B(-26,-8),ff=B(24,-8),hy=148+oy-cr*.6
const legs=[[114,bf],[132,ff]]
for(const[hx,f]of legs){const k=ik(hx,hy,f[0],f[1]-4,30);line(c,[[hx,hy],k],12,SHO);line(c,[k,[f[0],f[1]-4]],9,SKIN)}
for(const[,f]of legs){c.save();c.translate(f[0],f[1]-2);c.rotate(ang);c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.ellipse(4,-2,13,7,0,0,T);c.fill();c.stroke();c.strokeStyle=CAP;c.lineWidth=3;c.beginPath();c.moveTo(-4,-1);c.lineTo(10,-1);c.stroke();c.restore()}
c.translate(0,oy)
const ar=air?sin(PI*p):0
line(c,[[110,118],[92,130-ar*10],[78,128-ar*22]],8,HOOD)
c.lineWidth=4;c.fillStyle=SKIN;c.beginPath();c.arc(76,127-ar*22,6,0,T);c.fill();c.stroke()
c.fillStyle=HOOD;c.lineWidth=5;c.beginPath();c.moveTo(108,108);c.lineTo(140,108);c.quadraticCurveTo(152,130,146,154);c.lineTo(106,154);c.quadraticCurveTo(100,130,108,108);c.closePath();c.fill();c.stroke()
c.fillStyle=HOD;c.beginPath();c.moveTo(106,108);c.quadraticCurveTo(124,124,142,108);c.quadraticCurveTo(124,100,106,108);c.fill();c.stroke()
c.lineWidth=3.5;c.beginPath();c.moveTo(114,138);c.lineTo(138,138);c.lineTo(136,150);c.lineTo(116,150);c.closePath();c.stroke()
line(c,[[138,116],[156,124+ar*4],[170,116-ar*14]],8,HOOD)
c.lineWidth=4;c.fillStyle=SKIN;c.beginPath();c.arc(172,115-ar*14,6,0,T);c.fill();c.stroke()
c.save();c.translate(126,76);c.scale(.5,.5);c.translate(-128,-128)
c.save();c.translate(62,92);c.rotate(.5+.15*sin(T*t*2)+.25*ar)
c.lineWidth=8;c.fillStyle=HAIR;c.beginPath();c.moveTo(0,-8);c.bezierCurveTo(-50,0,-70,60,-60,110);c.quadraticCurveTo(-40,90,-30,110);c.bezierCurveTo(-34,60,-12,30,14,12);c.closePath();c.fill();c.stroke()
c.strokeStyle=HD;c.lineWidth=5;c.beginPath();c.moveTo(-10,10);c.bezierCurveTo(-36,30,-46,60,-46,90);c.stroke();c.strokeStyle='#111'
c.fillStyle=CAP;c.lineWidth=7;c.beginPath();c.ellipse(0,0,13,16,.4,0,T);c.fill();c.stroke();c.restore()
c.lineWidth=8;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
if(i==2){c.lineWidth=7;for(const x of[107,157])c.beginPath(),c.moveTo(x-15,142),c.quadraticCurveTo(x,150,x+15,142),c.stroke()}else eye(c,107,140,-1),eye(c,157,140,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(132+d*42,162,12,6,0,0,T),c.fill()
c.lineWidth=5;c.fillStyle='#c92a2a';c.beginPath()
if(air)c.moveTo(118,164),c.quadraticCurveTo(132,186,146,164),c.closePath(),c.fill();else c.arc(132,164,9,.15*PI,.85*PI)
c.stroke()
c.lineWidth=8;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,140)
c.bezierCurveTo(56,90,80,64,128,64);c.bezierCurveTo(176,64,200,90,186,140)
c.quadraticCurveTo(184,118,178,104);c.quadraticCurveTo(170,100,164,110);c.quadraticCurveTo(156,96,146,92);c.quadraticCurveTo(140,104,132,110)
c.quadraticCurveTo(126,96,118,92);c.quadraticCurveTo(112,104,104,110);c.quadraticCurveTo(96,96,88,96);c.quadraticCurveTo(82,104,80,110);c.quadraticCurveTo(72,118,70,140);c.closePath();c.fill();c.stroke()
c.fillStyle=CAP;c.beginPath();c.moveTo(66,92);c.bezierCurveTo(60,30,196,30,190,92);c.quadraticCurveTo(128,78,66,92);c.closePath();c.fill();c.stroke()
c.beginPath();c.moveTo(70,84);c.quadraticCurveTo(40,80,22,96);c.quadraticCurveTo(44,100,70,94);c.closePath();c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=6;c.beginPath();c.arc(128,90,50,PI*1.2,PI*1.38);c.stroke();c.strokeStyle='#111'
c.fillStyle='#fff';c.lineWidth=6;c.beginPath();c.arc(128,40,8,0,T);c.fill();c.stroke()
c.restore()
}
+57
View File
@@ -0,0 +1,57 @@
// navy-haired girl with a cold: her nose tickles, she tips back "ah... ah..." and a big achoo burst jerks her forward, then a sniffle
const{sin,cos,PI,min,round}=Math,T=2*PI
export const frames=20,delay=80
const SKIN='#ffe3d1',HAIR='#0c8599',HD='#0b7285',HL='#c5f6fa',EYE='#40c057',ED='#2b8a3e',SW='#d0ebff',SWD='#74c0fc',SC='#ff6b6b',NOSE='#ff8787',DROP='#a5d8ff',BURST='#fff3bf',MO='#c92a2a',BL='#ffa8a8'
const ease=x=>x<=0?0:x>=1?1:x*x*(3-2*x)
const eye=(c,x,y,d,l,u)=>{
const ly=y-14+22*l
c.save();c.beginPath();c.moveTo(x-24,ly+6);c.quadraticCurveTo(x,ly-4,x+24,ly+6);c.lineTo(x+24,y+30);c.lineTo(x-24,y+30);c.clip()
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.beginPath();c.ellipse(x,y+2-u,11.5,15,0,0,T);c.fillStyle=EYE;c.fill();c.lineWidth=2.5;c.stroke()
c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8-u,12,9,0,0,T);c.fill()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3-u,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5-u,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8-u,2,0,T);c.fill();c.restore()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,ly+6);c.quadraticCurveTo(x,ly-4,x+16,ly+6);c.moveTo(x+d*15,ly+5);c.lineTo(x+d*21,ly);c.stroke()
c.lineWidth=2.5;c.beginPath();c.moveTo(x-8,y+18);c.lineTo(x+8,y+18);c.stroke()
}
export default(c,t)=>{
const a=min(1,t/.4),sn=t>=.45&&t<.6,k=(t-.45)/.15,r=(t-.6)/.4,rc=t>=.6
const dy=sn?6:rc?round(6*(1-ease(r))):-round(6*a),fy=sn?3:rc?round(3*(1-ease(r))):-round(5*a)
if(sn){c.fillStyle=BURST;c.lineWidth=6;const s=1-k*.5;c.beginPath();for(let j=0;j<24;j++){const b=j*PI/12,rr=(j%2?96:132)*s;c.lineTo(128+cos(b)*rr,172+sin(b)*rr)}c.closePath();c.fill();c.stroke()}
c.lineWidth=6;c.fillStyle=SW;c.beginPath();c.moveTo(100,192);c.quadraticCurveTo(62,200,54,250);c.lineTo(202,250);c.quadraticCurveTo(194,200,156,192);c.closePath();c.fill();c.stroke()
c.strokeStyle=SWD;c.lineWidth=3;c.beginPath();for(const x of[80,96,160,176])c.moveTo(x,226),c.lineTo(x+(x<128?-2:2),248);c.stroke();c.strokeStyle='#111'
c.fillStyle=SKIN;c.beginPath();c.rect(116,166,24,26);c.fill()
c.save();c.translate(0,dy)
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,36);c.bezierCurveTo(196,36,206,96,198,136);c.lineTo(216,150);c.lineTo(198,154);c.lineTo(210,170);c.lineTo(186,164);c.lineTo(70,164);c.lineTo(46,170);c.lineTo(58,154);c.lineTo(40,150);c.lineTo(58,136);c.bezierCurveTo(50,96,60,36,128,36);c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
c.save();c.translate(0,fy)
if(sn){c.lineWidth=5.5;c.beginPath();c.moveTo(91,131);c.lineTo(113,140);c.lineTo(91,149);c.moveTo(165,131);c.lineTo(143,140);c.lineTo(165,149);c.stroke()}
else{const l=rc?.45-.3*r:.15+.55*a,u=rc?0:3*a;eye(c,103,140,-1,l,u);eye(c,153,140,1,l,u)
if(rc&&r<.7){c.fillStyle=DROP;c.lineWidth=3;for(const x of[86,170])c.beginPath(),c.ellipse(x,152+10*r,3.5,5,0,0,T),c.fill(),c.stroke()}}
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,161,13,7,0,0,T),c.fill()
c.lineWidth=2.5;for(const d of[-1,1])for(const j of[-5,0,5])c.beginPath(),c.moveTo(128+d*42+j-2,164),c.lineTo(128+d*42+j+2,158),c.stroke()
c.fillStyle=NOSE;c.beginPath();c.ellipse(128,156,6,4.5,0,0,T);c.fill()
c.lineWidth=2.5;if(!sn&&!rc&&a>.4){c.fillStyle='#111';for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*3,157,1.6,2.2,0,0,T),c.fill()}else{c.beginPath();c.moveTo(128,154);c.lineTo(127,158);c.stroke()}
c.lineWidth=3.5;c.fillStyle=MO;c.beginPath()
if(sn)c.ellipse(128,173,14,11,0,0,T),c.fill(),c.stroke()
else if(rc){c.moveTo(120,170);c.quadraticCurveTo(124,166,128,170);c.quadraticCurveTo(132,174,136,170);c.stroke()}
else c.ellipse(128,169,4+4*a,3+6*a,0,0,T),c.fill(),c.stroke()
if(rc&&r<.6){c.fillStyle=DROP;c.lineWidth=3;const s=1-r/.6;c.beginPath();c.ellipse(128,162+3*s,3*s+1,5*s+1,0,0,T);c.fill();c.stroke()}
c.restore()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(64,152)
c.bezierCurveTo(46,74,88,36,128,36);c.bezierCurveTo(168,36,210,74,192,152)
c.quadraticCurveTo(190,124,182,110);c.lineTo(174,114);c.quadraticCurveTo(170,100,160,92);c.quadraticCurveTo(152,104,142,110)
c.quadraticCurveTo(138,96,128,86);c.quadraticCurveTo(120,102,108,108);c.quadraticCurveTo(106,96,94,90);c.quadraticCurveTo(88,104,82,112)
c.lineTo(74,110);c.quadraticCurveTo(68,128,64,152);c.closePath();c.fill();c.stroke()
c.beginPath();c.moveTo(120,40);c.quadraticCurveTo(116,20,100,18);c.quadraticCurveTo(116,28,112,40);c.moveTo(134,40);c.quadraticCurveTo(140,22,154,24);c.quadraticCurveTo(142,30,142,40);c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[b,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*b,PI*e),c.stroke()
c.strokeStyle='#111'
if(!sn&&!rc){c.lineWidth=4;c.beginPath();for(const d of[-1,1])c.moveTo(128+d*38,124+fy),c.quadraticCurveTo(128+d*24,112+fy,128+d*13,114+fy);c.stroke()}
c.restore()
c.lineWidth=6;c.fillStyle=SC;c.beginPath();c.moveTo(94,184);c.quadraticCurveTo(128,198,162,184);c.quadraticCurveTo(170,196,162,208);c.quadraticCurveTo(128,222,94,208);c.quadraticCurveTo(86,196,94,184);c.fill();c.stroke()
c.beginPath();c.moveTo(150,206);c.lineTo(166,246);c.lineTo(184,238);c.lineTo(164,200);c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=5;c.beginPath();for(const x of[110,128,146])c.moveTo(x,193+(x==128?4:0)),c.lineTo(x,213+(x==128?3:0));c.moveTo(160,220);c.lineTo(174,214);c.moveTo(165,232);c.lineTo(179,226);c.stroke()
c.strokeStyle='#111'
if(!sn&&!rc&&a>.15){for(const[l,s]of[[7,'#111'],[3,'#fff']]){c.lineWidth=l;c.strokeStyle=s;c.beginPath();for(const d of[-1,1])c.moveTo(128+d*14,150+dy+fy),c.quadraticCurveTo(128+d*19,146+dy+fy+(t*20%2<1?-3:3),128+d*24,150+dy+fy);c.stroke()}c.strokeStyle='#111'}
if(sn){c.fillStyle='#74c0fc';c.lineWidth=2.5;for(let j=0;j<9;j++){const b=-.15*PI+j*PI*1.3/8,d=40+76*(k+.3),x=128+cos(b)*d,y=176+dy+sin(b)*d*.8;c.save();c.translate(x,y);c.rotate(b-PI/2);c.scale(1.4,1.4);c.beginPath();c.moveTo(0,8);c.quadraticCurveTo(6,-2,0,-6);c.quadraticCurveTo(-6,-2,0,8);c.fill();c.stroke();c.restore()}}
}
+38
View File
@@ -0,0 +1,38 @@
// worn-out auburn-haired girl slumped over her desk with blank eyes, her little ghost soul drifting out of her mouth and getting sucked back in
const{sin,cos,PI,max}=Math,T=2*PI
export const frames=16,delay=90
const SKIN='#ffe3d1',HAIR='#c8642c',HD='#9c4a1c',HL='#f5c29f',HOOD='#dee2e6',HDK='#adb5bd',DESK='#e8b07a',DD='#c47f45',BAG='#d0bfff',PAPER='#fff'
export default(c,t)=>{
const s=(1-cos(T*t))/2,a=t*T
const head=f=>{c.save();c.translate(128,204);c.rotate(-.22);c.translate(-128,-200);f();c.restore()}
head(()=>{c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(198,34,214,96,208,160);c.quadraticCurveTo(212,196,200,212);c.lineTo(56,212);c.quadraticCurveTo(44,196,48,160);c.bezierCurveTo(42,96,58,34,128,34);c.fill();c.stroke()})
c.lineWidth=6;c.fillStyle=HOOD;c.beginPath();c.moveTo(92,196);c.quadraticCurveTo(50,200,40,240);c.lineTo(216,240);c.quadraticCurveTo(206,200,164,196);c.closePath();c.fill();c.stroke()
head(()=>{
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
for(const x of[103,153]){
c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.ellipse(x,142,12,13,0,0,T);c.fill();c.stroke()
c.strokeStyle=BAG;c.lineWidth=3;c.beginPath();c.arc(x,146,15,PI*.25,PI*.75);c.stroke();c.strokeStyle='#111'
}
c.fillStyle='#862e9c';c.lineWidth=4;c.beginPath();c.ellipse(128,170,7,9-3*s,0,0,T);c.fill();c.stroke()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(66,170)
c.bezierCurveTo(46,74,88,36,128,36);c.bezierCurveTo(168,36,210,74,190,170)
c.quadraticCurveTo(184,130,180,110);c.quadraticCurveTo(170,112,168,124);c.quadraticCurveTo(160,104,150,98);c.quadraticCurveTo(146,110,140,116)
c.quadraticCurveTo(132,100,122,94);c.quadraticCurveTo(120,108,112,118);c.quadraticCurveTo(104,102,94,100);c.quadraticCurveTo(92,112,86,120)
c.quadraticCurveTo(80,112,76,110);c.quadraticCurveTo(72,140,66,170);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,b]of[[1.24,1.34],[1.42,1.5],[1.62,1.72]])c.beginPath(),c.arc(128,104,56,PI*a,PI*b),c.stroke()
c.strokeStyle='#111';c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(124,40);c.quadraticCurveTo(118,14,98,14);c.quadraticCurveTo(108,22,114,40);c.fill();c.stroke()
})
c.fillStyle=DESK;c.beginPath();c.roundRect(6,212,244,30,8);c.fill();c.stroke()
c.strokeStyle=DD;c.lineWidth=4;c.beginPath();c.moveTo(22,230);c.lineTo(234,230);c.stroke();c.strokeStyle='#111'
c.lineWidth=5;c.fillStyle=PAPER;c.lineWidth=4;for(let j=0;j<8;j++)c.beginPath(),c.roundRect(14+[0,4,1,5,2,0,3,1][j],203-j*8,56,8,2),c.fill(),c.stroke()
for(const d of[-1,1]){for(const[w,st]of[[30,'#111'],[20,HOOD]])c.lineWidth=w,c.strokeStyle=st,c.beginPath(),c.moveTo(128+d*44,206),c.lineTo(128+d*96,214),c.stroke();c.strokeStyle='#111';c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(128+d*114,215,11,7,0,0,T);c.fill();c.stroke()}
const m=[121.5,174.7],e=[126+80*s+8*sin(2*a)*s,176-122*s],k=.35+.65*s
const tail=()=>{c.beginPath();c.moveTo(m[0],m[1]);c.bezierCurveTo(m[0]+50*s,m[1]+10,e[0]-50*s,e[1]+40*s,e[0],e[1]+8*k)}
for(const[w,st]of[[13*k,'#111'],[6*k,'#fff']])c.lineWidth=w,c.strokeStyle=st,tail(),c.stroke()
c.strokeStyle='#111'
c.save();c.translate(e[0],e[1]);c.scale(k,k);c.rotate(.25*sin(2*a))
c.fillStyle='#fff';c.lineWidth=6;c.beginPath();c.arc(0,-6,20,PI,0);c.lineTo(20,10);for(let j=0;j<4;j++)c.quadraticCurveTo(15-j*10,20,10-j*10,12);c.closePath();c.fill();c.stroke()
c.lineWidth=3;for(const x of[-7,7])c.beginPath(),c.arc(x,-6,4,PI*.15,PI*.85),c.stroke()
c.beginPath();c.ellipse(0,3,2.5,3,0,0,T);c.stroke()
c.restore()
}
+62
View File
@@ -0,0 +1,62 @@
// braided navy haired girl in a cram headband scribbling furiously at her desk, steam puffing from her head, finished pages flying off
const{sin,PI,max,min}=Math,T=2*PI
export const frames=14,delay=85
const SKIN='#ffe3d1',HAIR='#4263eb',HD='#364fc7',EYE='#4dabf7',ED='#1864ab',BL='#ffa8a8',JS='#fa5252',WD='#e0a96d',WDD='#c08552',BK=['#69db7c','#ffd43b','#b197fc','#ff8787','#74c0fc'],TIE='#e03131'
const ds=(c,a,b,s,f)=>{for(const[l,k]of[[a,'#111'],[b,s]])c.lineWidth=l,c.strokeStyle=k,c.beginPath(),f(),c.stroke();c.strokeStyle='#111'}
const P=(u,v)=>{const a=106+90*u,b=98+108*u;return[a+(b-a)*v,190+42*v]}
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,15,0,0,T);c.fill()
c.save();c.clip();c.beginPath();c.ellipse(x+d*-2,y+7,11.5,14,0,0,T);c.fillStyle=EYE;c.fill();c.lineWidth=2.5;c.stroke()
c.save();c.clip();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-3,14,8,0,0,T);c.fill();c.restore()
c.fillStyle='#111';c.beginPath();c.ellipse(x+d*-2,y+9,5.5,7,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x+d*-2-4,y+3,4,0,T);c.fill();c.restore()
c.lineWidth=7;c.beginPath();c.moveTo(x-16,y-4);c.quadraticCurveTo(x,y-14,x+16,y-4);c.moveTo(x+d*15,y-5);c.lineTo(x+d*21,y-10);c.stroke()
}
const page=(c,lines)=>{
c.fillStyle='#fff';c.lineWidth=4;c.beginPath();for(const[u,v]of[[0,0],[1,0],[1,1],[0,1]])c.lineTo(...P(u,v));c.closePath();c.fill();c.stroke()
c.strokeStyle='#495057';c.lineWidth=2.5
for(let j=0;j<3;j++){const e=min(1,max(0,lines-j));if(e<=0)continue;c.beginPath();for(let s=0;s<=e*40;s++){const[x,y]=P(.1+.8*s/40,.25+.25*j);c.lineTo(x,y+2.2*sin(s*1.9+j))}c.stroke()}
c.strokeStyle='#111'
}
export default(c,t,i)=>{
const w=t<.75,ln=w?t/.75*3:3,j=min(2,ln|0),e=ln-j,[tx,ty]=P(.1+.8*(w?e:1),.25+.25*(w?j:2)),jx=w?(i%2?2:-2):0,fy=w?0:(t-.75)/.25
const hx=tx+12+jx,hy=ty-14+(w?0:-10*fy)
c.save();c.translate(152,150);c.scale(.8,.8);c.translate(-128,-186)
c.lineWidth=7;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(196,34,206,96,198,160);c.lineTo(58,160);c.bezierCurveTo(50,96,60,34,128,34);c.fill();c.stroke()
c.restore()
c.lineWidth=6;c.fillStyle=JS;c.beginPath();c.moveTo(130,150);c.quadraticCurveTo(92,158,86,196);c.lineTo(218,196);c.quadraticCurveTo(212,158,174,150);c.closePath();c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=3;c.beginPath();c.moveTo(152,160);c.lineTo(152,196);c.moveTo(134,153);c.lineTo(152,170);c.lineTo(170,153);c.stroke();c.strokeStyle='#111'
for(const d of[-1,1]){const bx=152+d*44;c.fillStyle=HAIR;c.lineWidth=4;for(let k=0;k<4;k++)c.beginPath(),c.ellipse(bx+d*k*1.5,140+k*12,8-k*.6,8,0,0,T),c.fill(),c.stroke();c.fillStyle=TIE;c.beginPath();c.ellipse(bx+d*6,186,5,4,0,0,T);c.fill();c.stroke()}
c.save();c.translate(152,150);c.scale(.8,.8);c.translate(-128,-186)
c.lineWidth=7;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
eye(c,103,142,-1);eye(c,153,142,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,164,13,7,0,0,T),c.fill()
c.lineWidth=4;c.beginPath();c.moveTo(116,172);for(let k=1;k<=6;k++)c.lineTo(116+k*4,172+(k%2?-3:2));c.stroke()
c.lineWidth=7;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,150)
c.bezierCurveTo(54,74,88,36,128,36);c.bezierCurveTo(168,36,202,74,186,150)
c.quadraticCurveTo(184,118,178,106);c.quadraticCurveTo(168,108,160,100);c.quadraticCurveTo(150,110,140,112);c.quadraticCurveTo(136,104,128,98)
c.quadraticCurveTo(120,106,114,112);c.quadraticCurveTo(104,110,96,100);c.quadraticCurveTo(88,108,78,106);c.quadraticCurveTo(72,124,70,150);c.closePath();c.fill();c.stroke()
c.strokeStyle='#111';c.lineWidth=6;c.beginPath();c.moveTo(88,116);c.lineTo(116,124);c.moveTo(140,124);c.lineTo(168,116);c.stroke()
for(const k of[1,-1])ds(c,13,6,'#fff',()=>{c.moveTo(196,80);c.quadraticCurveTo(214,80+k*6,224,88+k*14)})
c.fillStyle='#fff';c.lineWidth=6;c.beginPath();c.moveTo(66,82);c.quadraticCurveTo(128,58,190,82);c.lineTo(192,98);c.quadraticCurveTo(128,74,64,98);c.closePath();c.fill();c.stroke()
c.fillStyle=TIE;c.lineWidth=3;c.beginPath();c.arc(128,79,7,0,T);c.fill();c.stroke()
c.fillStyle='#fff';c.lineWidth=5;c.beginPath();c.ellipse(194,88,8,9,0,0,T);c.fill();c.stroke()
c.restore()
for(const[d,o]of[[-1,0],[1,.5]]){const p=(t*2+o)%1,s=sin(PI*p);if(s>.15){const x=152+d*(54+26*p),y=46-22*p;c.fillStyle='#fff';c.lineWidth=4;c.beginPath();for(const[ox,oy,r]of[[-6,2,7],[3,-3,8],[9,3,6]])c.moveTo(x+ox*s+r*s,y+oy*s),c.arc(x+ox*s,y+oy*s,r*s,0,T);c.stroke();c.fill()}}
const desk=()=>{c.moveTo(30,184);c.lineTo(226,184);c.lineTo(250,236);c.lineTo(6,236);c.closePath()}
c.fillStyle=WDD;c.lineWidth=6;c.beginPath();c.rect(6,232,244,14);c.fill();c.stroke()
c.fillStyle=WD;c.beginPath();desk();c.fill();c.stroke()
for(let k=0;k<5;k++){const y=206-k*18,x=18+(k%2?6:0)-(k==3?4:0);c.fillStyle=BK[k];c.lineWidth=5;c.beginPath();c.rect(x,y,72-k*3,18);c.fill();c.stroke();c.fillStyle='#fff';c.lineWidth=3;c.beginPath();c.rect(x+60-k*3,y+4,8,10);c.fill();c.stroke()}
page(c,0)
if(w)page(c,ln)
else{c.save();c.translate(152+130*fy,211-40*fy-30*fy*fy);c.rotate(1.2*fy);c.translate(-152,-211);page(c,3);c.restore()}
ds(c,20,11,JS,()=>{c.moveTo(108,166);c.lineTo(96,198);c.lineTo(102,214)})
c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(104,214,10,9,0,0,T);c.fill();c.stroke()
ds(c,20,11,JS,()=>{c.moveTo(196,166);c.lineTo(214,190);c.lineTo(hx+6,hy+4)})
const px=w?tx+jx:hx-12,py=w?ty:hy+14
ds(c,10,5,'#ffd43b',()=>{c.moveTo(px+2,py-3);c.lineTo(px+20,py-30)})
ds(c,10,5,'#ff8fab',()=>{c.moveTo(px+20,py-30);c.lineTo(px+23,py-35)})
c.fillStyle='#ffe8cc';c.lineWidth=3;c.beginPath();c.moveTo(px,py);c.lineTo(px+5,py-2);c.lineTo(px+2,py-7);c.closePath();c.fill();c.stroke()
c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(hx,hy,10,9,0,0,T);c.fill();c.stroke()
if(w)for(const[d,o]of[[1,0],[-1,.33],[1,.66]]){const p=(t*6+o)%1;if(p<.8){const x=tx+d*(8+16*p),y=ty-6-14*sin(PI*p);c.fillStyle='#ffc9c9';c.lineWidth=2.5;c.beginPath();c.rect(x-2.5,y-2.5,5,5);c.fill();c.stroke()}}
}
+66
View File
@@ -0,0 +1,66 @@
// chibi with chocolate double buns trembling over a low table, flipping it off screen with a roar, then calmly sliding a new one back in
const{sin,cos,PI,max,min}=Math,T=2*PI
export const frames=20,delay=70
const SKIN='#ffe3d1',HAIR='#7b4a2e',HD='#5c3520',HL='#d9a47c',TEE='#d0bfff',TD='#9775fa',RIB='#ff6b6b',WOOD='#e8a35c',WD='#b8742f',BL='#ffa8a8',CUP='#fff',TEA='#69db7c',RG='#f03e3e'
const ez=(t,a,b)=>{const x=min(1,max(0,(t-a)/(b-a)));return x*x*(3-2*x)}
const table=(c,x,y,r)=>{
c.save();c.translate(x,y);c.rotate(r)
c.lineWidth=6;c.fillStyle=WD
for(const d of[-1,1])c.beginPath(),c.roundRect(d*58-7,4,14,40,4),c.fill(),c.stroke()
c.beginPath();c.ellipse(0,6,94,16,0,0,PI);c.lineTo(-94,0);c.ellipse(0,0,94,16,0,PI,0,true);c.closePath();c.fill();c.stroke()
c.fillStyle=WOOD;c.beginPath();c.ellipse(0,0,94,16,0,0,T);c.fill();c.stroke()
c.strokeStyle='#ffd8a8';c.lineWidth=3;c.beginPath();c.ellipse(-6,-2,60,8,0,PI*1.1,PI*1.6);c.stroke();c.strokeStyle='#111'
c.restore()
}
const cup=(c,x,y,r)=>{c.save();c.translate(x,y);c.rotate(r);c.fillStyle=CUP;c.lineWidth=5;c.beginPath();c.moveTo(-12,-14);c.lineTo(12,-14);c.lineTo(9,6);c.quadraticCurveTo(0,10,-9,6);c.closePath();c.fill();c.stroke();c.fillStyle=TEA;c.beginPath();c.ellipse(0,-14,12,4,0,0,T);c.fill();c.stroke();c.restore()}
const eyes=(c,m)=>{
for(const d of[-1,1]){const x=128+d*25,y=140
if(m==2){c.lineWidth=6;c.beginPath();c.moveTo(x-10,y+2);c.lineTo(x+10,y+2);c.stroke();continue}
c.fillStyle='#fff';c.lineWidth=5;c.beginPath();c.ellipse(x,y,13,15,0,0,T);c.fill();c.stroke()
c.fillStyle='#111';c.beginPath();c.arc(x,y+(m?0:3),m?3.5:6,0,T);c.fill()
if(!m){c.fillStyle=SKIN;c.beginPath();c.moveTo(x-d*18,y-20);c.lineTo(x-d*18,y-12);c.lineTo(x+d*18,y);c.lineTo(x+d*18,y-20);c.fill();c.lineWidth=6;c.beginPath();c.moveTo(x-d*15,y-11);c.lineTo(x+d*15,y-1);c.stroke()}
}
}
export default(c,t)=>{
const p=(t-.25)/.25,fly=t>=.25&&t<.5,sl=ez(t,.6,.8),u=ez(t,.24,.3)-ez(t,.64,.8),m=t<.25?0:t<.6?1:2,tr=t<.25?2*sin(t*T*12):0
const sx=[128-66,128+66],hx=d=>128+d*(66+12*u),hy=184-140*u
c.save();c.translate(128,24);c.scale(.75,.75);c.translate(-128,-36)
c.lineWidth=7;c.fillStyle=HAIR;for(const d of[-1,1])c.beginPath(),c.arc(128+d*50,44,26,0,T),c.fill(),c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const d of[-1,1])c.beginPath(),c.arc(128+d*50,44,14,d<0?PI*.9:PI*1.6,d<0?PI*1.6:PI*2.3),c.stroke();c.strokeStyle='#111'
c.fillStyle=RIB;c.lineWidth=6;for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*34,58),c.lineTo(128+d*22,44),c.lineTo(128+d*20,66),c.closePath(),c.fill(),c.stroke()
c.restore()
c.lineWidth=6;c.fillStyle='#4c6ef5';c.beginPath();c.moveTo(92,196);c.lineTo(164,196);c.lineTo(196,236);c.quadraticCurveTo(128,250,60,236);c.closePath();c.fill();c.stroke()
c.strokeStyle='#364fc7';c.lineWidth=3;for(const x of[-34,-12,12,34])c.beginPath(),c.moveTo(128+x*.6,200),c.lineTo(128+x,240),c.stroke();c.strokeStyle='#111'
c.lineWidth=6;c.fillStyle=TEE;c.beginPath();c.moveTo(104,136);c.quadraticCurveTo(76,142,80,200);c.lineTo(176,200);c.quadraticCurveTo(180,142,152,136);c.closePath();c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(118,128);c.lineTo(118,140);c.quadraticCurveTo(128,148,138,140);c.lineTo(138,128);c.fill();c.lineWidth=5;c.beginPath();c.moveTo(118,128);c.lineTo(118,139);c.moveTo(138,128);c.lineTo(138,139);c.stroke()
const arms=()=>{for(const d of[-1,1]){const x=hx(d),y=hy+(u?0:tr);for(const[w,s]of[[24,'#111'],[14,TEE]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(128+d*32,150),c.quadraticCurveTo(128+d*(56+20*u),168-60*u,x,y),c.stroke();c.strokeStyle='#111';c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(x,y,11,10,0,0,T);c.fill();c.stroke()}}
if(u>.5)arms()
c.save();c.translate(128,24);c.scale(.75,.75);c.translate(-128,-36)
c.lineWidth=7;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
eyes(c,m)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,164,11,5.5,0,0,T),c.fill()
if(m==0){c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.roundRect(112,162,32,14,4);c.fill();c.stroke();c.lineWidth=3;c.beginPath();c.moveTo(112,169);c.lineTo(144,169);for(const x of[120,128,136])c.moveTo(x,162),c.lineTo(x,176);c.stroke()}
else if(m==1){c.fillStyle='#c92a2a';c.lineWidth=4.5;c.beginPath();c.roundRect(110,158,36,26,9);c.fill();c.stroke();c.fillStyle='#ff8fab';c.beginPath();c.ellipse(128,181,10,5,0,PI,0);c.fill()}
else{c.lineWidth=4;c.beginPath();c.moveTo(120,170);c.lineTo(136,170);c.stroke()}
c.lineWidth=7;c.fillStyle=HAIR;c.beginPath();c.moveTo(68,140)
c.bezierCurveTo(54,74,88,36,128,36);c.bezierCurveTo(168,36,202,74,188,140)
c.quadraticCurveTo(186,114,178,102);c.lineTo(166,112);c.quadraticCurveTo(160,98,150,94);c.lineTo(140,108)
c.quadraticCurveTo(132,96,122,92);c.lineTo(112,108);c.quadraticCurveTo(104,96,94,96);c.lineTo(86,112)
c.lineTo(78,104);c.quadraticCurveTo(70,120,68,140);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=6;for(const[a,b]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*b),c.stroke()
c.strokeStyle='#111';c.lineWidth=7;if(m<2)c.beginPath(),c.moveTo(86,110),c.lineTo(114,122),c.moveTo(170,110),c.lineTo(142,122),c.stroke()
c.restore()
if(m==1)for(const d of[-1,1])for(const[w,s]of[[9,'#111'],[4,RG]]){c.lineWidth=w;c.strokeStyle=s;c.beginPath();c.moveTo(128+d*76,40);c.lineTo(128+d*90,30);c.moveTo(128+d*80,62);c.lineTo(128+d*100,58);c.moveTo(128+d*74,18);c.lineTo(128+d*82,4);c.stroke()}
c.strokeStyle='#111'
if(fly){
table(c,128+190*p,184-170*p+60*p*p,-p*PI*1.2)
const cx=150+130*p,cy=166-260*p+120*p*p;cup(c,cx,cy,p*PI*2)
c.fillStyle=TEA;c.lineWidth=3.5;if(p>.25)for(let k=1;k<4;k++){const pp=max(0,p-k*.08);c.beginPath();c.arc(150+130*pp-k*5,166-260*pp+120*pp*pp+k*8,6-k,0,T);c.fill();c.stroke()}
}else if(t<.25||t>=.6){
const x=t<.25?128+tr*.5:-110+238*sl
table(c,x,184,0);cup(c,x+22,166,0)
if(t>=.6&&t<.8)for(const y of[170,190,206])for(const[w,s]of[[9,'#111'],[4,'#fff']])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(x-100-y%3*6,y),c.lineTo(x-130-y%3*6,y),c.stroke()
c.strokeStyle='#111'
}
if(u<=.5)arms()
}
+38
View File
@@ -0,0 +1,38 @@
// caramel-braided girl bawling waterfall tears, two streams arcing out of her shut eyes and splashing into puddles
const{sin,cos,PI,max}=Math,T=2*PI
export const frames=12,delay=70
const SKIN='#ffe3d1',HAIR='#f4b860',HD='#d4892a',HL='#fff0d4',TOP='#ffc078',TIE='#4dabf7',BL='#ffa8a8',WA='#74c0fc',WD='#339af0',MO='#c92a2a',TG='#ff8fab'
export default(c,t)=>{
const w=sin(3*T*t),a=t*T
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(196,34,206,96,198,150);c.lineTo(58,150);c.bezierCurveTo(50,96,60,34,128,34);c.fill();c.stroke()
c.fillStyle=WA;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*92,238,32,11,0,0,T),c.fill(),c.stroke()
c.fillStyle=TOP;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(66,198,60,256);c.lineTo(196,256);c.quadraticCurveTo(190,198,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';for(const d of[-1,1])c.beginPath(),c.moveTo(128,206),c.quadraticCurveTo(128+d*16,212,128+d*30,192),c.lineTo(128+d*12,188),c.closePath(),c.fill(),c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,166);c.lineTo(116,192);c.lineTo(128,206);c.lineTo(140,192);c.lineTo(140,166);c.fill();c.lineWidth=5;c.beginPath();c.moveTo(116,166);c.lineTo(116,190);c.moveTo(140,166);c.lineTo(140,190);c.stroke()
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
c.lineWidth=6;for(const d of[-1,1]){const x=128+d*25;c.beginPath();c.moveTo(x-d*14,132);c.lineTo(x+d*8,142);c.lineTo(x-d*14,150);c.stroke()}
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*40,163,11,5.5,0,0,T),c.fill()
c.save();c.translate(128,170);c.scale(1.25,1.25);c.translate(-128,-170);c.fillStyle=MO;c.lineWidth=3.5;c.beginPath();c.moveTo(112,170+w);c.quadraticCurveTo(116,164-w,120,168+w);c.quadraticCurveTo(124,164+w,128,168-w);c.quadraticCurveTo(132,164+w,136,168+w);c.quadraticCurveTo(140,164-w,144,170+w);c.quadraticCurveTo(140,184,128,184);c.quadraticCurveTo(116,184,112,170+w);c.fill();c.stroke()
c.save();c.clip();c.fillStyle=TG;c.beginPath();c.ellipse(128,184,9,6,0,0,T);c.fill();c.restore();c.restore()
for(const d of[-1,1]){
c.save();c.translate(128+d*64,146)
for(let k=0;k<5;k++){const y=14+k*17,x=d*(2-k*1.5);c.fillStyle=k%2?HAIR:HD;c.lineWidth=5;c.beginPath();c.ellipse(x,y,12,11,d*.15,0,T);c.fill();c.stroke()}
c.fillStyle=TIE;c.beginPath();c.ellipse(d*-5,100,9,6,0,0,T);c.fill();c.stroke()
c.fillStyle=HAIR;c.beginPath();c.moveTo(d*-5,104);c.quadraticCurveTo(d*-17,120,d*-11,128);c.quadraticCurveTo(d*-3,122,d*3,128);c.quadraticCurveTo(d*5,116,d*-5,104);c.fill();c.stroke()
c.restore()
}
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,146)
c.bezierCurveTo(54,74,88,36,128,36);c.bezierCurveTo(168,36,202,74,186,146)
c.quadraticCurveTo(186,116,178,102);c.quadraticCurveTo(170,104,164,112);c.quadraticCurveTo(160,98,150,92);c.quadraticCurveTo(144,104,136,110)
c.quadraticCurveTo(132,96,124,90);c.quadraticCurveTo(118,102,110,108);c.quadraticCurveTo(106,96,96,94);c.quadraticCurveTo(90,104,86,112)
c.quadraticCurveTo(80,104,78,102);c.quadraticCurveTo(70,120,70,146);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,b]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*b),c.stroke()
c.strokeStyle='#111';c.lineWidth=5;c.beginPath();c.moveTo(88,124);c.lineTo(112,116);c.moveTo(168,124);c.lineTo(144,116);c.stroke()
for(const d of[-1,1]){
const arc=()=>{c.beginPath();c.moveTo(128+d*40,148);c.bezierCurveTo(128+d*86,104,128+d*110,150,128+d*92,236)}
for(const[lw,s]of[[22,'#111'],[14,WA]])c.lineWidth=lw,c.strokeStyle=s,arc(),c.stroke()
c.strokeStyle='#fff';c.lineWidth=4;c.setLineDash([10,18]);c.lineDashOffset=-t*28*3;arc();c.stroke();c.setLineDash([])
c.strokeStyle='#111';c.fillStyle=WA;c.lineWidth=3.5
for(const o of[0,.33,.66]){const p=(t*3+o)%1,k=o*3-1,x=128+d*(92+(18+6*k)*p*(o>.5?-1:1)),y=232-40*p+46*p*p;c.beginPath();c.arc(x,y,5.5*(1-p*.5),0,T);c.fill();c.stroke()}
}
}
+60
View File
@@ -0,0 +1,60 @@
// chibi with short orange hair sprinting late for school, toast in her mouth, scarf and bag flapping, dust puffs and speed lines behind
const{sin,cos,PI,max,min,sqrt,round,abs}=Math,T=2*PI
export const frames=12,delay=60
const SKIN='#ffe3d1',HAIR='#ff922b',HD='#e8590c',HL='#ffd8a8',EYE='#845ef7',ED='#5f3dc4',NAVY='#4263eb',ND='#364fc7',SCARF='#fa5252',SOCK='#fff',SOCKB='#dee2e6',SHOE='#a0522d',BAG='#a9744f',BAGD='#7f5539',CRUST='#d9822b',BREAD='#ffe8a3',BUTTER='#fff3bf',BL='#ffa8a8'
const knee=(hx,hy,fx,fy,l)=>{let vx=fx-hx,vy=fy-hy,d=sqrt(vx*vx+vy*vy);if(d>2*l-.5){const k=(2*l-.5)/d;vx*=k;vy*=k;d=2*l-.5}const h=sqrt(l*l-d*d/4);return[hx+vx/2+vy/d*h,hy+vy/2-vx/d*h,hx+vx,hy+vy]}
const dbl=(c,w,col,pts)=>{for(const[lw,s]of[[w,'#111'],[w-9,col]]){c.lineWidth=lw;c.strokeStyle=s;c.beginPath();c.moveTo(...pts[0]);for(const p of pts.slice(1))c.lineTo(...p);c.stroke()}c.strokeStyle='#111'}
export default(c,t)=>{
const a=t*T,b=round(-5*abs(sin(a))),fl=k=>4*sin(2*a+k)
for(const[y,o,l]of[[56,0,46],[100,.5,64],[150,.25,40],[200,.75,56]]){const p=(t*2+o)%1,x=52-70*p,w=l*min(1,(1-p)*2.5);if(w>4)dbl(c,13,'#fff',[[x,y],[x-w,y]])}
for(const o of[0,.5]){const p=(t*2+o)%1,x=96-60*p,r=11*(1-p)+3;c.fillStyle='#fff';c.beginPath();for(const[dx,dy,s]of[[-r*.7,0,.8],[0,-r*.4,.9],[r*.7,0,.8]])c.moveTo(x+dx+s*r,236+dy),c.arc(x+dx,236+dy-r*.3,s*r,0,T);c.lineWidth=6;c.stroke();c.fill()}
const hip=[126,192+b],sh=[130,152+b]
const leg=(ph,sk)=>{const s=sin(a+ph),cc=cos(a+ph),[kx,ky,fx,fy]=knee(hip[0],hip[1],hip[0]+30*s,236-22*max(0,cc),27)
dbl(c,22,SKIN,[hip,[kx,ky]]);dbl(c,22,sk,[[kx,ky],[fx,fy-4]])
c.fillStyle=SHOE;c.lineWidth=5;c.beginPath();c.ellipse(fx+6,fy-3,14,8,s*.25,0,T);c.fill();c.stroke()}
const arm=ph=>{const al=-.9*sin(a+ph),ex=sh[0]+22*sin(al),ey=sh[1]+22*cos(al),hx=ex+20*sin(al+1.7),hy=ey+20*cos(al+1.7)
dbl(c,23,'#fff',[sh,[ex,ey],[hx,hy]]);c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.arc(hx,hy,9,0,T);c.fill();c.stroke()}
leg(PI,SOCKB);arm(PI)
c.save();c.translate(84,180+b);c.rotate(.25+.18*sin(2*a+1))
c.lineWidth=6;c.fillStyle=BAG;c.beginPath();c.roundRect(-22,-16,44,32,6);c.fill();c.stroke()
c.fillStyle=BAGD;c.beginPath();c.roundRect(-22,-16,44,14,6);c.fill();c.stroke();c.lineWidth=4;c.fillStyle='#ffd43b';c.beginPath();c.roundRect(-4,-4,8,7,2);c.fill();c.stroke()
c.restore()
c.lineWidth=5;c.strokeStyle=BAGD;c.beginPath();c.moveTo(122,146+b);c.lineTo(88,164+b);c.stroke();c.strokeStyle='#111'
c.save();c.translate(140,80+b);c.scale(.9,.9)
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(10,-62);c.bezierCurveTo(-40,-66,-70,-44,-80,-32+fl(0));c.lineTo(-60,-22);c.lineTo(-88,4+fl(1));c.lineTo(-62,10);c.lineTo(-80,36+fl(2));c.lineTo(-50,34);c.quadraticCurveTo(-40,56,-20,56);c.lineTo(30,30);c.closePath();c.fill();c.stroke()
c.restore()
c.lineWidth=6;c.fillStyle='#fff';c.beginPath();c.moveTo(108,140+b);c.quadraticCurveTo(98,160,102,184+b);c.lineTo(152,184+b);c.quadraticCurveTo(158,158,150,140+b);c.closePath();c.fill();c.stroke()
c.fillStyle=NAVY;c.beginPath();c.moveTo(102,180+b);c.lineTo(154,180+b);c.lineTo(168,208+b);c.lineTo(126,212+b);c.lineTo(86,200+b+fl(0));c.closePath();c.fill();c.stroke()
c.strokeStyle=ND;c.lineWidth=3;for(const x of[118,132,146])c.beginPath(),c.moveTo(x,182+b),c.lineTo(x+(x-128)*.25,204+b),c.stroke();c.strokeStyle='#111'
c.fillStyle=SCARF;c.lineWidth=5;c.beginPath();c.moveTo(140,152+b);c.quadraticCurveTo(118,150+b,96,146+b+fl(2));c.lineTo(100,160+b+fl(3));c.quadraticCurveTo(120,160+b,138,160+b);c.closePath();c.fill();c.stroke()
c.fillStyle=NAVY;c.lineWidth=6;c.beginPath();c.moveTo(108,138+b);c.lineTo(150,138+b);c.lineTo(146,154+b);c.lineTo(104,152+b);c.closePath();c.fill();c.stroke()
c.beginPath();c.arc(141,156+b,5,0,T);c.fillStyle=SCARF;c.fill();c.lineWidth=4;c.stroke()
leg(0,SOCK)
c.save();c.translate(140,80+b);c.scale(.9,.9)
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(-6,46);c.lineTo(-6,60);c.lineTo(10,60);c.lineTo(10,46);c.fill()
c.beginPath();c.moveTo(-42,-6);c.bezierCurveTo(-42,40,-4,60,22,60);c.bezierCurveTo(44,58,58,30,58,-6);c.bezierCurveTo(58,-60,-42,-60,-42,-6);c.fill();c.stroke()
for(const[x,rx,d]of[[4,12,-1],[42,9,1]]){
c.fillStyle='#fff';c.beginPath();c.ellipse(x,10,rx,15,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x+rx*.25,12,rx*.8,13,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x+2,4,rx,8,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x+rx*.25,12,rx*.8,13,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x+rx*.35,13,rx*.38,6,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-1,6,3.5,0,T);c.fill()
c.lineWidth=5.5;c.beginPath();c.moveTo(x-rx-2,0);c.quadraticCurveTo(x,-10,x+rx+2,0);c.stroke()
}
c.fillStyle=BL;c.beginPath();c.ellipse(-14,32,10,5,0,0,T);c.fill()
c.fillStyle='#c92a2a';c.lineWidth=3.5;c.beginPath();c.ellipse(30,42,6,5,0,0,T);c.fill();c.stroke()
c.save();c.translate(52,44);c.rotate(-.3+.08*sin(2*a))
c.fillStyle=CRUST;c.lineWidth=5;c.beginPath();c.moveTo(-14,18);c.lineTo(-14,-6);c.bezierCurveTo(-24,-10,-22,-26,-8,-24);c.bezierCurveTo(0,-30,14,-30,16,-22);c.bezierCurveTo(28,-22,26,-8,18,-6);c.lineTo(18,18);c.closePath();c.fill();c.stroke()
c.fillStyle=BREAD;c.beginPath();c.moveTo(-9,14);c.lineTo(-9,-8);c.bezierCurveTo(-16,-12,-14,-20,-6,-19);c.bezierCurveTo(0,-24,12,-24,12,-18);c.bezierCurveTo(20,-16,20,-10,13,-8);c.lineTo(13,14);c.closePath();c.fill()
c.fillStyle=BUTTER;c.lineWidth=3;c.beginPath();c.roundRect(-3,-6,10,8,2);c.fill();c.stroke()
c.restore()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(-46,10)
c.bezierCurveTo(-56,-40,-26,-66,10,-66);c.bezierCurveTo(46,-66,68,-40,62,-4)
c.lineTo(54,-10);c.lineTo(52,-2);c.lineTo(42,-14);c.lineTo(36,-4);c.lineTo(26,-18);c.lineTo(18,-6);c.lineTo(8,-20);c.lineTo(-2,-8)
c.lineTo(-12,-20);c.lineTo(-22,-6);c.lineTo(-30,-14);c.lineTo(-36,2);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[s,e]of[[1.2,1.32],[1.4,1.48],[1.58,1.7]])c.beginPath(),c.arc(10,-12,46,PI*s,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle='#ffd43b';c.lineWidth=4;c.beginPath();c.moveTo(34,-40);c.lineTo(50,-30);c.lineTo(44,-26);c.lineTo(30,-36);c.closePath();c.fill();c.stroke()
const p=(t*2)%1;c.fillStyle='#a5d8ff';c.lineWidth=3.5;c.save();c.translate(-50-30*p,-44-14*p);c.rotate(-.9);c.scale(1-p*.5,1-p*.5);c.beginPath();c.moveTo(0,-10);c.quadraticCurveTo(8,2,0,6);c.quadraticCurveTo(-8,2,0,-10);c.fill();c.stroke();c.restore()
c.restore()
arm(0)
}
+59
View File
@@ -0,0 +1,59 @@
// red-haired tsundere with her arms crossed, turning her nose up with a "hmph" puff, then sneaking a blushing peek back
const{sin,PI}=Math,T=2*PI
export const frames=20,delay=80
const SKIN='#ffe3d1',HAIR='#748ffc',HD='#4c6ef5',HL='#dbe4ff',EYE='#22b8cf',ED='#0b7285',BLZ='#495057',RIB='#ffd43b',BL='#ff8fab',MO='#c92a2a'
const peek=(c,x,y)=>{
c.save();c.beginPath();c.rect(x-20,y-3,40,30);c.clip()
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y+2,13,15,0,0,T);c.fill()
c.beginPath();c.ellipse(x+5,y+4,10,13,0,0,T);c.fillStyle=EYE;c.fill();c.lineWidth=2.5;c.stroke()
c.fillStyle=ED;c.beginPath();c.ellipse(x+5,y-2,11,7,0,0,T);c.fill()
c.fillStyle='#111';c.beginPath();c.ellipse(x+6,y+5,5,7,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x+2,y+1,3.5,0,T);c.fill();c.restore()
c.lineWidth=6;c.beginPath();c.moveTo(x-15,y);c.quadraticCurveTo(x,y-7,x+15,y-1);c.lineTo(x+20,y-6);c.stroke()
c.lineWidth=2.5;c.beginPath();c.moveTo(x-7,y+18);c.lineTo(x+7,y+18);c.stroke()
}
const shut=(c,x,y,d)=>{c.lineWidth=5;c.beginPath();c.moveTo(x-d*14,y+1);c.quadraticCurveTo(x,y+8,x+d*14,y+1);c.lineTo(x+d*19,y-4);c.stroke()}
export default(c,t)=>{
const pk=t>=.5&&t<.8,q=t/.4,sw=.12*sin(T*t)
c.lineWidth=6
c.save();c.translate(178,70);c.rotate(-.2+sw)
c.fillStyle=HAIR;c.beginPath();c.moveTo(-6,0);c.bezierCurveTo(40,6,52,80,34,150);c.quadraticCurveTo(26,170,10,166);c.quadraticCurveTo(30,110,4,26);c.closePath();c.fill();c.stroke()
c.strokeStyle=HD;c.lineWidth=3;c.beginPath();c.moveTo(10,16);c.bezierCurveTo(30,40,38,90,28,140);c.stroke();c.strokeStyle='#111'
c.restore()
c.lineWidth=6;c.fillStyle=HD;c.beginPath();c.moveTo(128,36);c.bezierCurveTo(196,36,206,96,198,156);c.lineTo(58,156);c.bezierCurveTo(50,96,60,36,128,36);c.fill();c.stroke()
c.fillStyle=RIB;c.lineWidth=5;c.beginPath();c.ellipse(178,70,9,13,-.5,0,T);c.fill();c.stroke()
c.lineWidth=6;c.fillStyle=BLZ;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(62,198,54,250);c.lineTo(202,250);c.quadraticCurveTo(194,198,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(104,190);c.lineTo(128,226);c.lineTo(152,190);c.closePath();c.fill();c.lineWidth=5;c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,168);c.lineTo(116,194);c.lineTo(128,208);c.lineTo(140,194);c.lineTo(140,168);c.fill();c.beginPath();c.moveTo(116,168);c.lineTo(116,192);c.moveTo(140,168);c.lineTo(140,192);c.stroke()
c.fillStyle=RIB;for(const d of[-1,1])c.beginPath(),c.moveTo(128,206),c.lineTo(128+d*16,198),c.lineTo(128+d*16,214),c.closePath(),c.fill(),c.stroke()
c.beginPath();c.arc(128,206,5,0,T);c.fill();c.stroke()
c.fillStyle=SKIN;c.lineWidth=5;c.beginPath();c.ellipse(186,214,11,13,-.3,0,T);c.fill();c.stroke()
for(const[a,b]of[[[66,234],[176,216]],[[190,234],[84,218]]]){
const[dx,dy]=[b[0]-a[0],b[1]-a[1]],n=Math.hypot(dx,dy),u=[dx/n,dy/n],e=[b[0]+u[0]*10,b[1]+u[1]*10]
for(const[l,s]of[[34,'#111'],[23,BLZ]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(...a),c.lineTo(...b),c.stroke()
c.lineCap='butt';for(const[l,s]of[[34,'#111'],[22,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(...b),c.lineTo(...e),c.stroke()
c.lineCap='round';c.strokeStyle='#111'
}
c.fillStyle=SKIN;c.lineWidth=5;c.beginPath();c.ellipse(70,214,11,13,.3,0,T);c.fill();c.stroke()
c.lineWidth=2.5;c.beginPath();for(const k of[-4,3])c.moveTo(66,214+k),c.lineTo(76,213+k);c.stroke()
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
if(pk){peek(c,92,138);peek(c,142,138)}else{shut(c,92,138,-1);shut(c,142,138,1)}
c.lineWidth=2.5;c.beginPath();c.moveTo(114,154);c.lineTo(112,158);c.stroke()
const b=pk?1.35:1;c.fillStyle=BL;for(const x of[84,154])c.beginPath(),c.ellipse(x,158,13*b,7*b,0,0,T),c.fill()
c.lineWidth=2.5;for(const x of[84,154])for(const k of pk?[-9,-4,1,6,11]:[-5,0,5])c.beginPath(),c.moveTo(x+k-2,162),c.lineTo(x+k+2,154),c.stroke()
c.lineWidth=3.5;c.beginPath()
if(pk)c.moveTo(102,170),c.quadraticCurveTo(106,166,110,170),c.quadraticCurveTo(114,174,118,170)
else c.moveTo(102,171),c.quadraticCurveTo(110,164,118,171)
c.stroke()
c.save();c.translate(-6,0);c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,150)
c.bezierCurveTo(54,74,88,36,128,36);c.bezierCurveTo(168,36,202,74,190,150)
c.quadraticCurveTo(188,118,182,102);c.lineTo(170,112);c.lineTo(164,96);c.lineTo(150,110);c.lineTo(140,92);c.lineTo(126,108)
c.lineTo(116,90);c.lineTo(102,108);c.lineTo(94,94);c.lineTo(84,110);c.quadraticCurveTo(74,124,70,150);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke()
c.restore();c.strokeStyle='#111';c.lineWidth=4.5;c.beginPath()
if(pk)c.moveTo(80,116),c.lineTo(102,114),c.moveTo(132,114),c.lineTo(154,117)
else c.moveTo(80,113),c.lineTo(102,120),c.moveTo(132,120),c.lineTo(154,113)
c.stroke()
if(t<.4){const s=1.4*sin(PI*q),x=96-56*q,y=168-22*q;if(s>.15){const cs=[[0,0,10],[-9,-6,8],[-8,7,7]];c.fillStyle='#fff';c.lineWidth=7;for(const[a,b,r]of cs)c.beginPath(),c.arc(x+a*s,y+b*s,r*s,0,T),c.stroke();for(const[a,b,r]of cs)c.beginPath(),c.arc(x+a*s,y+b*s,r*s,0,T),c.fill()}}
if(pk){c.fillStyle='#a5d8ff';c.lineWidth=4;const y=96+4*sin(T*(t-.5)/.3*2);c.beginPath();c.moveTo(196,y-12);c.quadraticCurveTo(204,y,196,y+6);c.quadraticCurveTo(188,y,196,y-12);c.fill();c.stroke()}
}
+48
View File
@@ -0,0 +1,48 @@
// vampire girl with a purple hime cut and a high-collared cape that billows, flashing a fang smile while three bats flap around her
const{sin,cos,PI}=Math,T=2*PI
export const frames=12,delay=90
const SKIN='#fff0f0',HAIR='#7048e8',HD='#5f3dc4',HL='#d0bfff',EYE='#fa5252',ED='#a51111',CAPE='#495057',CL='#868e96',LIN='#e03131',DRS='#5c5f66',BL='#ffa8a8',BAT='#5c5f66',BW='#868e96'
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=2.5;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,3.5,8,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,4.5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2,0,T);c.fill()
c.lineWidth=6;c.beginPath();c.moveTo(x-16,y-4);c.quadraticCurveTo(x,y-14,x+16,y-4);c.moveTo(x+d*15,y-5);c.lineTo(x+d*21,y-10);c.stroke()
}
const bat=(c,x,y,s,f)=>{
c.save();c.translate(x,y);c.scale(s,s)
const w=14*cos(f),p=d=>{c.beginPath();c.moveTo(d*6,-2);c.quadraticCurveTo(d*18,-10-w,d*30,-6-w*1.4);c.quadraticCurveTo(d*26,2-w*.6,d*22,4-w*.4);c.quadraticCurveTo(d*18,0,d*15,6);c.quadraticCurveTo(d*11,2,d*6,6);c.closePath()}
for(const[lw,col]of[[10,'#fff'],[4,'#111']]){c.lineWidth=lw;c.strokeStyle=col;for(const d of[-1,1])p(d),c.stroke();c.beginPath();c.ellipse(0,2,8,9,0,0,T);c.moveTo(-6,-4);c.lineTo(-5,-13);c.lineTo(-1,-6);c.moveTo(6,-4);c.lineTo(5,-13);c.lineTo(1,-6);c.stroke()}
c.fillStyle=BW;for(const d of[-1,1])p(d),c.fill()
c.fillStyle=BAT;c.beginPath();c.ellipse(0,2,8,9,0,0,T);c.fill();c.beginPath();c.moveTo(-6,-4);c.lineTo(-5,-13);c.lineTo(-1,-6);c.lineTo(1,-6);c.lineTo(5,-13);c.lineTo(6,-4);c.fill()
c.fillStyle='#ff6b6b';for(const d of[-1,1])c.beginPath(),c.arc(d*3,0,1.8,0,T),c.fill()
c.restore()
}
export default(c,t,i)=>{
c.save();c.translate(128,242);c.scale(.84,.84);c.translate(-128,-256)
const wv=k=>8*sin(T*t*2-k)
c.lineWidth=6;c.fillStyle=CAPE;c.beginPath();c.moveTo(96,186);c.bezierCurveTo(60,196,30+wv(0),230,6+wv(0),268);for(let k=0;k<5;k++){const x=6+(k+1)*48.8;c.quadraticCurveTo(x-24,252+wv(k+1)*.5,x+(k<4?0:wv(5)),268+(k<4?wv(k+1)*.4:wv(5)))}c.bezierCurveTo(226+wv(5),230,196,196,160,186);c.closePath();c.fill();c.stroke()
c.strokeStyle=CL;c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.moveTo(128+d*44,200),c.quadraticCurveTo(128+d*76,228,128+d*(88+wv(2)*.5),262),c.stroke();c.strokeStyle='#111'
for(const d of[-1,1]){c.fillStyle=LIN;c.lineWidth=6;c.beginPath();c.moveTo(128+d*24,184);c.quadraticCurveTo(128+d*84,168,128+d*106,92);c.quadraticCurveTo(128+d*112,160,128+d*66,208);c.closePath();c.fill();c.stroke()}
c.fillStyle=HD;c.beginPath();c.moveTo(128,34);c.bezierCurveTo(200,34,214,96,206,150);c.lineTo(208,226);c.lineTo(48,226);c.lineTo(50,150);c.bezierCurveTo(42,96,56,34,128,34);c.fill();c.stroke()
c.fillStyle=DRS;c.beginPath();c.moveTo(100,190);c.quadraticCurveTo(72,198,68,262);c.lineTo(188,262);c.quadraticCurveTo(184,198,156,190);c.closePath();c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(116,166);c.lineTo(116,194);c.lineTo(140,194);c.lineTo(140,166);c.fill();c.lineWidth=5;c.beginPath();c.moveTo(116,166);c.lineTo(116,192);c.moveTo(140,166);c.lineTo(140,192);c.stroke()
c.fillStyle='#fff';c.lineWidth=4;for(const d of[-1,1])c.beginPath(),c.moveTo(128,196),c.quadraticCurveTo(128+d*22,188,128+d*26,200),c.quadraticCurveTo(128+d*18,206,128+d*22,214),c.quadraticCurveTo(128+d*12,218,128,212),c.closePath(),c.fill(),c.stroke()
for(const y of[220,238])c.beginPath(),c.moveTo(118,y-6),c.quadraticCurveTo(128,y+6,138,y-6),c.quadraticCurveTo(128,y-2,118,y-6),c.fill(),c.stroke()
c.fillStyle=LIN;c.lineWidth=4;c.beginPath();c.ellipse(128,204,8,9,0,0,T);c.fill();c.stroke();c.fillStyle='#fff';c.beginPath();c.arc(125,201,2.5,0,T);c.fill()
c.lineWidth=6;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
if(i==6||i==7){c.lineWidth=6;for(const x of[103,153])c.beginPath(),c.moveTo(x-15,142),c.quadraticCurveTo(x,150,x+15,142),c.stroke()}else eye(c,103,140,-1),eye(c,153,140,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*42,161,11,5,0,0,T),c.fill()
c.lineWidth=3.5;c.fillStyle='#c92a2a';c.beginPath();c.moveTo(116,165);c.quadraticCurveTo(128,182,140,165);c.quadraticCurveTo(128,169,116,165);c.fill();c.stroke()
c.fillStyle='#fff';c.lineWidth=2.5;for(const x of[121,135])c.beginPath(),c.moveTo(x-3.5,167),c.lineTo(x,174),c.lineTo(x+3.5,167.5),c.closePath(),c.fill(),c.stroke()
c.lineWidth=6;c.fillStyle=HAIR;c.beginPath();c.moveTo(66,160)
c.bezierCurveTo(48,74,88,36,128,36);c.bezierCurveTo(168,36,208,74,190,160)
c.lineTo(176,170);c.quadraticCurveTo(182,138,176,104);c.quadraticCurveTo(128,112,80,104);c.quadraticCurveTo(74,138,80,170);c.closePath();c.fill();c.stroke()
c.strokeStyle=HD;c.lineWidth=3;c.beginPath();for(const x of[98,114,142,158])c.moveTo(x,86),c.lineTo(x,104);c.moveTo(184,124);c.lineTo(184,160);c.moveTo(72,124);c.lineTo(72,160);c.stroke()
c.strokeStyle=HL;c.lineWidth=5;for(const[a,e]of[[1.24,1.36],[1.44,1.52],[1.62,1.74]])c.beginPath(),c.arc(128,104,56,PI*a,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle=LIN;c.lineWidth=5;for(const d of[-1,1])c.beginPath(),c.moveTo(170,66),c.lineTo(170+d*18,52),c.lineTo(170+d*16,78),c.closePath(),c.fill(),c.stroke()
c.beginPath();c.arc(170,66,6,0,T);c.fill();c.stroke()
c.restore()
for(const[k,x,y]of[[0,40,50],[1,206,40],[2,212,146]]){const a=T*t+k*2.1;bat(c,x+12*cos(a),y+8*sin(2*a),1.05,T*t*3+k*1.7)}
}
+61
View File
@@ -0,0 +1,61 @@
// chibi girl in earmuffs and a striped scarf packing a snowball, winding up and throwing it off to the side, breath puffing
const{sin,cos,PI,max,min}=Math,T=2*PI
export const frames=16,delay=80
const SKIN='#ffe3d1',HAIR='#a5d8ff',HD='#4dabf7',HL='#e7f5ff',EYE='#9775fa',ED='#5f3dc4',COAT='#748ffc',CD='#4c6ef5',SC='#fa5252',MUFF='#faa2c1',MD='#f06595',BOOT='#a9744f',SN='#fff',SD='#d0ebff',BL='#ffa8a8',Z=.7
const cl=x=>max(0,min(1,x)),ease=x=>x*x*(3-2*x),lerp=(a,b,k)=>a.map((v,j)=>v+(b[j]-v)*k)
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.clip();c.fillStyle=EYE;c.fill();c.fillStyle=ED;c.beginPath();c.ellipse(x,y-8,13,10,0,0,T);c.fill();c.restore()
c.lineWidth=3;c.beginPath();c.ellipse(x,y+2,11.5,15,0,0,T);c.stroke()
c.fillStyle='#111';c.beginPath();c.ellipse(x,y+3,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-4,y-5,5,0,T);c.fill();c.beginPath();c.arc(x+5,y+8,2.5,0,T);c.fill()
c.lineWidth=8;c.beginPath();c.moveTo(x-16,y-6);c.quadraticCurveTo(x,y-20,x+16,y-6);c.moveTo(x+d*15,y-7);c.lineTo(x+d*21,y-12);c.stroke()
}
const ball=(c,x,y,r)=>{if(r<1)return;c.fillStyle=SN;c.lineWidth=4;c.beginPath();c.arc(x,y,r,0,T);c.fill();c.stroke();c.strokeStyle=SD;c.lineWidth=2.5;c.beginPath();c.arc(x+r*.15,y+r*.15,r*.55,.2,1.6);c.stroke();c.strokeStyle='#111'}
const puff=(c,x,y,s)=>{c.fillStyle='#e9ecef';c.lineWidth=3.5;c.beginPath();for(const[a,b,r]of[[0,0,6],[-9,-3,5],[-17,-1,4]])c.moveTo(x+a*s+r*s,y+b*s),c.arc(x+a*s,y+b*s,r*s,0,T);c.stroke();c.fill()}
export default(c,t)=>{
const X=104,Y=232,pk=cl(t/.4),wu=ease(cl((t-.4)/.15)),th=ease(cl((t-.55)/.07)),rc=ease(cl((t-.62)/.3))
const R0=[14,-62],R1=[60,-114],R2=[64,-64],L0=[-14,-62],L1=[-34,-84]
let Rh=lerp(lerp(lerp(R0,R1,wu),R2,th),R0,rc),Lh=lerp(lerp(L0,L1,wu),L0,rc)
if(t<.4){const p=2*sin(PI*pk*6);Rh=[Rh[0],Rh[1]+p];Lh=[Lh[0],Lh[1]-p]}
for(const[x,o]of[[30,0],[200,.5],[150,.25],[240,.75],[60,.6]]){const p=(t+o)%1;c.fillStyle='#fff';c.lineWidth=3;c.beginPath();c.arc(x+8*sin(p*T*2),p*230-10,4,0,T);c.fill();c.stroke()}
c.lineWidth=6;c.fillStyle=SN;c.beginPath();c.moveTo(6,248);c.quadraticCurveTo(10,226,40,222);c.quadraticCurveTo(70,214,104,222);c.quadraticCurveTo(150,212,190,222);c.quadraticCurveTo(232,226,240,248);c.closePath();c.fill();c.stroke()
c.strokeStyle=SD;c.lineWidth=4;c.beginPath();c.moveTo(150,236);c.quadraticCurveTo(180,230,210,236);c.moveTo(30,240);c.quadraticCurveTo(46,234,60,238);c.stroke();c.strokeStyle='#111'
c.save();c.translate(X,Y)
c.fillStyle=BOOT;c.lineWidth=6
for(const d of[-1,1])c.beginPath(),c.moveTo(d*5,-24),c.lineTo(d*5,-2),c.quadraticCurveTo(d*5,2,d*11,2),c.lineTo(d*26,2),c.quadraticCurveTo(d*30,-6,d*22,-8),c.lineTo(d*22,-24),c.closePath(),c.fill(),c.stroke()
const arm=(d,h)=>{for(const[w,s]of[[24,'#111'],[13,COAT]])c.lineWidth=w,c.strokeStyle=s,c.beginPath(),c.moveTo(d*18,-84),c.lineTo(...h),c.stroke();c.strokeStyle='#111'}
c.lineWidth=6;c.fillStyle=COAT;c.beginPath();c.moveTo(-22,-92);c.quadraticCurveTo(-30,-60,-40,-26);c.quadraticCurveTo(0,-16,40,-26);c.quadraticCurveTo(30,-60,22,-92);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();c.moveTo(-40,-26);c.quadraticCurveTo(0,-16,40,-26);c.lineTo(41,-20);c.quadraticCurveTo(0,-8,-41,-20);c.closePath();c.fill();c.stroke()
c.strokeStyle=CD;c.lineWidth=4;c.beginPath();c.moveTo(0,-84);c.lineTo(0,-20);c.stroke();c.strokeStyle='#111'
const fl=sin(T*t*2)
c.fillStyle=SC;c.lineWidth=5;c.beginPath();c.moveTo(-6,-90);c.lineTo(-10,-58);c.lineTo(2,-60+fl*2);c.lineTo(6,-88);c.closePath();c.fill();c.stroke()
c.strokeStyle='#fff';c.lineWidth=3;for(const y of[-80,-70])c.beginPath(),c.moveTo(-7,y),c.lineTo(4,y+1),c.stroke();c.strokeStyle='#111'
c.beginPath();c.roundRect(-26,-98,52,14,7);c.fill();c.stroke()
c.save();c.translate(0,-86);c.scale(Z,Z);c.translate(-128,-186)
c.lineWidth=8;c.fillStyle=HD;c.beginPath();c.moveTo(128,48);c.bezierCurveTo(60,48,56,110,68,150);c.lineTo(188,150);c.bezierCurveTo(200,110,196,48,128,48);c.fill();c.stroke()
c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
const hap=t>=.55&&t<.8
if(hap){c.lineWidth=8;for(const x of[103,153])c.beginPath(),c.arc(x,146,13,PI*1.15,PI*1.85),c.stroke()}else eye(c,103,140,-1),eye(c,153,140,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,161,14,7,0,0,T),c.fill()
c.lineWidth=5;c.fillStyle='#c92a2a';c.beginPath()
if(hap)c.moveTo(116,165),c.quadraticCurveTo(128,186,140,165),c.closePath(),c.fill(),c.stroke();else if(t>=.4)c.ellipse(128,169,5,6,0,0,T),c.fill(),c.stroke();else c.arc(128,164,8,.2*PI,.8*PI),c.stroke()
c.lineWidth=8;c.fillStyle=HAIR;c.beginPath();c.moveTo(70,144)
c.bezierCurveTo(54,74,88,42,128,42);c.bezierCurveTo(168,42,202,74,186,144)
c.quadraticCurveTo(182,114,172,102);c.quadraticCurveTo(164,108,160,116);c.quadraticCurveTo(154,100,142,94);c.quadraticCurveTo(136,106,128,112)
c.quadraticCurveTo(122,98,110,94);c.quadraticCurveTo(104,108,98,116);c.quadraticCurveTo(92,106,84,102);c.quadraticCurveTo(72,118,70,144);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=6;for(const[a,e]of[[1.28,1.4],[1.48,1.56],[1.64,1.74]])c.beginPath(),c.arc(128,104,54,PI*a,PI*e),c.stroke()
c.strokeStyle='#111';c.fillStyle=HAIR;c.lineWidth=7
for(const d of[-1,1])for(let k=0;k<4;k++)c.beginPath(),c.ellipse(128+d*(60-k*1.5),156+k*22,11-k,13-k,0,0,T),c.fill(),c.stroke()
c.fillStyle=MUFF
c.lineWidth=13;c.beginPath();c.arc(128,104,58,PI*1.08,PI*1.92);c.stroke();c.strokeStyle=MD;c.lineWidth=6;c.stroke();c.strokeStyle='#111'
c.lineWidth=8;for(const d of[-1,1])c.beginPath(),c.arc(128+d*58,112,20,0,T),c.fill(),c.stroke()
c.strokeStyle='#fff';c.lineWidth=5;for(const d of[-1,1])c.beginPath(),c.arc(128+d*58,112,10,PI*1.1,PI*1.6),c.stroke();c.strokeStyle='#111'
c.restore()
arm(-1,Lh);arm(1,Rh)
c.lineWidth=5;c.fillStyle=SC;for(const h of[Rh,Lh])c.beginPath(),c.arc(h[0],h[1],9.5,0,T),c.fill(),c.stroke()
if(t<.4)ball(c,(Rh[0]+Lh[0])/2,Rh[1]-4,3+9*pk);else if(t<.6)ball(c,Rh[0]+3,Rh[1]-13,12)
c.restore()
for(const o of[.2,.7]){const p=(t-o+1)%1;if(p<.3)puff(c,X-4-p*110,Y-98-p*60,.8+p*2.4)}
if(t>=.6&&t<.9){const p=(t-.6)/.3;ball(c,X+64+(290-X-64)*p,Y-78-160*p+40*p*p,12)}
}
+57
View File
@@ -0,0 +1,57 @@
// hime-cut girl in a summer yukata watching her senko hanabi sparkler crackle, fanning herself with an uchiwa
const{sin,cos,PI,max,min}=Math,T=2*PI
export const frames=12,delay=90
const SKIN='#ffe3d1',HAIR='#5c677d',HD='#3d4657',HL='#c5ccd8',EYE='#e8590c',ED='#a33a06',YU='#4c6ef5',YD='#364fc7',OBI='#ffa94d',FL='#fff',FP='#faa2c1',KZ='#f06595',BL='#ffa8a8',SP='#ffe066',Z=.8
const rnd=s=>()=>(s=(s*16807)%2147483647)/2147483647
const eye=(c,x,y,d)=>{
c.fillStyle='#fff';c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.fill()
c.save();c.beginPath();c.ellipse(x,y,14,17,0,0,T);c.clip();c.beginPath();c.ellipse(x-4,y+4,11.5,15,0,0,T);c.fillStyle=EYE;c.fill();c.lineWidth=3;c.stroke()
c.fillStyle=ED;c.beginPath();c.ellipse(x-4,y-4,13,9,0,0,T);c.fill()
c.fillStyle='#111';c.beginPath();c.ellipse(x-5,y+6,5.5,7.5,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-8,y-1,4.5,0,T);c.fill();c.beginPath();c.arc(x+1,y+10,2,0,T);c.fill()
c.fillStyle=SP;c.beginPath();c.arc(x-1,y+3,2.2,0,T);c.fill();c.restore()
c.lineWidth=7.5;c.beginPath();c.moveTo(x-16,y-4);c.quadraticCurveTo(x,y-16,x+16,y-4);c.moveTo(x+d*15,y-5);c.lineTo(x+d*21,y-10);c.stroke()
}
const flower=(c,x,y,r,f)=>{c.fillStyle=f;c.beginPath();for(let k=0;k<5;k++){const a=k*T/5-PI/2;c.moveTo(x+cos(a)*r*1.5+r*.75,y+sin(a)*r*1.5);c.arc(x+cos(a)*r*1.5,y+sin(a)*r*1.5,r*.75,0,T)}c.fill()}
export default(c,t,i)=>{
const R=rnd(i*977+13),bx=58,by=200,fa=.22*sin(t*T*2)
c.save();c.translate(144,166);c.scale(Z,Z);c.translate(-128,-186)
c.lineWidth=7.5;c.fillStyle=HAIR;c.beginPath();c.moveTo(128,46);c.bezierCurveTo(58,46,54,110,58,200);c.lineTo(60,262);c.lineTo(196,262);c.lineTo(198,200);c.bezierCurveTo(202,110,198,46,128,46);c.fill();c.stroke()
c.restore()
c.lineWidth=6;c.fillStyle=YU;c.beginPath();c.moveTo(120,186);c.quadraticCurveTo(80,192,70,256);c.lineTo(218,256);c.quadraticCurveTo(208,192,168,186);c.closePath();c.fill();c.stroke()
c.save();c.clip();for(const[x,y]of[[92,216],[196,206],[150,246],[84,250]])flower(c,x,y,5,FL),c.fillStyle=FP,c.beginPath(),c.arc(x,y,3,0,T),c.fill();c.restore()
c.fillStyle='#fff';c.beginPath();c.moveTo(126,186);c.lineTo(144,226);c.lineTo(162,186);c.closePath();c.fill();c.stroke()
c.fillStyle=YU;c.beginPath();c.moveTo(118,188);c.lineTo(150,236);c.lineTo(170,188);c.lineTo(160,186);c.lineTo(144,220);c.lineTo(128,186);c.closePath();c.fill();c.lineWidth=5;c.stroke()
c.fillStyle=OBI;c.lineWidth=6;c.beginPath();c.moveTo(76,232);c.quadraticCurveTo(144,240,214,232);c.lineTo(216,256);c.lineTo(74,256);c.closePath();c.fill();c.stroke()
c.strokeStyle='#e8590c';c.lineWidth=3;c.beginPath();c.moveTo(78,244);c.quadraticCurveTo(144,250,214,244);c.stroke();c.strokeStyle='#111'
c.fillStyle=SKIN;c.lineWidth=6;c.beginPath();c.rect(132,166,24,22);c.fill();c.beginPath();c.moveTo(132,166);c.lineTo(132,186);c.moveTo(156,166);c.lineTo(156,186);c.stroke()
c.save();c.translate(144,166);c.scale(Z,Z);c.translate(-128,-186)
c.lineWidth=7.5;c.fillStyle=SKIN;c.beginPath();c.moveTo(74,96);c.bezierCurveTo(70,152,100,184,128,186);c.bezierCurveTo(156,184,186,152,182,96);c.bezierCurveTo(182,44,74,44,74,96);c.fill();c.stroke()
eye(c,103,142,-1);eye(c,153,142,1)
c.fillStyle=BL;for(const d of[-1,1])c.beginPath(),c.ellipse(128+d*44,162,14,7,0,0,T),c.fill()
c.lineWidth=4.5;c.fillStyle='#c92a2a';c.beginPath();c.moveTo(117,166);c.quadraticCurveTo(125,180,135,166);c.closePath();c.fill();c.stroke()
c.lineWidth=7.5;c.fillStyle=HAIR;c.beginPath();c.moveTo(64,172);c.lineTo(62,120);c.bezierCurveTo(56,64,90,40,128,40);c.bezierCurveTo(166,40,200,64,194,120);c.lineTo(192,172);c.lineTo(178,172);c.lineTo(178,112)
for(let x=178;x>78;x-=20)c.lineTo(x-10,116),c.lineTo(x-20,112)
c.lineTo(78,172);c.closePath();c.fill();c.stroke()
c.strokeStyle=HL;c.lineWidth=6;for(const[a,e]of[[1.28,1.4],[1.48,1.56],[1.64,1.74]])c.beginPath(),c.arc(128,100,56,PI*a,PI*e),c.stroke();c.strokeStyle='#111'
const bs=j=>60+3*sin(t*T*2+j);c.lineWidth=5;c.beginPath();c.moveTo(64,84);c.lineTo(bs(2),137);c.stroke();for(const j of[0,1,2])c.fillStyle=j%2?SP:KZ,c.beginPath(),c.arc(bs(j),101+j*18,5.5,0,T),c.fill(),c.stroke()
c.lineWidth=6;c.beginPath();for(let k=0;k<5;k++){const a=k*T/5-PI/2;c.moveTo(72+cos(a)*16+11,76+sin(a)*16);c.arc(72+cos(a)*16,76+sin(a)*16,11,0,T)}c.stroke();flower(c,72,76,11,KZ);c.fillStyle=SP;c.beginPath();c.arc(72,76,7,0,T);c.fill();c.lineWidth=4;c.stroke()
c.restore()
c.save();c.translate(212,236);c.rotate(-.35+fa)
for(const[l,s]of[[12,'#111'],[6,'#e8c39e']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(0,0),c.lineTo(0,-40),c.stroke()
c.strokeStyle='#111';c.lineWidth=6;c.fillStyle='#fff';c.beginPath();c.ellipse(0,-64,26,24,0,0,T);c.fill();c.stroke()
c.fillStyle='#ff6b6b';c.lineWidth=3.5;c.beginPath();c.moveTo(-12,-60);c.quadraticCurveTo(0,-74,10,-64);c.lineTo(18,-70);c.lineTo(16,-58);c.lineTo(10,-62);c.quadraticCurveTo(0,-52,-12,-60);c.fill();c.stroke()
c.strokeStyle='#4dabf7';c.lineWidth=3;c.beginPath();c.moveTo(-18,-50);c.quadraticCurveTo(-8,-46,0,-50);c.quadraticCurveTo(8,-54,16,-50);c.stroke();c.strokeStyle='#111'
c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(0,-6,10,11,0,0,T);c.fill();c.stroke();c.restore()
const hx=bx+6,hy=by-48
c.lineWidth=6;c.fillStyle=YU;c.beginPath();c.moveTo(hx+12,hy+4);c.lineTo(hx+8,hy+40);c.quadraticCurveTo(hx+20,hy+58,112,232);c.lineTo(122,200);c.closePath();c.fill();c.stroke()
c.save();c.clip();flower(c,hx+26,hy+40,4,FL);c.restore()
for(const[l,s]of[[28,'#111'],[17,YU]])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(122,202),c.quadraticCurveTo(96,190,hx+6,hy+2),c.stroke()
c.strokeStyle='#111'
for(const[l,s]of[[6,'#111'],[3,'#ff8787']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(hx-2,hy+6),c.quadraticCurveTo(bx+2,by-24,bx,by-6),c.stroke()
c.lineWidth=5;c.fillStyle=SKIN;c.beginPath();c.ellipse(hx,hy,10,10,0,0,T);c.fill();c.stroke()
const sp=[];for(let k=0;k<9;k++){const a=R()*T,l=16+R()*24,x=bx+cos(a)*l,y=by+sin(a)*l,br=[];for(let j=0;j<3;j++){const b=a+(R()-.5)*2.2,m=5+R()*8;br.push([x+cos(b)*m,y+sin(b)*m])}sp.push([a,x,y,br,6+R()*4])}
for(const[w,s]of[[5,'#111'],[2.2,SP]]){c.lineWidth=w;c.strokeStyle=s;c.beginPath();for(const[a,x,y,br,r0]of sp){c.moveTo(bx+cos(a)*r0,by+sin(a)*r0);c.lineTo(x,y);for(const[u,v]of br)c.moveTo(x,y),c.lineTo(u,v)}c.stroke()}
c.strokeStyle='#111';c.fillStyle='#ff922b';c.lineWidth=4;c.beginPath();c.arc(bx,by,6+R()*1.5,0,T);c.fill();c.stroke()
c.fillStyle='#fff3bf';c.beginPath();c.arc(bx-1.5,by-1.5,2.5,0,T);c.fill()
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Some files were not shown because too many files have changed in this diff Show More