14 unstable releases (4 breaking)
0.5.0 | Sep 21, 2024 |
---|---|
0.4.0 | Jan 21, 2024 |
0.3.0 | Dec 28, 2023 |
0.2.0 | Oct 22, 2023 |
0.1.0-alpha.2 | Sep 30, 2023 |
#191 in Visualization
586 downloads per month
6MB
7.5K
SLoC
whiskers: interactive sketches for plotter generative art
whiskers is a Rust interactive sketch environment for plotter generative art, with a Processing inspired API.
👉 Try the live demo!
It's similar to vsketch, but faster, web-ready, and with vsvg as a much stronger foundation.
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
// this is where the drawing happens:
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:
Features
whiskers is a work in progress, but currently features:
- Interactive and highly customisable interactive UI.
- Export to SVG.
- Drawing with lines, shapes, svg paths.
- Support for curves: quadratic Béziers, cubic Bézier, Catmull-Rom splines—circles. (Ellipses and arcs are supported but internally converted to cubic Bézier.)
- Transformations such as translations, rotations, scaling.
- Pen settings such as line width, color, opacity, layers.
- Grid helpers for rectangular or hexagonal grid based sketches.
- Animated sketches support.
- Random Number Generator UI with seed control (see e.g.
asteroid
example). - Integrated profiler (based on puffin).
- Web assembly compatibility, export your sketch UI for browsers (demo)
- Support for inspect variables in the UI (such as randomly generated features of the artwork or debug values)
- 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)
On top of all that, you can import other rust packages for features such as noise and boolean operations, for which you can use noise-rs
and geo
respectively (see examples noise
and astroids
).
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()
.
Call to action
This project is at an early the stage and needs your contribution. Please get in touch via discussions on GitHub or the DrawingBots’s Discord server if you feel like helping!
Dependencies
~25–67MB
~1M SLoC