Code
source
const canvasSketch = require("canvas-sketch");
const p5 = require("p5");
const perspective = require("perspective-transform");
let img;
let THE_SEED;
const number_of_particles = 5000;
const number_of_particle_sets = 7;
let particle_sets;
const squeeze_y = 0.2;
const perspective_x = 0.9;
let pTransform;
let tick;
const print_time = 2000;
const preload = (p5) => {
img = p5.loadImage(
"assets/bramses_On_the_museum_wall_this_evocative_excerpt_invites_the_v_72996f7c-18e3-4bff-9358-16c921ab802a.png"
);
};
const settings = {
// Pass the p5 instance, and preload function if necessary
p5: { p5, preload },
// Turn on a render loop
animate: true,
};
canvasSketch(({ p5 }) => {
class Particle {
constructor(x, y, phi, img) {
this.pos = p5.createVector(x, y);
this.angle = phi;
this.val = 0;
this.img = img;
}
update(index) {
this.pos.x += p5.cos(this.angle);
this.pos.y += p5.sin(this.angle);
let nx = 1.3 * p5.map(this.pos.x, 0, p5.width, -1, 1);
let ny = 1.3 * p5.map(this.pos.y, 0, p5.height, -1, 1);
let np = pTransform.transformInverse(nx, ny);
let n = p5.createVector(nx, ny);
this.altitude =
p5.noise(n.x + 423.2, n.y - 231.1) +
0.04 * p5.noise(n.x * 15 - 113.3, n.y * 8 + 261.1) +
0.02 * p5.noise(n.x * 30 - 54.3, n.y * 30 + 121.1);
let nval =
(this.altitude + 0.065 * (index - number_of_particle_sets / 2)) % 1;
this.angle += 0.8 * p5.map(nval, 0, 1, -1, 1);
this.val = nval;
}
display(index) {
if (this.val > 0.47 && this.val < 0.53) {
let np = pTransform.transform(
this.pos.x,
this.pos.y + 1500 - this.altitude * 2700
);
// give the particle a color based on the image pixel at its location
let c = this.img.get(np[0], np[1]);
p5.stroke(c);
p5.point(np[0], np[1]);
}
}
}
p5.createCanvas(500, 600);
p5.noFill();
p5.background("#e7e7db");
p5.stroke(20, 15);
p5.strokeWeight(1.5);
p5.smooth();
let pad_x = (p5.width - p5.width * perspective_x) / 2;
let pad_y = (p5.height - p5.height * squeeze_y) / 2;
var srcCorners = [0, 0, p5.width, 0, p5.width, p5.height, 0, p5.height];
var dstCorners = [
pad_x,
pad_y,
p5.width - pad_x,
pad_y,
p5.width + pad_x,
p5.height - pad_y,
-pad_x,
p5.height - pad_y,
];
pTransform = perspective(srcCorners, dstCorners);
reset(p5);
function reset(p5) {
THE_SEED = p5.floor(p5.random(9999999));
p5.randomSeed(THE_SEED);
p5.noiseSeed(THE_SEED);
particle_sets = [];
for (var j = 0; j < number_of_particle_sets; j++) {
let ps = [];
for (var i = 0; i < number_of_particles; i++) {
ps.push(
new Particle(
p5.randomGaussian(p5.width / 2, 600),
p5.randomGaussian(p5.height / 2, 900),
p5.random(p5.TWO_PI),
img
)
);
}
particle_sets.push(ps);
}
tick = 0;
p5.background("#e7e7db");
}
return ({ p5, time, width, height }) => {
particle_sets.forEach(function (particles, index) {
particles.forEach(function (particle) {
particle.update(index);
particle.display(index);
});
});
};
}, settings);