Years ago I dabbled a bit with SVG. I didn’t really have much opportunity to do anything of consequence with it but one thing that stuck with me from that experience was its path geometry DSL. This DSL let us define shapes as a string-based sequence of commands consisting of a character and some numeric arguments. For instance, to draw a square we could write something like this:
M20,20 L20,30 30,30 30,20 Z
What this does is moves the cursor to 20,20 and draws 3 lines before connecting the end of the final line back to the start. It’s not necessarily the prettiest language but it certainly does its job and makes it store certain types of image resources right where they’re used.
Knowing a bit about the path language proved useful several years later when I was able to render some simple icons in WPF using a very similar language. By using the path DSL I was able to avoid managing a library of images since the strings could be placed inline in the XAML.
About a week ago I decided to start taking a serious look at TypeScript. As I was building out a simple application I found myself in a similar situation as I’d encountered with the WPF project; I wanted to include some images but didn’t want to maintain an image library. I immediately thought that <CANVAS> might provide the functionality I was looking for.
<CANVAS> provides a fairly rich API (through the HTML Canvas 2D Context) that lets us do some really impressive things. What really struck me as I looked over the API was that despite exposing methods that clearly trace their roots to the type of drawing I was looking to do, there was no corresponding DSL. In order to use <canvas> the way I wanted, I couldn’t use the convenient string syntax I’d come to love over the years. I’d have to instead construct shapes manually with a series of tedious method calls. This seemed like a great exercise for TypeScript and thus, TsPath was born.
TsPath is a simple parser that reads a path string (such as the one shown above) and generates a series of functions that draw the represented shape. All of the functionality is abstracted behind a single method, CanvasExtensions.drawPath, so all you need to do is pass it a reference to the canvas, the path string, and some rendering options and you’re done!
At this time, TsPath supports the following commands:
- F – Fill Mode
- L – Line To
- C – Cubic Bezier Curve
- Q – Quadratic Bezier Curve
- A – Elliptical Arc
- Z – Close Path
TsPath is available under the MIT license so feel free to use it as you wish. Of course, if you happen to find a bug or have suggestions for improvement I’d love to see some pull requests.