xxxxxxxxxx
160
// * choose your color *
// Learning with The Coding Train ~ https://thecodingtrain.com/
// This sketch by Bianca Mueller ~ https://bianca.works/
let colors = []; // Store generated colors
let selectedColor = null; // Currently selected color
let colorDisplay; // Element to show selected color code
let canSelect = true; // Flag to control selection state
function setup() {
createCanvas(400, 400);
colorDisplay = createP("");
colorDisplay.position(width / 2 - 75, height + 10);
generateRandomColors();
}
function draw() {
background(0);
drawColorRectangles();
drawTitle();
drawInstructions();
}
function drawColorRectangles() {
for (let i = 0; i < 8; i += 2) {
let x = i * 50;
let rectWidth = 40;
let rectHeight = 60;
let widthRectGroup = 340;
let roundedCorners = 40;
let xPos = x + (width - widthRectGroup) / 2;
let yPos = (height - rectHeight) / 2;
if (selectedColor === i / 2) {
stroke(255);
strokeWeight(3);
} else {
noStroke();
}
fill(colors[i / 2]);
rect(xPos, yPos, rectWidth, rectHeight, roundedCorners);
}
}
function drawTitle() {
fill(255);
textSize(24);
textAlign(CENTER, CENTER);
text("choose your color", width / 2, 40);
}
function drawInstructions() {
fill(200);
textSize(12);
let instructions = canSelect
? "click a color • then press SPACE for tetrad"
: "click any color to start over";
text(instructions, width / 2, height - 40);
if (selectedColor !== null) {
let c = colors[selectedColor];
colorDisplay.html(`RGB: ${c.levels[0]}, ${c.levels[1]}, ${c.levels[2]}`);
}
}
function mousePressed() {
// Prevent default to avoid text selection
event.preventDefault();
// Check if click is on any color rectangle
for (let i = 0; i < 4; i++) {
let x = i * 2 * 50 + (width - 340) / 2;
let y = (height - 60) / 2;
let rectWidth = 40;
let rectHeight = 60;
if (
mouseX > x &&
mouseX < x + rectWidth &&
mouseY > y &&
mouseY < y + rectHeight
) {
if (!canSelect) {
// Reset and allow new selection
selectedColor = null;
colorDisplay.html("");
generateRandomColors();
canSelect = true;
}
if (canSelect) {
selectedColor = i;
colorDisplay.html(
`RGB: ${colors[i].levels[0]}, ${colors[i].levels[1]}, ${colors[i].levels[2]}`
);
}
break;
}
}
return false; // Additional measure to prevent default
}
function keyPressed() {
if (keyCode === 32 && selectedColor !== null && canSelect) {
// SPACE key
generateTetradsFrom(selectedColor);
canSelect = false; // Disable further selection until reset
// Note: we're NOT clearing selectedColor here anymore
}
}
function generateRandomColors() {
colors = [];
for (let i = 0; i < 4; i++) {
colors.push(color(random(255), random(255), random(255)));
}
}
function generateTetradsFrom(baseIndex) {
// Store a copy of the exact base color
let exactBaseColor = colors[baseIndex];
// Convert to HSB for calculations only
colorMode(HSB, 360, 100, 100);
let baseHSB = color(
hue(exactBaseColor),
saturation(exactBaseColor),
brightness(exactBaseColor)
);
let h = hue(baseHSB);
let s = saturation(baseHSB);
let b = brightness(baseHSB);
// Generate tetrad colors
let tetrad1 = color((h + 90) % 360, s, b);
let tetrad2 = color((h + 180) % 360, s, b);
let tetrad3 = color((h + 270) % 360, s, b);
// Switch back to RGB
colorMode(RGB, 255);
// Create new array with exact original color preserved
let newColors = [];
let positions = [0, 1, 2, 3];
positions.splice(baseIndex, 1);
newColors[baseIndex] = exactBaseColor; // Use original color object
newColors[positions[0]] = tetrad1;
newColors[positions[1]] = tetrad2;
newColors[positions[2]] = tetrad3;
colors = newColors;
}