In web development I sometimes get an itch to learn something new. Just a tick that encourages me to push my knowledge a bit more. The possibilities are endless and sometimes I just feel like exploring them for the sake of learning something. And this week I got the itch to teach myself some SVG animations.

SVG’s are Scalable Vector Graphics printed through a browser through a SVG code generated by programs like Adobe Illustrator or Inkscape paths. Being extremely familiar with illustrator and having no experience with Inkscape naturally I downloaded the new program, stared at it for 5 minutes and decided to return to my adobe safety zone. Nestled securely in my wheelhouse I created my illustration, making sure that all my polyfills and circles were converted to compound paths.

My company had a release of it’s new battery case for the iPhone 6, obviously a pretty big product to launch. Early in my research I’d stumbled upon this link, I was inspired by it’s application to tech: how well it described the concept of product design and engineering as process. Naturally I downloaded the git and played around with the code they’d provided. After a half-hour of finagling I realized I’d never be able to use a plugin for this technology, I’d be letting myself and my craft down and decided it was back to the grind and the hand-code method to make this happen.

So I started with some basic code to animate the SVG. I’ve always found Chris Coyier over at CSS Tricks to be a reliable source of information and his article How SVG Line Animation Works was incredibly helpful just to wrap my head around the concept. Once I understood the process behind it I was able to incorporate a simple SVG animation using jquery/javascript to manipulate the css on my path and run the animation.

function drawSVGPaths(_parentElement, _timeMin, _timeMax, _timeDelay) { var paths = $(_parentElement).find('path'); $.each( paths, function(i) { //get the total length var totalLength = this.getTotalLength(); //set PATHs to invisible $(this).css({ 'stroke-dashoffset': totalLength, 'stroke-dasharray': totalLength + ' ' + totalLength }); //animate $(this).delay(_timeDelay*i).animate({ 'stroke-dashoffset': 0 }, { duration: Math.floor(Math.random() * _timeMax) + _timeMin ,easing: 'easeInOutQuad' }); }); } function startSVGAnimation(parentElement) { drawSVGPaths(parentElement, 2000, 3000, 50); }

As you can see I’m selecting all ‘path’ elements in my _parentElement, assigning their length to a variable, then animating them over a random time interval with some clever math (I pulled the clever math from another source that I can’t seem to find, if found please let me know and I’ll link it!). This of course just ran the animation. I needed the animation to start only once the element was scrolled in to the viewport.

After a few more hours of research I found myself with the following code.

function isScrolledIntoView(elem) { var docViewTop = $(window).scrollTop(); var docViewBottom = docViewTop + $(window).height(); var elemTop = $(elem).offset().top; var elemBottom = elemTop + $(elem).height(); return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop)); } $(window).scroll(function() { if (isScrolledIntoView('#svg-container')) { startSVGAnimation($('#route')); } });

This allowed me to trigger my animation once the element was scrolled into view. Solid! I started my CSS styling and jovially patted myself on the back for solving the puzzle all by my google! Until I loaded the page and realized the animation was repeating itself each time the page was scrolled, and as I scroll just a little very frequently the animation looked like it was stuttering. Obviously not my intention. Back to the code board!

I’m gonna admit this took me a lot longer to figure out than I’d like to say. I finally had to ask a developer friend to help me and the code he wrote is so annoyingly simple I wanted to punch myself for not figuring it out.

var hasExecuted = false; $(window).scroll(function() { if (!hasExecuted && isScrolledIntoView('#svg-container')) { startSVGAnimation($('#route')); hasExecuted = true; } });

Excuse me while I rage kick myself in the face, even looking at how simple the solution was, just sitting out of my reach still gets my blood boiling. But once I had this part refined I was able to move forward and work on fading in the actual product image on top of my SVG illustration once it was completed.

function drawSVGPaths(_parentElement, _timeMin, _timeMax, _timeDelay) { var paths = $(_parentElement).find('path'); $.each( paths, function(i) { //get the total length var totalLength = this.getTotalLength(); //set PATHs to invisible $(this).css({ 'stroke-dashoffset': totalLength, 'stroke-dasharray': totalLength + ' ' + totalLength }); //animate $(this).delay(_timeDelay*i).animate({ 'stroke-dashoffset': 0 }, { duration: Math.floor(Math.random() * _timeMax) + _timeMin ,easing: 'easeInOutQuad' }); }); var finalImg = $(_parentElement).next('img'); var imgTime = _timeMin + _timeMax + _timeDelay; setTimeout(function() { finalImg.animate({opacity: 1.0}) }, imgTime); }

My final drawSVGPaths function selected the image directly after the parent element and animated it’s opacity from 0 to 1 over the time interval defined for the animation itself. I wanted to make sure I could reuse this function on later projects, blood, sweat, and tears were going into this project I better be able to use it afterwards.

With a document.ready function to hide the paths on page load I was ready to deploy! I put this effect into use on the product page for the iPhone 6 Spare and have to say I’m pretty proud of it. I stuck through the difficulties and persevered through the frustrations. With google at my side, I can achieve anything! But mostly cool SVG animations.

Result

Final Code