Complex SVG interactions using Sketch, PaintCode and Angular 2+

John Armstrong
5 min readMar 4, 2018

If you are anything like us at Smart.network, your designers are increasingly asking for widgets in a mobile app to be replicated inside a non-mobile web application. This presents a unique set of challenges when you are working native on mobile and HTML5 on web since code reuse between these environments, particularly for complex widgets, is non-existent.

Fortunately for us the tooling around platform neutral procedural components has improved dramatically over the last few years and with Angular 2+ (just Angular from here on out) it has become incredibly easy to control these procedurally generated widgets.

Lets see a simple case to illustrate how these new toolchains enable complex widgets with their own independent lifecycle to be shared cross platform.

Step 1 : Design in Sketch

If you are like everyone else, your designers are using Sketch to design their mobile app. Sketch is amazing, we all love it and it lends itself well to mobile implementation. For our specific use case, we will be looking at an EQ Graph that is embedded in the application

The graph on the right is dynamically adjusting individual bar opacity from 0.15 to 1 every few seconds

Because our mobile engineers are amazing, this was no problem. Because our web engineers (me) are slightly less amazing, this presented a challenge. I looked at a few approaches including rolling my own by hand, using something like D3 or Charts.js and emulating it as a bar chart but none of these were going to let me get the pixel perfection I needed.

(optional) Step 1 : Import into PaintCode

Enter: PaintCode! PaintCode is a really interesting tool that allows you to create complex vector based drawings and then connect them directly to a systems of variables and scripts. Check it out, I’ll wait…

Moving a layer from Sketch into PaintCode is as easy as copy and paste.

Yes, you can just export directly from Sketch to SVG but stopping off at PaintCode creates a much tighter, less assumptive, and more programmatically addressable SVG image AND you can layer on more complex interactions before moving it into your app. I did not layer on more complex interactions in this example. So, in the spirit of transparency, PaintCode is an optional step here, your mileage may vary.

The EQ graph layer copied from Sketch and pasted to PaintCode

From here you can do some amazing things if you are so inclined including named animations, named colors, color transitions etc. It is flexible and deep but I am not, so for my use case I just exported this object as an SVG and imported it into my Angular-CLI app. You could have exported it as a Javascript function as well but that is super verbose and doesn’t feel very Angular-ish.

This SVG code was auto-generated by PaintCode by selecting Web-SVG in the panel tab

Step 3: Create an Angular Component

Every widget needs its own component so using the sweetness that is angular-cli I generated one:

Using Angular-cli creates 14.8% happier developers

Now there is a nice and clean home for my new HealthBar component that is waiting to be told what to do. Lets tell it.

Step 4: Embed the SVG

There are probably much better ways to do this but the quickest way I found to just paste the SVG object into my components html file. This has the added benefit of allowing you to dynamically name individual attributes for direct access in Step 5. This is particularly important if you want to have multiple instances of the widget on a single page.

Directly embed SVG with dynamically named id attributes — {{routerId}} .

Step 5: SVG.js

SVG.js is one of the most full featured javascript libraries for manipulating svg images and will fit directly into Angular using npm. The import directive is simple:

import * as SVG from ‘svg.js’;

Now we we can use SVG.js (via SVG) and directly interact with the svg image that we embedded into the view. SVG.js is simple to understand and lets you use simple DOM style selectors to extract individual paths from the image and act on them. In this case we are polling a REST endpoint and asking for a specific routers current health metric. We do some minor calculations on it and then adjust the opacity of individual bars every few seconds.

The emojis are not part of my SVG but fun anyhow.

The code to do this is simple and gives you a small glimpse into what Sketch, PaintCode/SVG and Angular can do together.

A very Java-ish looking Angular component to illustrate the concept
Relevant service code that uses an interval to return the data to the component

Basically this component polls a service, converts the 1–100 Health # to a level that is then used to break the HealthBar into lit segments, yielding the animation above. Since Angular is using an observable the graph updates on each poll interval automatically. If you take a look at line 35->43 you can see how easy it would be to make each of these bars do anything you might want them to and SVG.js gives you many more options then just setting attributes which I haven’t had the need to explore just yet.

Result

With <20 lines of SVG manipulation code (a real developer could probably do it in <10, maps anyone?) we’ve been able to create a real-time, dynamic web based widget that exactly mirrors its iOS counter-part, uses the same assets pipeline as our design and mobile teams and can be re-purposed anywhere else in the app as long as you can feed it a number from 1–100.

All in all this took about 2 hours start of thinking to sending out for testing and we ended-up with a pixel perfect implementation that not only mirrors the mobile app visually but also programmatically. You can actually watch the iOS app and the web app HealthBars change in unison which is an incredibly satisfying way to end the day.

--

--