Cleaned up styles
parent
db222246f2
commit
b19ffd494a
|
@ -1,5 +1,12 @@
|
||||||
# poptimal
|
# poptimal
|
||||||
|
|
||||||
|
An experiment in using Observable to generate colourful SVG patterns
|
||||||
|
reminiscent of op art or halftone dots.
|
||||||
|
|
||||||
|
Comments, feedback via Mastodon: [Mike Lynch](https://aus.social/@mikelynch)
|
||||||
|
|
||||||
|
## Observable
|
||||||
|
|
||||||
This is an [Observable Framework](https://observablehq.com/framework/) app. To install the required dependencies, run:
|
This is an [Observable Framework](https://observablehq.com/framework/) app. To install the required dependencies, run:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -16,6 +16,22 @@ function random_colour() {
|
||||||
return d3.rgb(r, g, b).formatHex();
|
return d3.rgb(r, g, b).formatHex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function random_palette() {
|
||||||
|
|
||||||
|
// monochrome
|
||||||
|
// one spot
|
||||||
|
// two spot
|
||||||
|
// RGB
|
||||||
|
// CMY
|
||||||
|
// RYB
|
||||||
|
// triad - full saturation
|
||||||
|
// triad - pastel
|
||||||
|
// trial - dusk
|
||||||
|
// random HSV
|
||||||
|
// random RGB
|
||||||
|
}
|
||||||
|
|
||||||
class DotControls {
|
class DotControls {
|
||||||
//
|
//
|
||||||
constructor(fg, radius_opts) {
|
constructor(fg, radius_opts) {
|
||||||
|
@ -23,14 +39,14 @@ class DotControls {
|
||||||
this.fg = Inputs.color({label: "colour", value: fg});
|
this.fg = Inputs.color({label: "colour", value: fg});
|
||||||
this.m = Inputs.range([1, 5], {value: 2, step: 1, label:"m"});
|
this.m = Inputs.range([1, 5], {value: 2, step: 1, label:"m"});
|
||||||
this.n = Inputs.range([1, 5], {value: 2, step: 1, label:"n"});
|
this.n = Inputs.range([1, 5], {value: 2, step: 1, label:"n"});
|
||||||
this.r = Inputs.range([0, 0.5], {value: 0.3, step: 0.01, label: "radius"});
|
this.r = Inputs.range([0, 0.4], {value: 0.2, step: 0.01, label: "radius"});
|
||||||
this.f = Inputs.select(radius_opts, {value: radius_opts[0]});
|
this.f = Inputs.select(radius_opts, {label: "gradient", value: radius_opts[0]});
|
||||||
}
|
}
|
||||||
|
|
||||||
random_grid() {
|
random_grid() {
|
||||||
this.m.value = random.choice([1, 2, 3, 4, 5]);
|
this.m.value = random.choice([1, 2, 3, 4, 5]);
|
||||||
this.n.value = random.choice([1, 2, 3, 4, 5]);
|
this.n.value = random.choice([1, 2, 3, 4, 5]);
|
||||||
this.r.value = random.float(0, 0.5);
|
this.r.value = random.float(0, 0.4);
|
||||||
this.f.value = random.choice(this.radius_opts);
|
this.f.value = random.choice(this.radius_opts);
|
||||||
this.m.dispatchEvent(new Event("input"));
|
this.m.dispatchEvent(new Event("input"));
|
||||||
this.n.dispatchEvent(new Event("input"));
|
this.n.dispatchEvent(new Event("input"));
|
||||||
|
|
|
@ -6,10 +6,10 @@ const RADIUS_OPTS = [
|
||||||
"left",
|
"left",
|
||||||
"up",
|
"up",
|
||||||
"down",
|
"down",
|
||||||
"RU",
|
"right-up",
|
||||||
"RD",
|
"right-down",
|
||||||
"LU",
|
"left-up",
|
||||||
"LD",
|
"left-down",
|
||||||
"in",
|
"in",
|
||||||
"out",
|
"out",
|
||||||
];
|
];
|
||||||
|
@ -58,13 +58,13 @@ class DotMaker {
|
||||||
return maxr * d.y / this.width;
|
return maxr * d.y / this.width;
|
||||||
case "up":
|
case "up":
|
||||||
return maxr * (this.width - d.y) / this.width;
|
return maxr * (this.width - d.y) / this.width;
|
||||||
case "RU":
|
case "right-up":
|
||||||
return 0.5 * maxr * (d.x + this.width - d.y) / this.width;
|
return 0.5 * maxr * (d.x + this.width - d.y) / this.width;
|
||||||
case "LU":
|
case "left-up":
|
||||||
return 0.5 * maxr * (this.width - d.x + this.width - d.y) / this.width;
|
return 0.5 * maxr * (this.width - d.x + this.width - d.y) / this.width;
|
||||||
case "RD":
|
case "right-down":
|
||||||
return 0.5 * maxr * (d.x + d.y) / this.width;
|
return 0.5 * maxr * (d.x + d.y) / this.width;
|
||||||
case "LD":
|
case "left-down":
|
||||||
return 0.5 * maxr * (this.width - d.x + d.y) / this.width;
|
return 0.5 * maxr * (this.width - d.x + d.y) / this.width;
|
||||||
case "out":
|
case "out":
|
||||||
return 2 * maxr * distance((d.x - this.cx), (d.y - this.cy)) / this.width;
|
return 2 * maxr * distance((d.x - this.cx), (d.y - this.cy)) / this.width;
|
||||||
|
|
17
src/index.md
17
src/index.md
|
@ -4,6 +4,8 @@ toc: false
|
||||||
|
|
||||||
<h1>poptimal</h1>
|
<h1>poptimal</h1>
|
||||||
|
|
||||||
|
<p>by <a href="https://mikelynch.org">mike lynch</a> | <a href="https://aus.social/@mikelynch">@mikelynch@aus.social</a> | <a href="https://git.tilde.town/bombinans/poptimal">source</a></p>
|
||||||
|
|
||||||
<div class="grid grid-cols-2">
|
<div class="grid grid-cols-2">
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
@ -20,27 +22,27 @@ const HEIGHT = WIDTH;
|
||||||
|
|
||||||
const dm = new DotMaker(WIDTH);
|
const dm = new DotMaker(WIDTH);
|
||||||
|
|
||||||
|
|
||||||
const bg_input = Inputs.color({label: "background", value: d3.color("yellow").formatHex()});
|
const bg_input = Inputs.color({label: "background", value: d3.color("yellow").formatHex()});
|
||||||
const bg = view(bg_input);
|
const bg = view(bg_input);
|
||||||
|
|
||||||
const ctrl1 = new DotControls(d3.color("red").formatHex(), RADIUS_OPTS);
|
const ctrl1 = new DotControls(d3.color("red").formatHex(), RADIUS_OPTS);
|
||||||
const ctrl2 = new DotControls(d3.color("blue").formatHex(), RADIUS_OPTS);
|
const ctrl2 = new DotControls(d3.color("blue").formatHex(), RADIUS_OPTS);
|
||||||
|
|
||||||
|
|
||||||
const fg1 = view(ctrl1.fg)
|
const fg1 = view(ctrl1.fg)
|
||||||
const m1 = view(ctrl1.m);
|
const m1 = view(ctrl1.m);
|
||||||
const n1 = view(ctrl1.n);
|
const n1 = view(ctrl1.n);
|
||||||
const r1 = view(ctrl1.r);
|
const r1 = view(ctrl1.r);
|
||||||
const f1 = view(ctrl1.f);
|
const f1 = view(ctrl1.f);
|
||||||
|
|
||||||
|
|
||||||
const fg2 = view(ctrl2.fg)
|
const fg2 = view(ctrl2.fg)
|
||||||
const m2 = view(ctrl2.m);
|
const m2 = view(ctrl2.m);
|
||||||
const n2 = view(ctrl2.n);
|
const n2 = view(ctrl2.n);
|
||||||
const r2 = view(ctrl2.r);
|
const r2 = view(ctrl2.r);
|
||||||
const f2 = view(ctrl2.f);
|
const f2 = view(ctrl2.f);
|
||||||
|
|
||||||
|
const randomise_pattern = view(Inputs.button("Random dots"));
|
||||||
const randomise_pattern = view(Inputs.button("Random grids"));
|
|
||||||
const randomise_colours = view(Inputs.button("Random colours"));
|
const randomise_colours = view(Inputs.button("Random colours"));
|
||||||
const randomise_all = view(Inputs.button("Random all"));
|
const randomise_all = view(Inputs.button("Random all"));
|
||||||
|
|
||||||
|
@ -138,6 +140,15 @@ display(svg.node());
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
h1 {
|
||||||
|
font-family: helvetica, arial, sans-serif;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-family: helvetica, arial, sans-serif;
|
||||||
|
font-size: 9pt
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in New Issue