Skip to content

Instantly share code, notes, and snippets.

@bazzargh
Created February 5, 2026 02:25
Show Gist options
  • Select an option

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

Select an option

Save bazzargh/1880c560707f8de8dd6328a0b3acfbb1 to your computer and use it in GitHub Desktop.
p5.js program to show a scene from The Shining with an animated carpet. Intended for use in https://editor.p5js.org/
const redrum = "#8a1d1e"
const dunny = "#46281c"
const torange = "#bb6538"
let img
let gr
const s3 = Math.sqrt(3)
function preload() {
img = loadImage("https://i0.wp.com/boingboing.net/wp-content/uploads/2018/07/the-shining-carpet-corridor-danny-600435-1.jpg")
}
function setup() {
createCanvas(img.width, img.height);
gr = createGraphics(120*2,170*2)
gr.pixelDensity(1)
gr.noStroke()
frameRate(15)
}
function hexagon(w, n) {
gr.push()
gr.beginShape()
if (n <= 2) {
for (let i = 0; i < 6; i++) {
gr.vertex(n*w*sin(2*PI*i/6), n*w*cos(2*PI*i/6))
}
} else {
let z = w/2
for (let i = 0; i < 7; i++) {
if (i == 0) {
gr.vertex(z, (n*w)-n*w*cos(PI/3)*(z/(n*w*sin(PI/3))))
} else if (i == 6) {
gr.vertex(-z, (n*w)-n*w*cos(PI/3)*(z/(n*w*sin(PI/3))))
} else {
gr.vertex(n*w*sin(2*PI*i/6), n*w*cos(2*PI*i/6))
}
}
for (let i = 6; i >=0; i--) {
if (i == 0) {
gr.vertex(z, (n-1)*w-(n-1)*w*cos(PI/3)*(z/((n-1)*w*sin(PI/3))))
} else if (i == 6) {
gr.vertex(-z, (n-1)*w-(n-1)*w*cos(PI/3)*(z/((n-1)*w*sin(PI/3))))
} else {
gr.vertex((n-1)*w*sin(2*PI*i/6), (n-1)*w*cos(2*PI*i/6))
}
}
}
gr.endShape(CLOSE)
gr.pop()
}
function brown1(w,t) {
let a = (PI/3)*(-(Math.cos(Math.PI * t) - 1))
let dx = -w*(3*s3+1)/4
let dy = -w*(2*s3+3)/4
gr.push()
gr.translate(dx, dy)
gr.fill(torange)
//hexagon(w,3)
gr.fill(dunny)
hexagon(w,2)
gr.fill(redrum)
hexagon(w,1)
gr.fill(dunny)
gr.translate(0, (5)*w)
gr.rotate(a)
gr.rect(-w/2,0,w,-4*w)
gr.rotate((2)*PI/3)
gr.rect(-w/2,0,w,-4*w)
gr.rotate((2)*PI/3)
gr.rect(-w/2,0,w,-4*w)
gr.pop()
}
function red1(w,t) {
let a = (PI/3)*(-(Math.cos(Math.PI * t) - 1))
let dx = -w*(3*s3+1)/4
let dy = -w*(2*s3+3)/4
gr.push()
gr.translate(dx, dy)
gr.fill(torange)
//hexagon(w,3)
gr.fill(dunny)
hexagon(w,2)
gr.fill(dunny)
gr.push()
gr.translate(0, (5)*w)
gr.rect(-w/2,0,w,-4*w)
gr.rotate((2)*PI/3)
gr.rect(-w/2,0,w,-4*w)
gr.rotate((2)*PI/3)
gr.rect(-w/2,0,w,-4*w)
gr.pop()
gr.pop()
}
function red2(w,t) {
let a = (PI/3)*(-(Math.cos(Math.PI * t) - 1))
let dx = -w*(3*s3+1)/4
let dy = -w*(2*s3+3)/4
gr.push()
gr.translate(dx, dy)
gr.translate(6*w*t,0)
gr.rotate(a)
gr.fill(redrum)
hexagon(w,1)
gr.pop()
}
function orange1(w,t) {
let a = (PI/2)*(-(Math.cos(Math.PI * t) - 1))
let dx = -w*(3*s3+1)/4
let dy = -w*(2*s3+3)/4
gr.push()
gr.translate(dx, dy)
gr.fill(redrum)
hexagon(w,1)
gr.pop()
gr.push()
gr.rotate(a)
gr.fill(torange)
gr.translate(dx, dy)
hexagon(w,3)
gr.pop()
}
function pattern(w) {
if ((floor(frameCount/20)%3)==0) {
brown1(w,(frameCount%20)/20)
} else if ((floor(frameCount/20)%3)==1) {
orange1(w, (frameCount%20)/20)
} else {
red1(w,(frameCount%20)/20)
}
}
function mod(n, m) {
return ((n % m) + m) % m;
}
function getUnprojected(xa, ya) {
let x = -0.903104 * xa - 0.846660 * ya + 399.623706;
let y = 0.000000 * xa + 2.798683 * ya - 1007.52587;
let w = 0.000000 * xa - 0.006938 * ya + 1.000000;
return [ x / w, y / w ];
}
function draw() {
let w = 20
background(0)
if ((floor(frameCount/20)%3)==0) {
gr.background(torange)
} else if ((floor(frameCount/20)%3)==1) {
gr.background(dunny)
} else {
gr.background(torange)
}
gr.push()
for(let i = 0; i < 3; i++) {
for(let j = 0; j < 3; j++) {
gr.push()
gr.translate(120*i,170*j)
pattern(w)
gr.scale(-1,-1)
pattern(w)
gr.pop()
}
}
if ((floor(frameCount/20)%3)==2) {
for(let i = 0; i < 6; i++) {
for(let j = 0; j < 3; j++) {
gr.push()
gr.translate(120*i,170*j)
red2(w,(frameCount%20)/20)
gr.scale(-1,-1)
red2(w,(frameCount%20)/20)
gr.pop()
}
}
}
gr.pop()
gr.loadPixels()
stroke(0,0,0,10)
for(let gy=159; gy<img.height;gy++) {
let xmin = 274+(160-274)*(gy-159)/(250-159)
let xmax = 330+(440-330)*(gy-159)/(250-159)
if (gy>=250) {
xmin = 0
xmax = 600
}
for (let gx = xmin; gx < xmax; gx++) {
let [ix,iy] = getUnprojected(gx,gy)
ix = round(mod(ix-31,120))
iy = round(mod(iy+48,170))
let index = iy*240*4+ix*4;
stroke(gr.pixels[index],gr.pixels[index+1],gr.pixels[index+2])
point(gx,gy)
}
}
push()
//translate(-img.width/2,-img.height/2)
beginClip({invert: true})
beginShape()
vertex(279,162)
vertex(329,162)
vertex(356,182)
vertex(356,196)
vertex(370,196)
vertex(423,243)
vertex(422,248)
vertex(429,257)
vertex(490,257)
vertex(488,255)
vertex(599,255)
vertex(599,439)
vertex(0,439)
vertex(0,375)
vertex(55,335)
vertex(90,340)
vertex(119,335)
vertex(137,315)
vertex(131,275)
vertex(136,270)
vertex(150,270)
vertex(170,255)
vertex(178,255)
vertex(183,251)
vertex(183,243)
vertex(194,234)
vertex(194,228)
vertex(198,224)
vertex(204,224)
endShape(CLOSE)
beginShape()
vertex(291,217)
vertex(284,230)
vertex(282,240)
vertex(285,243)
vertex(280,248)
vertex(278,281)
vertex(282,297)
vertex(258,308)
//bottom left
vertex(258,324)
vertex(294,336)
vertex(297,340)
vertex(312,343)
vertex(326,340)
vertex(330,332)
vertex(350,324)
vertex(350,314)
vertex(342,311)
vertex(342,306)
vertex(330,304)
vertex(328,288)
vertex(331,281)
vertex(327,245)
vertex(318,240)
vertex(320,234)
vertex(316,220)
vertex(310,214)
vertex(298,213)
endShape(CLOSE)
endClip()
image(img, 0, 0)
pop()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment