A library for creating generative art with Elixir. Currently Sketch only supports generating static images (There's only so much one can achieve in 48h, hopefully there will be animation in the future)
The code used to generate all of the images below can be found in the Examples
module
Generated with Examples.colourful_grid() |> Sketch.save()
Generated with Examples.candy_dots(6) |> Sketch.save()
Generated with Examples.maurer_rose(6, 71) |> Sketch.save()
. Have a look at the Wikipedia article for more information about the Maurer rose, and for more values to try!
Generated with Examples.barnsley_fern(7000) |> Sketch.save()
. Have a look at the Wikipedia article for more information about the Barnsley Fern
This one would look even cooler with higher detail, but I hit the limit of what Mogrify
could deal with at around 7000 drawing operations. Optimizations to come after Spawnfest I'm afraid!
Currently Sketch is not yet available on Hex, but to give it a try you can install it directly from this repo.
def deps do
[
{:sketch, git: "https://github.com/spawnfest/toe-BEAMS.git", branch: "main"}
]
end
One of the main aims of Sketch is to be easy and intuitive to use, so basic usage is fairly simple: Create a %Sketch{}
struct with Sketch.new()
, and use any of the other functions to add or change things about your sketch. Since all functions in the
main Sketch
module take a %Sketch{}
as the first argument and return a %Sketch{}
, you can easily pipe everything together.
Once you've built your final Sketch
, you can call Sketch.run(sketch)
to render it on screen (using wxWidgets
), or Sketch.save(sketch)
to save it as a png
. (Note: saving to PNG requires you to have ImageMagick installed on your machine)
In addition, I unfortunately only had access to a MacBook this weekend. I am not aware of any reasons why things shouldn't work as expected on other operating systems, but figured I'd mention it just in case...
Sketch.new()
|> Sketch.set_fill({100, 100, 100})
|> Sketch.square(%{origin: {0, 0}, size: 50})
|> Sketch.run()
This will draw a medium gray square with its top left corner at x 0, y 0 and a width and height of 50.
To add more shapes to the canvas, just keep piping:
Sketch.new()
|> Sketch.square(%{origin: {0, 0}, size: 50})
|> Sketch.rect(%{origin: {0, 0}, width: 10, height: 20})
|> Sketch.line(%{start: {0, 0}, finish: {50, 50}})
|> Sketch.save()
Any fill, stroke or transforms applied to the sketch will apply to anything added after, and will stack with any applied before them. You can use Sketch.reset_matrix/1
to remove all transforms applied up until that point. A future goal is to allow overrides on specific primitives, but that is beyond the scope of a weekend.
Sketch.new()
|> Sketch.translate({20, 20})
# This next square will be drawn at {20,20} from the top left
|> Sketch.square(%{origin: {0, 0}, size: 50})
|> Sketch.translate({10, 10})
# This next square will be drawn at {30,30} from the top left
|> Sketch.square(%{origin: {0, 0}, size: 50})
|> Sketch.reset_matrix()
# This next square will be drawn at {0,0} from the top left
|> Sketch.square(%{origin: {0, 0}, size: 50})
|> Sketch.save()
A brief overview of features that are available so far, and ones that you might expect from a drawing library, that are not yet implemented.
- Sketch size
- Sketch title
- Sketch background colour
- Specify png save location
- Line
- Rectangle
- Square
- Ellipse
- Circle
- Point
- Triangle
- Arc
- Quad
- Path (for more complex lines)
- Translate
- Rotate
- Scale
- Reset all transforms
- Skew
- Push & Pop
- Fill
- No Fill
- No Stroke
- Stroke colour
- Stroke weight
- Alpha support
- HSV support
- Gradients
- Stroke style (dashed lines etc.)
- Lerp
- Map
- Processing & P5.js for much of the functionality and overall approach to making ✨art✨.
- The Coding Train for general generative art inspiration!
- Scenic as inspiration for how to structure things (although much of that is too ambitious for this 0.0.1 Spawnfest version)
Thinking beyond this hackathon, there are many things that could (should) probably be improved and expanded on in no particular order!
- Animation!
- Use OpenGL instead?
- Text
- Math and Random helper modules
- Random seeds and persisting those so screen/png are the same result
- Interaction??
- More graceful starting of the wx object when calling
Sketch.run/1
- Test coverage
- Friendly errors
- Figure out why the
wx
window sometimes doesn't get the render message?