Writing generative art on an iPad: Why and how
7 minutes read | 1280 words by Ruben BerenguelIf you have been paying attention, you may have seen me talk about p5js and generative art lately. Here is a break-down of the why and how.
Why?
I like creating things. This is the fundamental driving force: I have run the full gamut of “stuff you can do”. And I enjoy all of them (sadly?) I have knitted, crocheted, bobbin laced, embroidered and tatted. I have done (and published) origami, cut kirigami, quilled paper strips, created foldable pop-ups, scissor-cut silhouettes, knife cut paper art. I have drawn watercolor, pencil, ballpoint pen, gouache. Broad and fine calligraphy. I have carved spoons, made shoes. I will play almost any instrument I lay my hands on (I don’t care how badly). Generative art is just another medium I can use to enjoy life.
I have a past with generative art, going back to when I was starting programming. I never got very into it, but even before becoming a mathematician I was fascinated by IFS (Iterated Function Systems) and fractals like the Mandelbrot set. Probably my first two “proper” generative pieces were done as part of a long-lost tradition, of Christmas postcards I would email friends and colleagues: approximating images with translucent triangles (2010) and Postscript Christmas Card (2008) (the code for the latter is here). But since those two, the only generative items I created were based on my research on complex dynamics.
What has changed? When COVID lockdown started, I got a vague surge of energy to finish some personal projects. I wrote a significant amount of free-time-code (mostly Python). This required being in front of the computer many hours, after work, meaning I was sitting in front of my computer for 14 or 15 hours a day. That’s not particularly good. I decided to stop being too much in front of it (limiting it to around 1 non-work hour), and that left me wondering what I could do with the I want to code but don’t know how time I had remaining.
This gets us to the how section.
How?
It started on Saint George’s day, when I created a generative rose for Laia using p5js. I based it on some examples for other types of flowers, with a lot of patience tweaking values. This was on my computer, with emacs, all as usual development goes for me. I saw how easy p5js is, and how impressive the results can be. That was the seed. Those days I was giving some final touches to some project or another, so I left the seed to sprout.
Then, after 5 or 6 days (either late April or just beginning of May), I was sitting on the sofa with just my iPad Mini, watching something on TV and I cracked open a text editor, trying to use p5js on it. And… it worked.
I was lucky in that the first editor I tried is the excellent Textastic: it not only offers a native webview with console logging, but also can serve against Safari. From that point on, I was hooked: I could do something fun and creative while watching TV, on the off-hours, away from my computer.
The setup
The setup is mostly Textastic and Safari for p5js documentation. I have just found out about Inspect Browser, but haven’t tried it yet. There are some quirks, tips and tricks that may be interesting though.
Syntax errors in Textastic
Sadly, the console/webkit view provided by Textastic doesn’t report on badly written Javascript. If you forget a brace, paren or similar you will just get a blank screen. It was puzzling at the beginning, now I just have gotten terribly good at spotting missing delimiters. And a recent update added marking of unbalanced delimiters (in some cases only as far as I have seen) which should help tremendously.
Too much logging in Textastic
You can’t go crazy by logging in every line of a tight for
loop. This
will make Textastic slow to a crawl, and possibly OOM. I recommend you add a
div
where you can write logs regularly if you need to write a lot of them. I
haven’t tried this myself yet, but it’s on my plans for some projects where I
need significant logging output.
p5js instance mode
If you are moderately serious, you want to start using instance
mode. All the
examples (except the first) in my sketches
repository use instance mode. Why?
Because of ES6 modules. This way I can have some libraries/common code I can
import straight from the code with import
statements.
Parameterise/add some GUI/controls
This is something I read here, at least in having a way to tweak all parameters. I started using datgui, but promptly decided I didn’t like it and whipped a small div with a few basic controls. This has grown into my own personal library of GUI/sketch.
You don’t need to go that deep. Use datgui, or
p5gui or any other option you find. Or
at least add a handler for s
to save the current image, and build from that.
Being able to tweak values quickly, and save the current canvas pay off
extremely quick.
Testing, linting, etc
If you are on an iPad, the amount of tools you have at your disposal is significantly reduced. These are some options I have found, you may find others, or just ignore them. After all, not everybody is a fan of linters and testing. Note that on my code I avoid semicolons as much as I can. This is on purpose.
Beautifying Javascript
I use the online beautifier.io with all settings at default. I just want something consistent across all my files. I try not to care too much about formatting. For Python, I use black. For Scala, scalafmt. I want consistency, even if I dislike some of the choices of any of these tools under defaults, consistency eventually pays off.
Linting
I have rarely used it in my sketches, but when I’ve done, I used
JSHint. It kind of works, although you need to set it up
to ignore missing semis (/*jshint asi*/
header comment, see
divide).
Testing
I was ecstatic to find out you can run mocha/chai tests directly in the browser. I have used them to test parts of the GUI library to avoid regressions. For now I haven’t tested much more, but I plan to keep using it. They are easy to write and having tests is useful.
TDD
I haven’t followed my usual TDD approaches. Since I’m exploring areas where I don’t know either the result or how to get there, TDDing would be too painful/wasteful. Also, I do this for fun. If it doesn’t work, it’s kind of fine. When I’m done with a sketch and I consider it finished, I want it to always work, of course. But the amount of things that are untestable in p5js is large (will it look good? will it actually work…?) so I restrict testing to where it really shines: small helper methods, mathematical routines, etc.
Documentation, publishing, sharing
I have shared most of my sketches (and the ones I haven’t is because they are unfinished). Not only I think these can be useful to somebody else, but the act of polishing them knowing they may be seen makes them better. At least I get a small jolt of pride at having posted some relatively easy to read code that anybody can use in the future. Consider doing the same, you never know what may come from your code.
As for sharing, I share my creations in r/generative and while I’m creating them, on my Instagram account.