Creating a seamless SVG line loop animation with DrawSVG
Have you ever wanted to draw part of a stroke from nothing and then have that line segment loop around your SVG element endlessly? It can be a bit tricky, but with a duplicate ‘helper’ stroke, we can make it happen.
I’m going to be using GreenSock’s animation platform for this process. Specifically, TweenMax and DrawSVG. Yes, you can make the calculations on your own, but this plugin deals with several browser inconsistencies that would normally drive you crazy.
Full disclosure: I am a huge fan of GreenSock and highly recommend GSAP and all the incredible plugins to anyone looking to save time in their work. I do volunteer some time over there as a forum moderator.
In this first demo, you can see a stroke draw from 0 to 50% of its length and then start animating around the circle. Once the leading edge of the stroke has made a full revolution, the remaining line animates to the end and the whole thing starts over. That’s nice, but not exactly what we want.
Side note: I’m using the new GSDevTools in this demo. For more info on this latest addition to the GreenSock library, check out the GSDevTool Docs.
Let's add a helper
In this next demo, we can see a little difference in the single stroke animation vs the previous demo. It animates to 25% of its length and when the leading edge hits the full revolution, it snaps to the beginning of the timeline and starts over. This is also not what we want. However, in the second version with a duplicate helper stroke, we get the exact effect we’re looking for with seamless loops.
To create your helper duplicate, it's just a simple matter of copying and pasting the stroke you want to animate. Then give each one a class. I usually just use 'master' and 'helper'.
Looking under the hood
So, what exactly is happening here? Let’s take a look. Here’s a demo that shows three versions (master only, helper only & combo). I’ve made the helper stroke orange so you can better see what it’s doing. I‘ve also added a slight pause when the helper starts and ends to better illustrate everything.
The master shows what’s happening with the original stroke. It draws to 25% and when it gets around to a full revolution, the tail end draws down to nothing. That’s just like the first demo in this post. But that stroke can’t be in two places at once so we use a duplicate helper. That helper draws to 25% while the original is drawing the tail end to nothing. Once that happens, we set the original immediately to 25% and the helper back to 0. They effectively trade places. Now the helper is ready to draw to 25% again for all subsequent loops. We then restart the timeline, but not from the beginning. We don't need the initial draw from 0% to 25% so we restart just past that point by using a label.
Getting the timing right
We have our master animation drawing to the end while the helper is starting so how is that calculated? With a couple variables, we can calculate everything we need.
const sp = 25; // line percentage to show (1-99); const duration = 4; // change the duration; const overlapDuration = sp/100 * duration; // allocate the proper percentage of the duration to the overlap const mainDuration = duration - overlapDuration; // remainder of duration for main animation TweenLite.defaultEase = Linear.easeNone; // needed for seamless loops
For the examples above, we are showing 25% of the line (sp) and the duration is 4 seconds. So, we want the initial draw from 0% to 25% (and helper overlap draw) to take up 25% of the duration. In this case, 1 second (sp/100 * duration). We then subtract that from the total duration to find out how long that new segment takes to get around to a full revolution (mainDuration = duration - overlapDuration). Those values are then used for our tweens. You'll also notice there is no ease in or out. It has to be Linear in order to create the illusion of a seamless loop.
I won't list all the actual tweens here, but please feel free to dive into the JS further to see how everything is plugged into the DrawSVG tweens on the timeline.
All the complexity you need
The demos above used simple circles, but you can use any SVG element with a stroke. You can also use multiple strokes on the same element. Here's an example of circuits running around parts of a logo. Notice how one set of lines runs parallel while the other set runs in opposite directions.
Here’s an interactive example allowing you to play with the duration, line percentage, stroke-width and color.
The DrawSVG plugin is a premium plugin as part of Club GreenSock, but you can test it or any of the bonus plugins for free on CodePen. See this GreenSock demo for the links.
I hope you found some of this useful. See ya next time.