Flip 16 minimalist creatures to white with a dark edge

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 13:32:58 +00:00
co-authored by Claude Opus 5.5
parent 95c6ae7fb4
commit 461a39caa2
49 changed files with 24 additions and 20 deletions
+8 -4
View File
@@ -3,6 +3,7 @@
// npm run gen renders only what's missing (published files never change by accident)
// npm run gen -- cat/blink renders only the named ones, even if they already exist
// a file can export rim=<px> to get a white sticker border, so black ink still shows on a black page
// and invert=true to swap ink and paper (#111 <-> #fff), turning a black silhouette with a white rim into a white one with a dark rim
import{createCanvas}from'@napi-rs/canvas'
import sharp from'sharp'
import{readdirSync as rd,existsSync as ex,mkdirSync as mk,statSync as st}from'fs'
@@ -16,9 +17,9 @@ if(dup)throw Error(`${dup} is in more than one section`)
for(const[k,f]of files.entries()){
const id=ids[k],o=`public/${id}`
if(redo.length?!redo.includes(id):ex(o+'.webp')&&ex(o+'.gif'))continue
const{default:draw,frames=16,delay=80,rim=0}=await import(url(resolve(f)))
const{default:draw,frames=16,delay=80,rim=0,invert=false}=await import(url(resolve(f)))
const px=[...Array(frames)].map((_,i)=>{
const c=createCanvas(S,S).getContext('2d')
let c=createCanvas(S,S).getContext('2d')
Object.assign(c,{lineWidth:7,lineCap:'round',lineJoin:'round',strokeStyle:'#111',fillStyle:'#fff'})
draw(c,i/frames,i)
if(rim){
@@ -26,9 +27,12 @@ for(const[k,f]of files.entries()){
const r=createCanvas(S,S).getContext('2d')
for(let d=1;d<=rim;d++)for(let a=0;a<24;a++)r.drawImage(c.canvas,d*Math.cos(a*Math.PI/12),d*Math.sin(a*Math.PI/12))
r.globalCompositeOperation='source-in';r.fillStyle='#fff';r.fillRect(0,0,S,S)
r.globalCompositeOperation='source-over';r.drawImage(c.canvas,0,0);return Buffer.from(r.getImageData(0,0,S,S).data.buffer)
r.globalCompositeOperation='source-over';r.drawImage(c.canvas,0,0);c=r
}
return Buffer.from(c.getImageData(0,0,S,S).data.buffer)
const b=Buffer.from(c.getImageData(0,0,S,S).data.buffer)
// 17 and 255 trade places, the antialiased grays in between flip along, alpha is untouched
if(invert)for(let j=0;j<b.length;j++)if(j%4<3)b[j]=Math.min(255,272-b[j])
return b
})
mk(dirname(o),{recursive:true})
const img=()=>sharp(Buffer.concat(px),{raw:{width:S,height:S*frames,channels:4,pageHeight:S}})