Coder Social home page Coder Social logo

void's Introduction

Void

A toolkit for making generative art.

IntroductionExamplesDocumentation


Void makes it easy to create and explore generative art. It gives you the workflows you know from modern graphics programs, paired with a simple, powerful library for building sketches with HTML's <canvas>.

  • Tweak variables. The traits of a sketch can be changed directly in the UI, so you can experiment quickly, and create a variety of different outputs.

  • Export artwork. The output of a sketch can be exported to raster formats like PNG or JPG, as well as vector formats like SVG out of the box!

  • Control randomness. Changing the random seed for a sketch allows you to reproduce existing outputs, or create entirely new outputs.

  • Customize layout. Use common presets like Letter, A4, or 1080p, or define a custom size, add margins, change orientations, etc.

  • Import dependencies. Sketches are just JavaScript (or TypeScript) files, so you can import useful helpers from npm packages or neighboring files as usual.

  • Bundle efficiently. The Void library is designed to be completely treeshake-able, so it produces the absolute smallest bundle sizes when packaging up your code.

  • Feel familiar. Void's UI is inspired by modern tools like Figma and Blender, its API is inspired by creative coding frameworks like P5.js and canvas-sketch.



Introduction

To get started, download the Void desktop app:

Download for Mac (Apple Silicon) Download for Mac (Intel) Download for Windows Download for Linux

Install the void package:

npm install --save void

Create a new sketch file:

import { Void } from 'void'

export default function () {
  let { width, height } = Void.settings([300, 300, 'px'])
  let radius = Void.int('radius', 10, 150)
  let ctx = Void.layer()
  ctx.beginPath()
  ctx.arc(width / 2, height / 2, radius, 0, Math.PI * 2, false)
  ctx.fill()
}

Then open the sketch file with the Void app:

A screenshot of the basic sketch in the Void app.

If you see a black circle on the screen, congrats!

The Radius trait has a randomly generated value. You can change it in the sidebar and the sketch will update in real time. This is a simple sketch that draws just one shape, but you can do a lot more…


Examples

Void is designed to make it easy to quickly iterate on sketches, so you can explore new ideas quickly. To get a sense for what's possible, here are some examples:

Download and open any example file in the Void desktop app to see their output.


Documentation

Void's API is designed to be extremely simple to use. It gives you a handful of tools that are useful when making generative art, and it delegates the rendering itself to the HTML <canvas> element.

It's built as a series of helper functions:


License

Void is open-source and MIT-licensed. If you run into issues or think of improvements, all contributions are very welcome! Feel free to open an issue or submit a pull request.


Thanks

Thanks to Eric Johnson for letting us use the void package name on NPM! Thanks to Lauren Lee McCarthy and Matt DesLauriers for creating P5.js and canvas-sketch which served as inspiration for the API.

void's People

Contributors

ianstormtaylor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

void's Issues

Consider adding `Math.nudgeTo`

For when dealing with small floating point errors. It would "fix" the error if it was within a tiny distance from the equivalent rounded number. So for example:

let x = 0.1 + 0.2
// 0.30000000000000004

Math.nudgeTo(x, 1)
// 0.3

Math.nudgeTo(0.3005, 1)
// 0.3005

Where the epsilon value is the same as the existing Math.TOLERANCE (aka tiny).

Or alternatively try to get fancier with a single argument — https://github.com/TetroGem/fix-floats/blob/main/index.mjs — but I'm unsure if that covers all cases.

Auto-update crashes on restart

Not sure what's going on, but something with the Electron auto-updated isn't configured properly. If you press "Restart" when an update is ready, it won't relaunch and when you manually launch it errors.

Add aspect ratio configuration

So you can choose a specific aspect ratio without having to define a specific width. For when the sketch is full screen.

Add variant auto-generation

If we have the gallery view from #5, we can then layer on auto-generation of variants by randomly stepping up/down the default variables which would be really cool as a way to generate new concepts you might not have been aware of

Fix float traits truncation

If you don't supply a step it will print always with 3 decimal places, which is janky for values like 1.5 which get rendered at 1.500. Should get rid of the unnecessary zeroes in those cases.

Consider a `gradient` trait

More complex than a single color, would give you a Figma-like gradient editor as the UI, and an array of stops with position and color properties, like:

[
  { position: 0, color: 'red' },
  { position: 0.5, color: 'blue' },
  { position: 1, color: 'yellow' }
]

Up to the user whether they want to use it for a linear, conical, radial, etc. type of gradient.

Clear error when live reloading again

When an error happens and then you edit and save and live-reload, right now the error popups stays there sometimes, despite the sketch working again.

Add variants gallery view

If you have a few different variants (with seed and variables) of a sketch saved it would be nice to be able to show a grid-like gallery view with all of the variants rendered so you can quickly navigate between them.

Add play/pause/stop buttons

For animations. I'll often want to pause at a certain frame, or even just to hit stop to save CPU while going to edit the code for a bit.

Add mouse helper

To get the mouse's x and y coords if its over the canvas. I think just as a single object reference that gets updated so that you can always check mouse.x for the latest values, like:

let mouse = Void.mouse()

Void.draw(() => {
  if (mouse.x == 100) ...
})

Add HTML export

Should bundle the sketch into a single HTML file that you can just open in the browser.

Non-inlined sourcemaps don't load

Because the entrypoint server is really simple currently, and just serves sketch.js and sketch.js.map, if any of the imported packages in a sketch don't include their sourceContent inline in the sourcemap, they won't be able to be loaded by devtools.

In TypeScript a third-party package can make its source content inlined by setting…

{
    "sourceMap": true,
    "inlineSources": true,
}

…but many won't have done that.

Ideally either the server could serve all files (need to check if this is secure first though). Or the single sourcemap could get all of its source files's content inlined, and its JSON can be updated with the new source content strings before serving.

Imported local files don't trigger live reload

Right now if you import an local file (instead of a dependency) it doesn't get picked up by the reloading service, so nothing new is built. This is due to esbuild not having bundle: true specified for it's watcher.

Add color switch to color traits

Just detecting whether it's a color and then adding a little swatch next to the value to see the color itself. Potentially also getting smarter with a striped swatch for color palette arrays.

Showing/hidden layers shouldn't restart sketch

Right now it restarts the sketch, but it should really just toggle the visibility of the DOM element instead. For static sketches it's equivalent, but for animations the current behavior is tedious.

Add folder gallery view

It would be nice to be able to open an entire folder (similar to how you would in VSCode) instead of a file, and then see a representation of all the sketches in that folder in a little grid/list you can move between.

Could model it off of Figma's setup with the tabs in the top bar and a "home" tab which shows the directory.

Add undo/redo stack

When changing traits, orientation, seed, etc. it would be cool if you could cmd+z to undo something you just did.

Add recent files list

Just an easy way to re-open previous tabs. Probably good to have it in the operating system-native menu first, and maybe in the tabs bar like Figma?

Change traits to have no defaults

Right now the second argument to trait resolves to a default value, which is always used unless you've generated a random one (and these generated values aren't seed-dependent). But I think it would be better to always be generating a random value tied to the seed.

And you can always use an enum with just one entry to set a constant value when starting out, eg:

let nib = trait('enum', [0.2])

Which you can then expand with more options later.

Whereas now using simple numbers will represent the step argument:

let amount = trait('amount', 0.1) // shorthand for { step: 0.1, min: 0, max: 1 }
let count = trait('count', 2) // shorthand for { step: 2, min: 2, max: 2 * 5 }
let angle = trait('angle', 90) // shorthand for { step: 90, min: 0, max: 360 }

But you could potentially also use the min, max, step longer-hand (although might be too confusing, better as object):

let amount = trait('amount', 0.25, 0.75, 0.05)
let count = trait('count', 3, 7, 1)
let angle = trait('angle', 0, 360, 45)

Consider adding default `false` boolean traits

Right now when creating a boolean trait, either true or false are both treated the same.

But there's a common use case of making a "flag" trait for development that defaults to false but can be toggled on (like "show gridlines"). It could be that using false as the default value will always make the trait locked when first run?

Either that or maybe there's value in a flag helper that never gets exported?

Add a next frame button

So that you can have an animated sketch paused, but inch forward a frame at a time.

Potentially even a shift and option+shift variants like in design programs to jump 10 or 60 frames forward as well.

Consider adding layers

Not sure exactly how this might work. But it would be awesome if you could define layers that you can then show and hide directly in the UI instead of going in and commenting things. And if we could add in the ability to associate a default stroke/fill with a layer, the you could change that in the UI as well.

Technically you could string this functionality together with your own custom variables, so not sure yet whether there's some emergent properties that make it worth doing.

Change saving to include variables

Right now when you "heart" a sketch it just saves the random seed. But it should save the variables too, so you can build up custom settings and save the good ones for later.

Add loading indicators to export buttons

If you export an animation it replays the whole thing to export it, so it can take a while, so we need a little indicator showing the frame ticking by so you know how long it will take.

Reintroduce PDF exports

Didn't really have this working well, so need to re-think. It's useful for situations where you're dealing with printer software or laser cutter software that accepts PDFs but doesn't recognize SVGs.

Consider supporting P5.js

Since P5.js is so widespread, it would be really cool if we could make it so that any valid P5.js script was also valid. Not exactly sure if it's possible or worth it or what it would entail though.

There are certain things like context.random that are much nicer than what P5.js gives you, so I feel like they should still be exposed even though P5.js gives you a few helpers.

Consider adding hash to seed panel?

Some frameworks have a hash associated as the main seed. It could be cool to visualize the hash if the framework used is one of those (like fxhash or art blocks)

Consider button/function traits

Which is a button that when clicked invokes a function. Something like:

Void.button('name', () => {
  // do something here…
})

Only useful in animated sketches, since you can react to the button click by for example toggling a variable, like a light/dark color theme for instance.

Not super priority, since for most things you could just use regular clicks on the canvas, or right-clicks for a secondary action, or button presses, etc.

Consider adding a math utility

There are certain utility functions that everyone reinvents for generative art, like range, subdivide, lerp, unlerp, clamp, etc., etc. which could make a case for adding a context.math helper with some of these. Ideally they should already be in JavaScript natively, but that won't happen soon.

Add animations / frames

Right now for simplicity it's just a single frame. But the API should be that you return a function that gets called with requestAnimationFrame and then it'll keep going. As well as a context.frame property that you can react to.

Might need to just quickly investigate whether using generators would be a good idea, but I feel like it might be too complex.

Add trait nesting

If you define variables inside an object it should group them together inside a dropdown. So you could define a series of show variables like so:

variables: {
  show: {
    grid: false,
    lines: true,
    dots: false,
  }
}

And they'd be collapsed under "Show >" by default and you could expand to see them.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.