GSAP + SVG for Power Users: Motion Along A Path
Complete Series
Now that the GreenSock API is picking up steam, there are many tutorials and Getting Started guides out there to provide good introductions to the library, not to mention GreenSock's own Forum and Documentation. This article isn't intended for beginners, but rather a deeper dive into some of the more exciting and lesser-known features that one can work with after they've gotten past the initial introduction. As SVG is scalable, crisp, and easy to make responsive (more on this in subsequent articles), everything shown will be about SVG in specific, however, you can still use GSAP for Canvas as well.
Please keep in mind that they don't pay me to write for them- this isn't a marketing article. The library is a tool I find extremely useful. I personally have been using it heavily since I benchmarked performance for SVG animation in both timeline recordings and through visual benchmarks and found that it performed as well as many native technologies. (Note: please keep in mind that these tests were run in January 2015 with a certain version of each library, and a certain version of Chrome. I encourage you to run tests for yourself with your own use-cases.)
There are a plethora of interesting features to play around with in the GreenSock API. This is the first in a series of articles. We'll begin with focus on their Bezier Plugin. This plugin is included within TweenMax, if you are using TweenLite you will have to load it separately.
Motion Along a Path
Motion along a path is truly vital for realistic movement in animation. Interpolating single values in x, y, and z directions will only get you so far. Consider the movement of a firefly in a jar. Living beings rarely sail along in a linear fashion. Currently, motion along a path is not supported in CSS (though it is coming down the pipeline, and you can vote to support its implementation in Microsoft Edge). SMIL offers motion along a path, but no SMIL support is offered in IE, nor does it look to be supported in the upcoming Edge browser. GreenSock offers a stable way to create such an effect with the BezierPlugin, included in TweenMax, providing support in even IE8 unlike native technologies. Thus, it's currently the most fully-supported and backwards-compatible way to work with motion along a path.
In order to create a motion along a path, pass an array of x, y
coordinates as values into the bezier definition. The coordinates refer to points relative to the element's position, not the canvas itself. In other words, if you specify x:5, y:10
, the motion will be defined from 5
to the right and 10
down from where the element is currently. Subsequent points are still defined by the element's initial position, not the last coordinate. This makes plotting points in an area much easier to map around the element. In the case of these particular fireflies, I tweaked the path to stay within the bounds of the lightbulb, and also look slightly jumpy- as realistic movement of bugs tends to hop around a bit:
TweenMax.to($firefly1, 6, { bezier: { type: "soft", values:[{x:10, y:30}, {x:-30, y:20}, {x:-40, y:10}, {x:30, y:20}, {x:10, y:30}], autoRotate: true }, ease: Linear.easeNone, repeat: -1 }, "start+=3");
See the Pen Steampunk Lighting by Sarah Drasner (@sdras) on CodePen.
Let's say you aren't animating fireflies. Perhaps you'd like to use the paths as general coordinates, but want the motion between them to be smooth and refined. There are two ways of achieving this. The first is to set the type
parameter to soft-
this will take the paths you feed it and curve towards these points as if being pulled in the direction towards them, rather than interpolating values to one set and then the next. The other, more nuanced way that offers more control is to set the type to thru (this is the default), and define a curviness
value. 0
defines no curviness, 1
is normal, 2
is twice as curvy, and so on- this pen shows the effects of each setting:
See the Pen Demo for Curviness in GreenSock Bezier by Sarah Drasner (@sdras) on CodePen.
Note that past a value of 3, the curviness begins to look less smooth overall, because each point is beginning to loop around its own axis.
In addition to thru and soft, we have 2 other specifications for bezier types: quadratic
, and cubic
. Quadratic allows you to define a control point between each anchor. This means you can define one control point (but only one) in between your coordinates. Cubic is similar, but you can specify two control points. For both quadratic and cubic, you must begin and end the array with an anchor, though you can use as many iterations as you like.
For now, you pass an array of coordinates, though I wouldn't be surprised if in the future, GSAP added the ability to use an SVG path itself as the definition for the movement. This library consistently adds new features, and you can watch their repository for updates, and see what's been added in the past year.
In the earlier pen, I'm simply using autoRotate: true
, so that I can have the fireflies spin on their own axis that correlates to the direction of the line while they travel through the array. You can be more specific by setting autoRotate to an integer rather than a boolean to set the initial degree of the element before it begins spinning. You may also pass an array, to adjust these options:
- Position property 1 (typically "x")
- Position property 2 (typically "y")
- Rotational property (typically "rotation", but can also be "rotationX" or "rotationY")
- Number of degrees (or radians/Math.PI) to add to the new rotation at the onset (this is optional)
- Boolean value indicating whether or not the rotational property should be defined in radians rather than degrees (default is false which results in degrees)
Setting the array to autoRotate: ["x","y","rotation",0,false]
is the same thing as autoRotate:true, as I have in the pen below, and the element will follow the rotation trajectory of the path it's following. I've provided a toggle for autoRotate:true and false, so that you can see precisely the effect this parameter has on the animation:
See the Pen Demo for autoRotate true/false by Sarah Drasner (@sdras) on CodePen.
The little character looks much more alive that way than if he had statically been set to any degree angle during the course of the tween. You can also see that I set his initial rotation to face down towards the direction he'd be autoRotating to- that's because if I hadn't, there would have been a little "jump" as he tried to right himself along the correct origin and axis. I could have also passed that in as an option in autoRotate as specified above, either way works.
Motion along a path does not just refer only to character animation, of course. When paired with other types of opacity and transform animations, there are endless possibilities for expressive yet fine-tuned control over animations.
This is part one of a several-part series. As we move forward learning each of these techniques, we'll begin tying different ways of working together to create increasingly more complex and engaging work. Stay tuned!
About Sarah Drasner
Sarah Drasner is currently a Senior UX Engineer at Trulia (Zillow Group) in San Francisco. She spends most of her time thinking about engaging user interfaces, animation, and how to weld together pieces of the DOM. You can find her on Codepen as sdras, on Twitter as @sarah_edo, or at sarahdrasnerdesign.com.
Good Read Sarah. The animations you have created are really impressive. It’s amazing how far web technologies have come today that we now have flash-free, smooth animation using css/javascript.
Thanks, Logo! There are some really incredible things we can do, and it’s getting better all the time :)
Hi Sarah,
In regards to your little guy animation example above, I wonder how can we replicate an effect of a dotted line or a line follow him while he’s moving?
Cheers,