xxxxxxxxxx
468
// Like throwing a dice
// Colormono, 2022
var rows = 9;
var cols = 9;
var cellSize = [50, 50];
var gap = 10;
var margin = [60, 60];
var isSaving = false;
// Use one Layer for each shade
// var shades = ["#E2E8F0", "#002BFF", "#7BFA81", "#FFA08D"];
var shades = [
"#000000",
"#666666",
"#CCCCCC",
"#FF0000",
"rgba(100,255,255,0.5)",
];
// Shapes collection
var shapes = [
{ name: "Empty", fragments: 0 },
{ name: "Rect", fragments: 1 },
{ name: "Circle", fragments: 1 },
{ name: "SplitCircle", fragments: 2 },
{ name: "SplitCircleMirror", fragments: 2 },
{ name: "Halfs", fragments: 2 },
{ name: "HalfsMirror", fragments: 2 },
{ name: "Corners", fragments: 2 },
{ name: "CornersMirror", fragments: 2 },
{ name: "Triangles", fragments: 3 },
{ name: "TrianglesMirror", fragments: 3 },
];
// array of Pattern objects
let patterns = [];
function setup() {
createCanvas(660, 660, SVG); // Create SVG Canvas
angleMode(DEGREES); // Change the mode to DEGREES
// Composition
generate();
}
function draw() {
background("#FFFFFF");
// strokeWeight(2);
// stroke("#FFF");
noStroke();
noFill();
/*
for (var layer = 0; layer < shades.length; layer++) {
// print boundary
noFill();
rect(0, 0, width, height);
// layer patterns
push();
translate(margin[0], margin[1]);
for (let i = 0; i < patterns.length; i++) {
if (patterns[i].shade === layer) {
patterns[i].display();
}
}
pop();
// Save on click instead
if (isSaving) {
// layer patterns
push();
translate(margin[0], margin[1]);
for (let i = 0; i < patterns.length; i++) {
if (patterns[i].shade === layer) {
patterns[i].display();
}
}
pop();
save(`render-layer-0${layer}`);
}
}
*/
// Drawing textures on layer 4
// print boundary
// noFill();
// rect(0, 0, width, height);
// layer patterns
push();
translate(margin[0], margin[1]);
stroke(0);
// for (let i = 0; i < patterns.length; i++) {
// if (patterns[i].shade === 0) {
// patterns[i].display();
// push();
// translate(patterns[i].x, patterns[i].y);
let x = 0;
let y = 0;
let spacing = 10;
while (y < (height - margin[1]*2)) {
if (random(1) < 0.5) {
line(x, y, x + spacing, y + spacing);
} else {
line(x, y + spacing, x + spacing, y);
}
x = x + spacing;
if (x > (width - margin[1]*2)) {
x = 0;
y = y + spacing;
}
}
save(`render-layer-texture`);
// pop();
// }
// }
pop();
// Composition mask
// The last layer is the mask
// Cuts should be smarter (detect the overall shape, and avoid inner cuts)
// save time and resources
// if (isSaving) {
// // print boundary
// noFill();
// rect(0, 0, width, height);
// push();
// translate(margin[0], margin[1]);
// generate(true);
// pop();
// save(`render-layer-mask`);
// }
isSaving = false;
noLoop();
}
// Composition
function generate(mask = false) {
// clean array
patterns = [];
// for each cell in a grid
for (var col = 0; col < cols; col++) {
for (var row = 0; row < rows; row++) {
var x = row * cellSize[0] + row * gap;
var y = col * cellSize[1] + col * gap;
// just cell boundary
if (mask) {
strokeWeight(1);
stroke(0);
noFill();
rect(x, y, cellSize[0], cellSize[1]);
} else {
// pick a random shape from the collection
var shape = shapes[floor(random(2, shapes.length))];
// one shade for single shapes
if (shape.fragments === 1) {
const layer = floor(random(shades.length));
patterns.push(
new Pattern(x, y, cellSize[0], cellSize[1], layer, shape)
);
}
// for combined shapes use differents shades for each fragment
if (shape.fragments > 1) {
const layers = getFragmentsColors(shape.fragments);
for (var fragment = 0; fragment < shape.fragments; fragment++) {
patterns.push(
new Pattern(
x,
y,
cellSize[0],
cellSize[1],
layers[fragment],
shape,
fragment
)
);
}
}
}
}
}
// console.log(patterns);
}
// Pattern class
class Pattern {
constructor(x, y, w, h, shade, shape, fragment) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.shade = shade; // [shadeA, shadeB]
this.shape = shape.name;
this.fragment = fragment;
}
display() {
if (this.shape === "Rect") {
rect(this.x, this.y, this.w, this.h, this.shade);
} else if (this.shape === "Circle") {
drawCircle(this.x, this.y, this.w, this.h, this.shade);
} else if (this.shape === "SplitCircle") {
drawSplitCircle(
this.x,
this.y,
this.w,
this.h,
0,
this.shade,
this.fragment
);
} else if (this.shape === "SplitCircleMirror") {
drawSplitCircle(
this.x,
this.y,
this.w,
this.h,
90,
this.shade,
this.fragment
);
} else if (this.shape === "Halfs") {
drawHalfs(
this.x,
this.y,
this.w,
this.h,
false,
this.shade,
this.fragment
);
} else if (this.shape === "HalfsMirror") {
drawHalfs(
this.x,
this.y,
this.w,
this.h,
true,
this.shade,
this.fragment
);
} else if (this.shape === "Corners") {
drawCorners(
this.x,
this.y,
this.w,
this.h,
false,
this.shade,
this.fragment
);
} else if (this.shape === "CornersMirror") {
drawCorners(
this.x,
this.y,
this.w,
this.h,
true,
this.shade,
this.fragment
);
} else if (this.shape === "Triangles") {
drawTriangles(
this.x,
this.y,
this.w,
this.h,
false,
this.shade,
this.fragment
);
} else if (this.shape === "TrianglesMirror") {
drawTriangles(
this.x,
this.y,
this.w,
this.h,
true,
this.shade,
this.fragment
);
}
}
}
// Export
function mouseReleased() {
// save();
}
function keyPressed() {
if (key === "G" || key === "g" || keyCode === BACKSPACE) {
generate();
}
if (key === "S" || key === "s") {
save("render.png");
isSaving = true;
}
loop();
}
// Shuffle
function getFragmentsColors(n = 2) {
// Initial empty array
const arr = [];
// Null check
if (n == 0) {
console.log(null);
}
do {
// Generating random number
const randomNumber = floor(random(shades.length));
// Pushing into the array only
// if the array does not contain it
if (!arr.includes(randomNumber)) {
arr.push(randomNumber);
}
} while (arr.length < n);
// Printing the array elements
// console.log(arr);
return arr;
}
/**
* Shapes Collection
*/
// Shape 1
function drawCircle(_x, _y, _w, _h, _shade) {
push();
translate(_w / 2, _h / 2);
fill(shades[_shade]);
ellipse(_x, _y, _w, _h);
pop();
}
// Shape 2 and 3
function drawSplitCircle(_x, _y, _w, _h, _rotate = 0, _shade, _fragment) {
var offsetX = 0;
var offsetY = 0;
if (_fragment === 0) {
push();
if (_rotate > 0) {
translate(_w / 2, _h);
offsetY = 2;
} else {
translate(_w, _h / 2);
offsetX = 2;
}
fill(shades[_shade]);
arc(_x, _y, _w - offsetX, _h - offsetY, 90 + _rotate, 270 + _rotate, CHORD);
pop();
}
if (_fragment === 1) {
push();
if (_rotate > 0) {
translate(_w / 2, 0);
offsetY = 2;
} else {
translate(0, _h / 2);
offsetX = 2;
}
fill(shades[_shade]);
arc(_x, _y, _w - offsetX, _h - offsetY, 270 + _rotate, 90 + _rotate, CHORD);
pop();
}
}
// Shape 4 and 5
function drawHalfs(_x, _y, _w, _h, _rotate, _shade, _fragment) {
if (_rotate) {
if (_fragment === 0) {
fill(shades[_shade]);
rect(_x, _y, _w / 2, _h);
}
if (_fragment === 1) {
fill(shades[_shade]);
rect(_x + _w / 2, _y, _w / 2, _h);
}
} else {
if (_fragment === 0) {
fill(shades[_shade]);
rect(_x, _y, _w, _h / 2);
}
if (_fragment === 1) {
fill(shades[_shade]);
rect(_x, _y + _h / 2, _w, _h / 2);
}
}
}
// Shape 6 and 7
function drawCorners(_x, _y, _w, _h, _rotate, _shade, _fragment) {
var offset = 0;
push();
translate(_x, _y);
if (_rotate) {
scale(1, -1);
translate(0, -_h);
}
if (_fragment === 0) {
fill(shades[_shade]);
triangle(0, 0, _w - offset, _h, 0, _h);
}
if (_fragment === 1) {
fill(shades[_shade]);
triangle(offset, 0, _w, 0, _w, _h);
}
pop();
}
// Shape 8 and 9
function drawTriangles(_x, _y, _w, _h, _rotate, _shade, _fragment) {
push();
translate(_x, _y);
if (_rotate) {
scale(-1, 1);
translate(-_w, 0);
}
if (_fragment === 0) {
fill(shades[_shade]);
triangle(0, 0, _w, 0, _w, _h / 2);
}
if (_fragment === 1) {
fill(shades[_shade]);
triangle(0, 0, _w, _h / 2, 0, _h);
}
if (_fragment === 2) {
fill(shades[_shade]);
triangle(0, _h, _w, _h / 2, _w, _h);
}
pop();
}