Skip to content

Instantly share code, notes, and snippets.

@bazzargh
Created December 20, 2025 10:31
Show Gist options
  • Select an option

  • Save bazzargh/be402da4991444d43e8ee4ceae2fd406 to your computer and use it in GitHub Desktop.

Select an option

Save bazzargh/be402da4991444d43e8ee4ceae2fd406 to your computer and use it in GitHub Desktop.
cross-stitch generator. paste into p5js.org to see it. fakes "3d" just by drawing threads 3 times in different shades.
const bf = [
" XXX XXXX XXXX XXXX XXXXX XXXXX XXXX X X XXXXX XX X X X X X X X XXX XXXX XXX XXXX XXXX XXXXX X X X X X X X X X X XXXXX",
"X X X X X X X X X X X X X X X X X XX XX XX X X X X X X X X X X X X X X X X X X X X X X ",
"XXXXX XXXX X X X XXX XXX X XX XXXXX X X XXX X X X X X X X X X XXXX X X XXXX XXX X X X X X X X X X X X ",
"X X X X X X X X X X X X X X X X X X X X X X XX X X X X X X X X X X X X X XX XX X X X X ",
"X X XXXX XXXX XXXX XXXXX X XXX X X XXXXX XXX X X XXXXX X X X X XXX X XX X X X XXXX X XXX X X X X X X XXXXX"
]
const b1 = [
" ",
" gg ",
" gg ggggg",
" g ",
" g rr rr",
" g rrrrr",
" g ryr ",
" g rrrrr",
" g rr rr",
]
const b2 = [
"gg ",
"gg ",
" g ",
" g gg ",
" g gg ",
" g ",
"rr rr g ",
"rrrrr g ",
" ryr g ",
"rrrrr g ",
"rr rr g ",
]
function corner(x1, y1, x2, y2) {
let dx = x1 > x2 ? -1 : 1;
let dy = y1 > y2 ? -1 : 1;
let xr = ceil((abs(x1-x2)-b1.length)/b2.length)
console.log(xr)
let yr = ceil((abs(y1-y2)-b1.length)/b2.length)
colorMode(HSL)
let colours = {
"r": color(0,50,70),
"g": color(100,50,50),
"y": color(50,50,60)
}
for(let i = 0; i < b1.length; i++) {
for(let j=0; j < b1[0].length; j++) {
if (b1[i][j] in colours) {
stitch(x1+dx*i, y1+dy*j, colours[b1[i][j]]);
}
}
}
let x = x1 + b1.length * dx
for (let k = 0; k < xr; k++) {
for(let i = 0; i < b2.length; i++) {
for(let j=0; j < b2[0].length; j++) {
let t = k%2 == 0? j : (b1[0].length - j - 1)
if (b2[i][t] in colours) {
stitch(x, y1+dy*j, colours[b2[i][t]]);
}
}
x+=dx;
}
}
let y = y1 + b1.length * dy
for (let k = 0; k < yr; k++) {
for(let i = 0; i < b2.length; i++) {
for(let j=0; j < b2[0].length; j++) {
let t = k%2 == 0? j : (b1[0].length - j - 1)
if (b2[i][t] in colours) {
stitch(x1+j*dx, y, colours[b2[i][t]]);
}
}
y+=dy;
}
}
}
function stitch(x, y, hsl) {
colorMode(HSL)
let h = hue(hsl)
let s = saturation(hsl)
let l = lightness(hsl)
let offset = 10;
let darker = color(h, s, max(0, l-offset))
let lighter = color(h, s, min(100, l+offset))
stroke(lighter)
line(x*5+1, y*5, x*5+5, y*5+4)
stroke(darker)
line(x*5, y*5+1, x*5+4, y*5+5)
stroke(hsl)
line(x*5, y*5, x*5+5, y*5+5)
stroke(lighter)
line(x*5+4, y*5, x*5, y*5+4)
stroke(darker)
line(x*5+5, y*5+1, x*5+1, y*5+5)
stroke(hsl)
line(x*5+5, y*5, x*5, y*5+5)
}
function stitchtext(s, x, y, hsl) {
// centre the text around x, y
s = s.toUpperCase()
const w = Array.from(s).reduce((a,c)=>a+(c==" "?3:6),0)-1;
x -= floor(w/2) + 1;
y -= 2;
for(let c of s) {
if (c == " ") {
x += 3;
} else if ("A" <= c && c <= "Z") {
let n = c.charCodeAt(0) - "A".charCodeAt(0);
for(let i = 0; i < 5; i++) {
for(let j = 0; j < 5; j++) {
if (bf[j][n*6 + i] == "X") {
stitch(x + i, y + j, hsl)
}
}
}
x+=6
}
}
}
function setup() {
createCanvas(600, 400);
background(220);
colorMode(HSL);
let hsl;
for(let x = 0; x < 600; x++) {
if (x%5>0) {
stroke(50,10,90+random(5))
line(x,0,x,400)
}
}
for(let y = 0; y < 400; y++) {
stroke(50,10,90+random(5))
if (y%5>0) {
for(x=(int(y/5)%2)*5;x<600;x+=10) {
line(x, y,x+5,y)
}
}
}
hsl = color(250,50,50)
stitchtext('NEVER EXPECT TWO', 60, 20, hsl)
stitchtext('INDEPENDENT URL',60, 30, hsl)
stitchtext('PARSERS TO TREAT', 60, 40, hsl)
stitchtext('EVERY URL', 60, 50, hsl)
stitchtext('IDENTICALLY', 60, 60, hsl)
hsl = color(100,50,50)
corner(0, 0, 40,30)
corner(0,79, 40, 49)
corner(119, 0,79, 30)
corner(119, 79, 79, 49)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment