Skip to content

Latest commit

 

History

History

sketch

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

nightsketch

A low-boilerplate framework for making sketches with the nightgraphics crate

Overview

The purpose of this crate is to house the artworks ("sketches") and a way to interact with them in the graphical and command line interfaces. The design philosophy here is to minimize infrastructural code (such as field access and modification, and sketch listings) through macros. This is heavily at odds with the Rust best practices to avoid implicitness, and therefore is only really appropriate for usage within this workspace. See nightsketch_derive for an overview of the code that is generated by the #[sketch], #[param], etc macros.

Anatomy of a sketch

/// If a doc comment preceeds the struct declaration, it is used as the
/// description of the sketch, for example in the help/usage text of the
/// nightgraph-cli command. Similarly, the struct's name is used as the
/// sketches name. Both are overridable with attributes, see the "attributes"
/// section of this README
#[sketch]
pub struct ConcentricCircles {
    // Fields defined in the sketch's struct are exposed to the CLI/GUI as
    // parameters, if their datatype is supported. The #[param(key=val)]
    // attribute allows further customization. Just like the struct,
    // doc comments are used for parameter descriptions, and names are
    // processed to be "kebab-cased" (such-as-this)

    /// Number of circles to place
    #[param(default = 5, range = 1..=30)]
    circle_count: u32,

    /// Spacing between each circle (in mm)
    #[param(name = "spacing", default = 0.5, range = 0.01..=10.0)]
    circle_spacing: f64,

    // Note: when bools are default true, the generate command
    // line flag is prefixed with a "-no" to indicate negation,
    // e.g. --no-randomize-center

    /// Whether or not to randomize each circle's center point
    #[param(default = true)]
    randomize_center: bool,

    // Fields can be skipped, such as for caching certain intermediate
    // geometries for subsequent renders
    #[param(internal)]
    cached_circles: Option<Vec<Circle>>,
}

/// Each sketch needs to implement the `Sketch` trait's `exec` method.
impl Sketch for ConcentricCircles {
    fn exec(&self) -> SketchResult<Canvas> {
        // The general mechanic of a sketch is adding shapes to a canvas
        // which is then returned so that the caller can render it to the
        // desired output format, such as SVG or egui shapes.
        const WIDTH: f64 = 11. * INCH;
        const HEIGHT: f64 = 17. * INCH;
        let mut canvas = Canvas::new(point(0, 0), Size::new(11. * INCH, 17. * INCH));

        let page_center = point(WIDTH / 2., HEIGHT / 2.);

        for n in 0..self.circle_count {
            ...
        }

        ...

        Ok(canvas)
    }