Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Generative art with Markdeep diagrams. Examples: https://twitter.com/doersino/status/1321191553403129857
// Generative art with Markdeep diagrams.
//
// Examples: https://twitter.com/doersino/status/1321191553403129857
// Markdeep: https://casual-effects.com/markdeep/features.md.html#basicformatting/diagrams
//
// Usage:
// 1. Navigate to: https://doersino.github.io/markdeep-diagram-drafting-board/
// 2. Open the JavaScript console (if you need help, see https://webmasters.stackexchange.com/a/77337).
// 3. Paste the contents of this file and press Enter.
// 4. Type "art()" and press Enter.
// 5. ???
// 6. Profit!
// 7. If you want more, goto 4.
// 8. You can also set a fixed width and height and add a border, e.g. "art(30, 15, true)".
function art(w, h, addBorder=false) {
// random number machine
const rint = (min, max) => min + parseInt(Math.random() * (max - min));
// generate width and height if not specified
if (!w) w = rint(10, 40);
if (!h) h = rint(10, 20);
// randomly select probabilites of various symbols
const probabilites = {
".": rint(0, 4),
"'": rint(0, 4),
">": rint(0, 2),
"<": rint(0, 2),
"|": rint(0, 4),
"(": rint(0, 3),
")": rint(0, 3),
"-": rint(2, 8),
"_": rint(0, 6),
"/": rint(0, 6),
"\\": rint(0, 6),
"+": rint(6, 12),
"o": rint(0, 3),
"*": rint(0, 3),
" ": rint(0, 20)
}
const symbols = Object.entries(probabilites).map(([c, p]) => {
return "".padStart(p, c);
}).join("").split("")
// generate grid
const xs = Array.from(Array(w).keys());
const ys = Array.from(Array(h).keys());
// populate
let s = "";
ys.forEach(y => {
xs.forEach(x => {
s += symbols[parseInt(Math.random() * symbols.length)];
});
s += "\n";
});
// optionally, add a border
if (addBorder) {
const rule = " +---" + "".padStart(xs.length, "-") + "---+ ";
const blank = " | " + "".padStart(xs.length, " ") + " | ";
s = [
"",
rule,
blank,
...s.split("\n").filter(l => l.trim() != "").map(l => ` | ${l} | `),
blank,
rule,
""
].join("\n")
}
// render
input.value = s;
render();
// hackily hide input
input.style.color = "#ddd";
input.style.backgroundColor = "#ddd";
// hide non-converted symbols from svg
document.querySelectorAll("svg text").forEach(e => e.style.display = "none");
// randomly color in some open circles
document.querySelectorAll("svg circle.opendot").forEach(e => {
if (rint(0, 1) == 0) {
e.style.fill = `rgb(${rint(0,255)},${rint(0,255)},${rint(0,255)})`;
}
});
// other ideas
/*
// randomly change opacity of some paths
document.querySelectorAll("svg path").forEach(e => {
e.style.opacity = rint(0, 11) / 10;
});
// scale up some circles by random amounts
document.querySelectorAll("svg circle").forEach(e => {
e.style.transform = `scale(${rint(10, 20) / 10})`;
});
// rotate the whole drawing by a random amount
document.querySelector("svg").style.transform = `rotate(${rint(-90, 90)}deg)`
// invert colors
input.style.color = "#000";
input.style.backgroundColor = "#000";
document.querySelector("svg").style.filter = `invert(1)`;
// color in some open circles based on their position
const numCircles = document.querySelectorAll("svg circle.opendot").length;
document.querySelectorAll("svg circle.opendot").forEach((e, i) => {
const l = 255 * i / numCircles;
e.style.fill = `rgb(${l + rint(-32, 32)},${l + rint(-32, 32)},${l + rint(-32, 32)})`;
});
// fade image out towards the bottom (replace "populate" code above with this)
let s = "";
ys.forEach(y => {
xs.forEach(x => {
if (rint(0, h) < y) {
s += " ";
} else {
s += symbols[parseInt(Math.random() * symbols.length)];
}
});
s += "\n";
});
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment