No direct user interaction, but you can tweak constants in the code to alter the clouds.
xxxxxxxxxx
/**************************************************
* The Poetry Clouds by Kyle Geske (stungeye.com) *
**************************************************/
// Defines the size of the text grid in pixels.
const cloudPixelScale = 6;
// Cloud coverage between 0.3 (plentiful) and 0.6 (sparse).
const cloudCutOff = 0.5;
// Speed of cloud panning. Larger values make it faster.
const panSpeed = 8;
// Speed of cloud transformation over time. Larger is faster.
const cloudEvolutionSpeed = 4;
function setup() {
createCanvas(min(windowWidth, 640), min(windowHeight, 480));
// Provide description of this sketch for screen readers.
describe('2D clouds made of white text float slowly across a blue sky. The shape of the clouds is changing subtly over time.', LABEL);
}
function draw() {
// A beautiful sky blue background.
background(19, 142, 192);
// Nested loop to draw a grid of letters across the canvas.
for (let x = 0; x <= width; x += cloudPixelScale) {
for (let y = 0; y <= height; y += cloudPixelScale) {
let tinyTimeOffset = millis() / 100000;
// Defines the scale of noise for visually appealing clouds.
let noiseScale = 0.01;
// 3D noise sampling: The first two dimensions are tied to
// the canvas position, with the x and y values panning
// slowly over time. The third dimension is solely influenced
// by time, enabling the clouds to gradually change shape.
let n = noise(
x * noiseScale + tinyTimeOffset * panSpeed,
y * noiseScale + tinyTimeOffset * 0.25 * panSpeed,
tinyTimeOffset * cloudEvolutionSpeed
);
// Skip this position/letter if noise value is under cutoff.
if (n < cloudCutOff) { continue; }
// Use the alpha channel to fade out the edges of the clouds.
let alpha = map(n, cloudCutOff, 0.65, 10, 255);
fill(255, alpha);
// Set the text size to be 15% larger than the grid.
textSize(cloudPixelScale * 1.15);
text(getLetterForCoordinate(x, y), x, y);
}
}
}
function getLetterForCoordinate(x, y) {
// Simple hash function for x, y coordinates.
let hash = (x + y) * sin(x * y);
// Ensure a positive value and limit to 26 letters.
let index = abs(int(hash * 1000)) % 26;
// Convert to uppercase letter using ASCII character code.
return String.fromCharCode(65 + index);
}