There are two main schools of javascript drawing APIs: those that let you paint shapes onto a canvas that are merged into a single image (normally targeting a web canvas or similar surface), and those that remember the individual shapes and let you interact with them after they’re drawn (normally targeting surfaces like SVG, or perhaps WebGL). Generally speaking they follow what the drawing surface they target supports, though in some cases you will find libraries that try to extend one target with the capabilities of the other.
The library I’ve probably used most extensively is Mike Bostock’s D3.js, the data visualisation lib that targets SVG, though it has support for canvas as well. It was a key component of the GetBulb startup I worked on for a few years. It’s a great library: mature, full-featured, and easily composable with other libraries (like React). It was developed while Mike worked as part of the NYTimes’s data visualisation team, so you’ve probably seen it in action on some of their excellent data visualisation reports.
Recently some users have complained that it’s been too oriented towards Observable, Mike Bostock’s live visualisation editor/platform hybrid. But the previous versions are still available, and the latter complaints smack of overly self-interested users with their own expectations but no desire to pitch in on a fork that scratches their particular itch.
I’ve also used Processing, mainly via its Clojure wrapper, Quil. It’s also very full-featured and mature. It has an online analogue, p5.js, that you can use instead of the original java-hosted version, that seems to largely have parity with the original. I wrapped some processing examples from the Generative Design book using Quil a few years ago. There’s a newer version of the Generative Design book for p5.js which I’ve still to dig into but looks every bit as good as the first. The companion machine learning library, ml5, is also worth checking out.
Other libraries that I’ve used, though not as extensively as Processing or D3 include:
- thi.ng is extraordinary. Karsten Schmidt is a phenomenally productive coder and visualisation artist. He’s written far more lines of Clojure & Clojurescript than I could ever hope too as part of his data visualisation libraries - and then for good measure ported them all to Typescript while still expanding their functionality. They’re a bit harder to get into due to their breadth and the docs assuming a higher level of competence than a typical introductory guide. But the scope and quality of these libraries is breath-taking. A magnum opus. I attended one of his workshops in London about 5 years ago and I recommend them whole-heartedly to anyone.
- Pts, which I really like, largely because of its rational attempt to organise its API around “abstractions of Space, Form, and Point”. Space is equivalent to a drawing surface, Form to a pen or other means of making marks, and Point to the data representation of your visual idea. The documentation is excellent too. William Ngan, it’s author, has a good Medium blog as well.
- Two, a “two-dimensional drawing api geared towards modern web browsers”. It can target any of SVG, Canvas or WebGL, and comes with a scenegraph and animation loop. I need to trial it properly. The name is either a reference to three.js or a nice case of simultaneous invention by two separate authors.
- Three, a low-complexity, lightweight 3D engine. It usually targets WebGL but it can also work with Canvas or SVG. It’s another large piece of code to navigate but their fundamentals series gets you up and running quickly. Courtesy of Mr Doob - check out his homepage, currently it’s a fun multi-user sketch pad.
- Skija which I’ve mentioned in passing before - looks like a great target for lower-level drawing access than what Processing offers. Also focused on the JVM, built on the Skia, the cross-platform 2D drawing library. Unlike most of the others this one can’t target web-hosted drawing surfaces, though maybe you could get part of the way there with Emscripten, Skia & the Canvas API?
That’s not even a complete list 😅 but this is turning into quite the library zoo. There’s some tantalising examples of generative design using J, the array programming language, which I’ve not had time to dig into too closely, and I’ve not even mentioned where I first started getting into this kind of stuff - back when I was a teenager and one half of the demoscene Mesmery team on the 8 bit Commodore 64. Hilariously that might’ve been when I got the most stuff done - there wasn’t quite the paralysis of choice the above list hints at…