12 unstable releases (3 breaking)
0.4.0 | Jan 21, 2024 |
---|---|
0.4.0-rc.0 | Jan 20, 2024 |
0.3.0 | Dec 28, 2023 |
0.2.0 | Oct 22, 2023 |
0.1.0-alpha.2 | Sep 30, 2023 |
#165 in Visualization
53 downloads per month
6MB
6.5K
SLoC
whiskers: interactive sketches for plotter generative art
👉 Try the live demo!
whiskers is a Processing-like interactive sketch environment and API built over vsvg and vsvg-viewer. It's similar to vsketch, but faster, web-ready, and with much stronger foundations.
Installation
Simply add whiskers as a dependency to your project:
cargo add whiskers
Usage
Here is the code for a basic sketch:
use whiskers::prelude::*;
#[sketch_app] // <- this is the magic to make the sketch interactive
struct HelloWorldSketch {
width: f64, // <- interactive UI is automagically built for these fields
height: f64,
}
impl Default for HelloWorldSketch {
fn default() -> Self {
Self {
width: 400.0,
height: 300.0,
}
}
}
impl App for HelloWorldSketch {
fn update(&mut self, sketch: &mut Sketch, _ctx: &mut Context) -> anyhow::Result<()> {
sketch.color(Color::DARK_RED).stroke_width(3.0);
// the `Sketch` API is a delight to work with
sketch
.translate(sketch.width() / 2.0, sketch.height() / 2.0)
.rect(0., 0., self.width, self.height);
Ok(())
}
}
fn main() -> Result {
HelloWorldSketch::runner()
.with_page_size_options(PageSize::A5H)
.run()
}
This is the result:
whiskers is part of the vsvg project.
Features
- Interactive UI automatically built based on the sketch
struct
's fields. - Sketch parameter UI highly customisable using
#[param(...)]
attributes (see e.g.asteroid
example). - Sketch parameter UI easily extendable for custom data types (see e.g.
custom_ui
example). - Page size management UI.
- Export to SVG.
- Support for curves (including quadratic Béziers, cubic Bézier, Catmull-Rom splines—circles, ellipses and arcs are supported but internally converted to cubic Bézier).
- Time parameter management UI (for animated sketches).
- Random Number Generator UI with seed control (see e.g.
asteroid
example). - Integrated profiler (based on puffin).
-
Grid
helper for grid-based sketches. -
HexGrid
helper for hexagonal-grid-based sketches - Configuration handling (save/restore config, etc.).
- Compiled sketches are also a flexible CLI utility with the capability to batch generate sketch outputs with parameter ranges.
- Export to other format through templating (HPGL, g-code, etc. — for now, please use vpype).
- ... (please complete this list)
Isn't that vsketch?
Compared to vsketch, whiskers offers the following advantages:
- It's in Rust, so it's faaast! 🚀
- Sketches can be compiled to WebAssembly and published on the Web (try it here).
- It's built on a stack (mainly egui and wgpu) that's much faster and easier to work with.
On the other hand:
- It's in Rust, which has a steeper learning curve than Python.
- Since sketches are compiled, the edit code/execute cycle is heavier than with vsketch.
I have the vague dream to slap a Python front-end on top of whiskers to build vsketch 2.0, but that's a lot of work and other things have a higher priority, so no promises on this front.
Running examples
To run the example, use the following command (in this case to run crates/whiskers/examples/asteroid.rs
):
cargo run --release --package whiskers --example asteroid
Non-interactive use
The whiskers::Sketch
object can be used stand-alone, without the interactive sketch runner. This is useful if you want to use the drawing capabilities in your own tools.
For example, I use whiskers::Sketch
to build the generative asteroids in my Rusteroïds toy game.
Here is how the code could look:
use whiskers::prelude::*;
fn main() -> Result {
Sketch::with_page_size_options(PageSize::A5)
.scale(Units::Cm)
.translate(7.0, 6.0)
.circle(0.0, 0.0, 2.5)
.translate(1.0, 4.0)
.rotate_deg(45.0)
.rect(0., 0., 4.0, 1.0)
.save("output.svg")?;
Ok(())
}
If the viewer
feature of *whiskers is enabled (which it is by default), the sketch can be displayed using the basic viewer using sketch.show()
.
Dependencies
~23–69MB
~1M SLoC