plotwork -- an experimental generative art framework enabling generative art experiments.
(The idea isn't new and I'm probably doing it wrong. I don't know the space, I didn't know what existed before building this. It works for me though.)
This project is an interactive web interface to plot canvas drawings and control their variable parts dynamically.
- An overview of all plots, displaying them as thumbnails.
- Creating a new plot is as simple as dropping a JS file into a specific directory; plotwork automatically detects it and reloads.
- Displaying a single plot automatically renders a "control panel" allowing the user to change parameters and see the resulting plot in real-time.
Check out the source of the demo plot demo.js
, or the minimal plot minimal.js
.
Taking a look at the minimal example, minimal.js
might help. It only exports what needs to be exported, nothing else.
export const tweak = {
seed: ''
}
The tweak
object is the "magical" part of this project. Nothing special in there, it leverages the fact that JavaScript objects are references (they are one of the Reference types, aka complex types or container types).
It must contain a seed
key with string value. When tweak.seed
is the empty string, it will be assigned a random seed.
To export a variable you want to tweak from the frontend, add a property with a default value to the tweak
object and use it with tweak.myProperty
in your generate()
function.
Although any variable type can be tweaked because the interface exposes the tweak object as an editable JSON field, some variable types provide a nicer tweak interface:
-
strings
legend: 'hello'
-
numbers
quantity: 11.98
-
boolean
flag: true
-
ranges
between: [1, 10]
You can see most of them in use in the demo plot demo.js
.
As we have seen in a. 1. tweak
variable types, some variable types generate user-friendly knobs. These can be made more helpful by providing some metadata.
For instance let's export the seed, a range and a number:
export const tweak = {
seed: '',
sides: [3, 8],
depth: 3
}
seed
being a string, it will be rendered as a text input (remember that you have to export the seed)sides
being a list of two numbers, it will be rendered as a range sliderdepth
being a number, it will rendered as a slider
We have default values for these, let's be a bit more specific by exporting the following tweakMetadata
object:
export const tweakMetadata = {
sides: {
label: 'Each shape will have between x and y sides',
range: [0, 20]
},
depth: {
label: 'How deep this shape is',
min: 1,
max: 10
},
}
That way the frontend will have better information on how to render more useful tweak sliders.
Try it for yourself or take a closer at the demo plot demo.js
.
export const dimensions = [40, 40]
export function generate (context, tweak) {
return function render ({disableAnimation, step}) {}
}
generate(context, tweak)
gets called with:context
, the canvas context, use it inrender()
tweak
, thetweak
object
render({disableAnimation, step})
gets called with:disableAnimation
(bool, default: false), the frontend can tell you not to draw step by stepstep
(int), which step to render, starts at 0 and increments on requestAnimationFrame, use it to animate the drawing
Take a look at the code and comments in the minimal plot example, minimal.js
.
- Presets: a way of exporting the
tweak
object and to quickly recall it. It would be something like "saving" the result of having tweaked things. - Full export: I'm thinking about writing the full source of the
.js
file together with the tweaked chosen values right into the exported SVG file, in a big<!--XML comment-->
. It might be interesting for archival/reproducibility. - Try to add examples using
Paper.jsand other libs.- For Paper.js, see
paper.js
- For Paper.js, see
- Go back to actually create some generative/procedural art instead of building this, that's been enough of yak shaving for now.
# install dependencies
yarn
# or
npm install
npm run dev
Copy the minimal example and start modifying it.
cp plots/minimal.js _plots/something.js
The server will automatically pick it up and update the page in your browser, you should now
see something.js
on http://localhost:8080.
- My main inspiration for this software is penplot by @mattdesl (website). I wanted a tweakable version of his amazingly fun tool.
- I discovered apparatus.generated.space by @kgolid a few days before releasing this project. If only I knew about dat.gui before creating this…
- Shout out to @inconvergent, whose work keeps me inspired.
This project is licensed under AGPLv3. You can read it in the LICENSE file.