let pointDensity = 0.005;
let selectedImgIndex = 0;
let imgOffset = { x: 0, y: 0 };
let imgVelocity = { x: 1, y: 1 };
for (let i = 0; i < photo.length; i++) imgs[i] = loadImage(photo[i][0]);
bg = createGraphics(width, height);
toggleButton = createButton('Change Image');
toggleButton.size(200, 50);
toggleButton.position(800, 750);
toggleButton.mousePressed(toggleImageAndColors);
function generateBackground() {
for (let i = 0; i < 10000; i++) {
let s = noise(x * 0.01, y * 0.01) * 2;
bg.fill(random(100, 255), 20);
function initializeShapes() {
selectedImgIndex %= imgs.length;
const img = imgs[selectedImgIndex];
const ratio = min(width * 0.9 / img.width, height * 0.9 / img.height);
img.resize(img.width * ratio, img.height * ratio);
points = getEdgePoints(img, max(img.width, img.height) * pointDensity, photo[selectedImgIndex][1]);
triangles = Delaunay.triangulate(points);
shapes = triangles.map((_, i) => {
const p1 = points[triangles[i]];
const p2 = points[triangles[i + 1]];
const p3 = points[triangles[i + 2]];
imgOffset.x += imgVelocity.x;
imgOffset.y += imgVelocity.y;
if (imgOffset.x < 0 || imgOffset.x + imgs[selectedImgIndex].width > width) imgVelocity.x *= -1;
if (imgOffset.y < 0 || imgOffset.y + imgs[selectedImgIndex].height > height) imgVelocity.y *= -1;
translate(imgOffset.x, imgOffset.y);
image(imgs[selectedImgIndex], 0, 0);
for (let shape of shapes) {
fill(random(100, 255), random(100, 255), random(100, 255), 150);
vertex(shape.p1[0], shape.p1[1]);
vertex(shape.p2[0], shape.p2[1]);
vertex(shape.p3[0], shape.p3[1]);
function toggleImageAndColors() {
isGrayscale = !isGrayscale;
selectedImgIndex = (selectedImgIndex + 1) % imgs.length;
function getEdgePoints(img, span, threshold) {
points.push([img.width, 0]);
points.push([img.width, img.height]);
points.push([0, img.height]);
for (let y = 0; y < img.height; y += span) {
for (let x = 0; x < img.width; x += span) {
if (x > img.width - span || y > img.height - span) continue;
let currentCol = img.get(x, y);
let nextCol = img.get(x + span, y);
let underCol = img.get(x, y + span);
if (getColDist(currentCol, nextCol) > threshold || getColDist(currentCol, underCol) > threshold) {
function getColDist(col1, col2) {
return dist(col1[0], col1[1], col1[2], col2[0], col2[1], col2[2]);
function mouseClicked() {
save("img_" + month() + '-' + day() + '_' + hour() + '-' + minute() + '-' + second() + ".jpg");
} else if (key === 'R') {
console.log("Edge Threshold:", edgeThreshold);
} else if (key === '-') {
console.log("Edge Threshold:", edgeThreshold);