Double the anime and manga sections to 100 each

Anime, 50 more colored girls: daily moments (yawn, hiccup, toothbrush, hair
dryer, blanket burrito, pocky), hobbies (baker, barista, DJ, piano, violin,
polaroid, knitting, origami, pottery), sports (swimming, tennis, badminton,
skating, ballet, jump rope, hula hoop, bicycle, campfire, surfing), holidays
(halloween, christmas, valentine, mochi, birthday, easter, tsukimi,
suikawari, taiko, teru teru bozu) and fantasy (fairy, bunny hood, slime,
cyber, magical girl, alien, jiangshi, tanuki, yuki-onna, little devil).

Manga, 50 more black-and-white girls: reactions (doki, stare, ufufu,
denial, fired up, panic, sigh, confused, shiver, poka poka), sports and
martial arts (boxing, fencing, volleyball, sprint, gymnast, baseball,
naginata, nunchaku, parkour, motorbike), school (library, flute,
calligraphy, science, hanko, transfer student, tug of war, sweeping, note
passing, yakisoba bread), home and town (claw machine, cooking, ironing,
bus stop, matcha, sewing, boxes, stray cat, foggy window, piggy bank) and
yokai and fantasy (tengu, kappa, rokurokubi, temari, alchemist, mummy, wolf
girl, medusa, genie, bard).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 11:39:30 +00:00
co-authored by Claude Opus 5.5
parent 56666ba0e3
commit c4dd37f62c
300 changed files with 6009 additions and 0 deletions
+73
View File
@@ -0,0 +1,73 @@
// girl with sleek ink hair kneeling at a low desk, writing the kanji 心 stroke by stroke with a big brush, a happy beat, then the ink fades for the next try
import{createCanvas}from'@napi-rs/canvas'
const{sin,cos,PI,min,max,hypot}=Math,T=2*PI
export const frames=24,delay=90,rim=4
const tile=createCanvas(6,6),q=tile.getContext('2d');q.fillStyle='#111';for(const[x,y]of[[1.5,1.5],[4.5,4.5]])q.beginPath(),q.arc(x,y,1.1,0,T),q.fill()
const toned=(c,p)=>{c.fillStyle='#fff';c.fill();c.fillStyle=p;c.fill();c.stroke()}
const C=[128,224],S=.95
// strokes of 心 as points with brush radius, in stroke order
const ST=[[[-30,-2,2],[-27,5,3.5],[-24,12,4.5]],[[-16,-15,4],[-15.5,4,4.5],[-9,15,4.5],[6,18,4],[21,13,3.5],[28,7,3],[22,1,1.5]],[[-3,-21,2],[0,-15,3.5],[4,-10,4.5]],[[20,-19,2],[24,-12,3.5],[28,-6,4.5]]]
const P=ST.map(s=>s.map(([x,y,r])=>[C[0]+x*S,C[1]+y*S,r]))
const len=s=>{let l=0;for(let k=1;k<s.length;k++)l+=hypot(s[k][0]-s[k-1][0],s[k][1]-s[k-1][1]);return l}
// point at fraction p along a stroke
const along=(s,p)=>{let d=p*len(s);for(let k=1;k<s.length;k++){const a=s[k-1],b=s[k],l=hypot(b[0]-a[0],b[1]-a[1]);if(d<=l||k==s.length-1){const f=min(1,d/l);return[a[0]+(b[0]-a[0])*f,a[1]+(b[1]-a[1])*f,a[2]+(b[2]-a[2])*f]}d-=l}}
const ink=(c,s,p)=>{const l=len(s),n=Math.ceil(l*p);for(let k=0;k<=n;k++){const[x,y,r]=along(s,min(p,k/l));c.beginPath();c.arc(x,y,r,0,T);c.fill()}}
// timeline: [start,end] of each stroke, the brush glides between them
const W=[[.06,.14],[.18,.4],[.44,.5],[.54,.62]],REST=[218,212]
const lerp=(a,b,f)=>[a[0]+(b[0]-a[0])*f,a[1]+(b[1]-a[1])*f]
const brushAt=t=>{
if(t<W[0][0])return lerp(REST,P[0][0],t/W[0][0])
for(let k=0;k<4;k++){const[a,b]=W[k];if(t<a)return lerp(along(P[k-1],1),P[k][0],(t-W[k-1][1])/(a-W[k-1][1]));if(t<b)return along(P[k],(t-a)/(b-a))}
return t<.72?lerp(along(P[3],1),REST,(t-.62)/.1):REST
}
export default(c,t)=>{
const dot=c.createPattern(tile,'repeat'),done=t>=.66&&t<.9,fade=t<.88?1:1-(t-.88)/.12,[bx,by]=brushAt(t)
c.save();c.translate(128,-6);c.scale(.86,.86);c.translate(-128,0)
// ink hair: sleek, center parted, sides down past the ears
c.lineWidth=6;c.fillStyle='#111';c.beginPath();c.moveTo(128,36);c.bezierCurveTo(196,36,206,100,196,170);c.lineTo(60,170);c.bezierCurveTo(50,100,60,36,128,36);c.fill();c.stroke()
// white kimono with a dotted collar crossing
c.fillStyle='#fff';c.beginPath();c.moveTo(100,186);c.quadraticCurveTo(58,196,48,236);c.lineTo(208,236);c.quadraticCurveTo(198,196,156,186);c.closePath();c.fill();c.stroke()
c.lineWidth=4;c.beginPath();c.moveTo(112,186);c.lineTo(132,236);c.lineTo(146,236);c.lineTo(124,186);c.closePath();toned(c,dot)
c.beginPath();c.moveTo(144,186);c.lineTo(118,222);c.lineTo(108,214);c.lineTo(132,186);c.closePath();toned(c,dot)
c.fillStyle='#fff';c.beginPath();c.rect(116,166,24,22);c.fill();c.lineWidth=5;c.beginPath();c.moveTo(116,166);c.lineTo(116,184);c.moveTo(140,166);c.lineTo(140,184);c.stroke()
// white ribbon on the low ponytail, peeking by her neck
c.lineWidth=4;for(const r of[-.5,.6])c.beginPath(),c.ellipse(186,176,13,7,r,0,T),c.fill(),c.stroke()
c.lineWidth=6;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 cast down at the paper, or shut happy when the kanji is done
for(const[x,d]of[[103,-1],[153,1]]){
if(done){c.lineWidth=5;c.beginPath();c.arc(x,144,12,1.15*PI,1.85*PI);c.stroke();continue}
c.save();c.beginPath();c.rect(x-16,138,32,24);c.clip()
c.fillStyle='#fff';c.beginPath();c.ellipse(x,146,12,13,0,0,T);c.fill()
c.fillStyle='#111';c.beginPath();c.ellipse(x,152,9,11,0,0,T);c.fill()
c.fillStyle='#fff';c.beginPath();c.arc(x-3,148,3,0,T);c.fill();c.restore()
c.lineWidth=6;c.beginPath();c.moveTo(x-14,139);c.quadraticCurveTo(x,135,x+14,139);c.lineTo(x+d*19,143);c.stroke()
c.lineWidth=2.5;for(const k of[-6,0,6])c.beginPath(),c.moveTo(x+k,139),c.lineTo(x+k*1.3,134),c.stroke()
}
c.lineWidth=3.5;for(const[x,d]of[[103,1],[153,-1]])c.beginPath(),c.moveTo(x-12,120+d*3),c.lineTo(x+12,120-d*3),c.stroke()
c.lineWidth=3;c.beginPath();if(done)c.arc(128,166,6,.15*PI,.85*PI);else c.moveTo(123,170),c.lineTo(133,170);c.stroke()
if(done){c.lineWidth=2.5;for(const d of[-1,1])for(let k=0;k<3;k++)c.beginPath(),c.moveTo(128+d*42+(k-1)*5-3,166),c.lineTo(128+d*42+(k-1)*5+3,158),c.stroke()}
// sleek ink bangs parted in the middle, white shine
c.lineWidth=6;c.fillStyle='#111';c.beginPath();c.moveTo(70,150);c.bezierCurveTo(54,76,88,38,128,38);c.bezierCurveTo(168,38,202,76,186,150)
c.quadraticCurveTo(184,112,170,100);c.quadraticCurveTo(144,88,128,64);c.quadraticCurveTo(112,88,86,100);c.quadraticCurveTo(72,112,70,150);c.closePath();c.fill();c.stroke()
c.fillStyle='#fff';c.beginPath();for(let k=0;k<=22;k++){const a=PI*(1.24+k*.024);c.lineTo(128+(k%2?54:50)*cos(a),106+(k%2?54:50)*sin(a))}for(let k=22;k>=0;k--){const a=PI*(1.24+k*.024);c.lineTo(128+(k%2?47:43)*cos(a),106+(k%2?47:43)*sin(a))}c.fill()
c.restore()
// low desk with a felt mat, paper, paperweight and inkstone
c.lineWidth=5;c.fillStyle='#fff';c.beginPath();c.moveTo(16,184);c.lineTo(240,184);c.lineTo(250,250);c.lineTo(6,250);c.closePath();c.fill();c.stroke()
c.lineWidth=4;c.beginPath();c.rect(56,188,144,62);toned(c,dot)
c.fillStyle='#fff';c.beginPath();c.rect(66,194,124,56);c.fill();c.stroke()
c.fillStyle='#111';c.beginPath();c.rect(66,190,124,9);c.fill()
c.fillStyle='#111';c.beginPath();c.roundRect(204,200,32,42,5);c.fill();c.strokeStyle='#fff';c.lineWidth=2.5;c.beginPath();c.roundRect(209,205,22,32,4);c.stroke();c.strokeStyle='#111'
// the kanji so far, fading out at the end of the loop
c.globalAlpha=fade;c.fillStyle='#111'
for(let k=0;k<4;k++){const[a,b]=W[k];if(t>=a)ink(c,P[k],min(1,(t-a)/(b-a)))}
c.globalAlpha=1
if(done){c.fillStyle='#fff';c.lineWidth=2.5;const s=6+3*sin(T*(t-.66)*4);for(const[x,y]of[[176,204],[78,242]]){c.beginPath();for(let k=0;k<8;k++){const a=k*PI/4,r=k%2?s*.35:s;c.lineTo(x+r*cos(a),y+r*sin(a))}c.closePath();c.fill();c.stroke()}}
// writing arm and brush, the hand stays above the paper
const hx=bx+12,hy=by-54
for(const[l,s]of[[28,'#111'],[22,'#fff']])c.lineWidth=l,c.strokeStyle=s,c.beginPath(),c.moveTo(166,160),c.quadraticCurveTo((166+hx)/2+6,(160+hy)/2+18,hx+8,hy+4),c.stroke()
c.strokeStyle='#111';c.lineWidth=4;c.fillStyle='#fff';c.beginPath();c.moveTo(bx-1,by-8);c.lineTo(bx+16,by-86);c.lineTo(bx+24,by-84);c.lineTo(bx+7,by-7);c.closePath();c.fill();c.stroke()
c.lineWidth=2;for(const f of[.3,.62])c.beginPath(),c.moveTo(bx-1+17*f,by-8-78*f),c.lineTo(bx+7+17*f,by-7-77*f),c.stroke()
c.fillStyle='#111';c.beginPath();c.moveTo(bx-2,by-10);c.quadraticCurveTo(bx-3,by-2,bx,by+1);c.quadraticCurveTo(bx+6,by-2,bx+8,by-9);c.closePath();c.fill()
c.fillStyle='#fff';c.lineWidth=4;c.beginPath();c.ellipse(hx,hy,12,13,0,0,T);c.fill();c.stroke()
c.lineWidth=2.5;c.beginPath();c.moveTo(hx-8,hy-4);c.quadraticCurveTo(hx,hy-1,hx+8,hy-5);c.moveTo(hx-8,hy+4);c.quadraticCurveTo(hx,hy+7,hx+8,hy+3);c.stroke()
}