The Process Behind Our End of Year Report

Last week we finished Maxwell Health’s End of Year Report for 2015. Since this project represents our journey from a 63-person startup to a 160-person game-changer over the course of last year, we wanted to capture the sense of scale that came with growing so quickly. We challenged ourselves to step away from a single-page product site or the standard PDF annual report downloads.

We ultimately decided that illustrating and animating a representation of our move from our old headquarters on 131 Tremont Street to 101 Tremont Street would be the best approach, and ended up with a lopsided-T shape that would allow for the concurrent horizontal and vertical movement down the page. The main problem with horizontal movement, however, is that scrolling sideways is usually a UX no-no (especially if you navigate using Mac’s magic mouse interactions). We solved this by tying vertical scroll movement with 2D transforms to move the entirety of our Illustration canvas as the page moved downwards.

3D view of our finalized project

What We Learned

Over the course of designing and building this project we learned a considerable amount about Scalable Vector Graphics (SVG), SVG limitations, and got a better grasp at why SVG is the future of the web. Here are some quick techniques that we applied to make this project lighter and more feasible within a tight timeframe:

Reduce HTTP Requests with SVG images

Early on in our process we decided to forego the usual PNG export path that many similar projects take, and experiment with SVGs. We quickly realized that the biggest benefit of vector graphics is its roots in XML and the ability to include them directly in our markup. This meant that the entirety of our base code (besides our content images) would be within our DOM.

Unfortunately, this also left us with painfully unreadable code, so we used PHP to keep our working code clean and minimal:

<?php echo file_get_contents(“img/star.svg”); ?>

Having the SVG in our markup also meant that we could directly target it with CSS & Javascript, which leads to the next step:

Dynamic Manipulation of Graphics

A big part of our project was manipulating specific parts of our graphics without changing the entire image (i.e.: window lighting colors, streetlights turning on/off, etc). Since we wanted to move quickly, incorporating a library we had never used before (like the awesome Snap.svg) wasn’t an ideal option. Thankfully, JQuery’s 3.0 Alpha was recently made available and came bundled with direct SVG support, making our lives much easier by being able to target SVGs directly:

$(‘cloudsLeft’).css(‘animation’,’flyleft 1s’)

Thus, allowing us to switch between different animations on the same object without spaghetti code getting in the way.

Universal Stylesheets for SVGs

Another (completely optional) way to clean up your code is to load all the internal styles of your SVG files in an external stylesheet rather than in your DOM (these can be found if you open your SVG file with a text editor and copy the content between the <style> tags). Note that this only works if your markup contains the SVG code, as stated above. If you remove the syling then try to load the graphics via <img> or CSS backgrounds you will not be able to manipulate the CSS and will end up with large black blobs.

:(

Once the SVG’s internal styling was copied to the stylesheet, we added it to our _svg.scss partial and edited it to our heart’s desire. Those not using SASS or LESS can simply add the properties to their CSS file. The added benefit to this is that your SVG styles can be cached by the browser.

A typical SVG universal stylesheet

P.S . To avoid CSS conflicts between exported files, try exporting them via individual artboards in the same Illustrator document. Preemptively naming groups and layers in Illustrator can also save you quite a bit of headache.

Transitioning Gradients

One major shortcoming of CSS3 is its inability to parse gradient transitions without hacking it together. No matter how hard we tried, transitioning from one pair of RGB values to another pair in a linear gradient background led to quick flashes from one color to the next. To solve this, we added Skrollr.js, which interpolates between values based on the user’s scroll position, a perfect tool for what we needed done quickly.

The background sky as the user scrolls between sections, triggered by scroll height

While some might be wary of using multiple JS libraries, the project was finished faster (in about one month) and more elegantly than if we had reinvented the wheel. The final result was a pleasant and natural illustration of the Boston sky, the subtle variation of the star positions, the changing background buildings, and the lights in the windows.

Persistent Keyframe Animations

A small but annoying issue with keyframe animations is that when your animation is finished (or looping a set number of times), whatever object you were animating returns back to its original position. One small trick we used to keep our animated graphics in their final resting point after a keyframe animation finished was the CSS3 property animation-fill-mode:

-webkit-animation-fill-mode: forwards; /* Chrome, Safari, Opera */ animation-fill-mode: forwards;

Which can also be used in context with your animation property:

.star {
animation: fadein 2s forwards;
}

This sets the keyframe endpoint as your objects new position. Keep in mind this may affect any future animations of that object, so use only when absolutely necessary.

Horizontal and Vertical Scrolling

We achieved horizontal movement via downwards scrolling by using the Fullpage.js callbacks, which allowed us to time content changes with our CSS transform triggers:

// JAVASCRIPT
// On section change move buildings right
if(index == 6 && direction ==’down’){
$(backgroundBuildings).removeClass(‘bg-position3’).addClass(‘bg-position4’);
}
// If scrolled back up, move buildings left
else if(index == 7 && direction == ‘up’){
$(background).removeClass(‘bg-position4’).addClass(‘bg-position3’);
}

Illustrations

The illustrations in this project were based on the Google street view images of Tremont Street coupled with photographs we took on foot to capture the necessary details. Once we had those, we overlaid our artboards over satellite view of the street to make sure every building illustration was proportional. The final result was a detailed side view of Tremont Street:

The “window lighting” was a single element (colored pink) to allow for easy simultaneous editing in the code later on.

Final Result

You can see the final results of the project here: Maxwell Health 2015 End of Year Report