Spend a month making one beautiful thing per day, given a bunch of prompts. A month late, but as they say, ’the second best time is now'.
Let’s do it!
24) Textile
let gui;
let params = {
threadCount: 10,
red: false,
lightGreen: false,
purple: false,
fall: true,
winter: true,
yellow: false,
maroon: false,
}
const THREAD_RADIUS = 4;
const COLOR_GROUPS = {
red: [[0, 100, 50]],
lightGreen: [[140, 100, 50]],
purple: [[290, 100, 30]],
fall: [[0, 0, 50], [0, 100, 50], [60, 100, 50], [30, 90, 40]],
winter: [[180, 90, 40], [244, 90, 40], [244, 85, 20], [244, 85, 85]],
yellow: [[55, 80, 55]],
maroon: [[340, 55, 35]],
}
function setup() {
createCanvas(400, 400);
colorMode(HSL, 360, 100, 100);
gui = createGuiPanel('params');
gui.addObject(params);
gui.setPosition(420, 0);
}
function draw() {
noLoop();
background(255);
let xBundleCount = width / (params.threadCount * THREAD_RADIUS);
let yBundleCount = height / (params.threadCount * THREAD_RADIUS);
let colorGroups = [];
for (let [name, group] of Object.entries(COLOR_GROUPS)) {
if (params[name] === true) {
colorGroups.push(group);
}
}
if (colorGroups.length == 0) {
return;
}
for (let y = 0; y <= yBundleCount; y++) {
bundle(
random(colorGroups),
0,
y * params.threadCount * THREAD_RADIUS,
400 + THREAD_RADIUS,
y * params.threadCount * THREAD_RADIUS,
params.threadCount,
false
);
}
for (let x = 0; x <= xBundleCount; x++) {
let colorGroup = random(colorGroups);
for (let y = 0; y <= yBundleCount; y++) {
if ((x + y) % 2 == 0) {
bundle(
colorGroup,
x * params.threadCount * THREAD_RADIUS,
y * params.threadCount * THREAD_RADIUS,
x * params.threadCount * THREAD_RADIUS,
(y + 1) * params.threadCount * THREAD_RADIUS + THREAD_RADIUS,
params.threadCount,
true
);
}
}
}
noLoop();
}
function bundle(colors, x1, y1, x2, y2, n, is_x) {
for (let delta = 0; delta < n; delta++) {
thread(
colors,
x1 + ( is_x ? delta * THREAD_RADIUS : 0),
y1 + (!is_x ? delta * THREAD_RADIUS : 0),
x2 + ( is_x ? delta * THREAD_RADIUS : 0),
y2 + (!is_x ? delta * THREAD_RADIUS : 0)
);
}
}
function thread(colors, x1, y1, x2, y2) {
noFill();
let color = random(colors);
let src = createVector(x1, y1);
let dst = createVector(x2, y2);
let offset = p5.Vector.sub(dst, src);
offset.normalize();
offset.mult(2);
let a = TWO_PI / 8;
for (
let p = src.copy(), i = 0;
p5.Vector.sub(dst, p).mag() > THREAD_RADIUS;
p.add(offset), i++
) {
let [h, s, l] = color;
h = parseInt(h + random(10)) % 360;
strokeWeight(0.1);
stroke("black");
fill([h, s, l]);
circle(
p.x + random(THREAD_RADIUS / 4) - THREAD_RADIUS / 8,
p.y + random(THREAD_RADIUS / 4) - THREAD_RADIUS / 8,
THREAD_RADIUS
);
}
}
function stack(thunk) {
push();
thunk();
pop();
}
Posts in Genuary 2023:
- Genuary 2023.01: Perfect loop
- Genuary 2023.02: Made in 10 minutes
- Genuary 2023.03: Glitch art
- Genuary 2023.04: Intersections
- Genuary 2023.05: Debug view
- Genuary 2023.06: Steal like an artist
- Genuary 2023.07: Sample a color palette
- Genuary 2023.08: Signed Distance Functions
- Genuary 2023.09: Plants
- Genuary 2023.10: Generative Music
- Genuary 2023.11: Suprematism
- Genuary 2023.12: Tessellation
- Genuary 2023.13: Something you've always wanted to learn
- Genuary 2023.14: Asemic Writing
- Genuary 2023.15: Sine Waves
- Genuary 2023.16: Reflections of a Reflection
- Genuary 2023.17: A grid inside a grid inside a grid
- Genuary 2023.18: Definitely not a grid
- Genuary 2023.19: Black and white
- Genuary 2023.20: Art Deco
- Genuary 2023.21: Persian Carpet
- Genuary 2023.22: Shadows
- Genuary 2023.23: Moiré
- Genuary 2023.24: Textile
- Genuary 2023.25: Yayoi Kusama
- Genuary 2023.26: My kid could have made that
- Genuary 2023.27: In the style of Hilma Af Klint
- Genuary 2023.28: Generative poetry
- Genuary 2023.29: Maximalism
- Genuary 2023.30: Minimalism
- Genuary 2023.31: Break a previous image