xxxxxxxxxx
116
// replicating the effect from
// https://studiodumbar.com/work/cities-in-motion
const rowCount = 3;
const colCount = 3;
const minWidth = 80;
const textScalar = 1.37;
const tick = 60;
const lerpVal = 0.15;
let x, y, prevX, prevY, counter = 0;
let letterWidths = x = y = [];
const word = "PLAYGROUND";
let colors, bgColors;
function setup() {
createCanvas(500, 800);
background(100);
textFont("Helvetica");
textStyle(BOLD);
textSize(100 * textScalar);
noStroke();
colors = [color(255, 0, 255), color(255, 255, 0)];
bgColors = [color(255), color(0)];
x = prevX = getRandomValues(colCount, minWidth, width);
y = prevY = getRandomValues(rowCount, minWidth, height);
// measure all letters
letterWidths = [];
for(let i = 0; i < word.length; i++) {
letterWidths[i] = textWidth(word[i]);
}
}
function draw() {
background(0);
if(frameCount % tick === 0) {
prevX = x;
prevY = y;
x = getRandomValues(colCount, minWidth, width);
y = getRandomValues(rowCount, minWidth, height);
}
for(let i = 0; i < colCount; i++) {
prevX[i] = lerp(prevX[i], x[i], lerpVal);
for(let j = 0; j < rowCount; j++) {
prevY[j] = lerp(prevY[j], y[j], lerpVal);
// comment in, if you want to draw a rect behind each letter
// fill(bgColors[(i * colCount + j) % 2]);
// rect(lerp(prevX[i], x[i], lerpVal),
// lerp(prevY[j], y[j], lerpVal),
// lerp(prevX[i + 1], x[i + 1], lerpVal),
// lerp(prevY[j + 1], y[j + 1], lerpVal));
}
}
for(let i = 0; i < colCount; i++) {
fill(colors[i % 2]);
for(let j = 0; j < rowCount; j++) {
translate(prevX[i], prevY[j + 1]);
scale((prevX[i + 1] - prevX[i]) / letterWidths[i * rowCount + j] ,
(prevY[j + 1] - prevY[j]) / 100);
text(word[i * rowCount + j], 0, 0);
resetMatrix();
}
}
}
function getRandomValues(colCount, minWidth, max) {
let z = [];
let tooClose;
do {
tooClose = false;
let i = colCount - 1;
while(i--) {
z[i] = random(minWidth, max - minWidth);
}
z.sort();
for(i = 0; i < colCount + 2; i++) {
if(z[i + 1] - z[i] < minWidth) {
tooClose = true;
break;
}
}
} while(tooClose);
z.unshift(0);
z.push(max);
return z;
}