When it comes to animation, SVG and GSAP go together like peanut butter and jelly. Chocolate and strawberries. Bacon and...anything. SVG offers the sweet taste of tiny file size plus excellent browser support and the ability to scale graphics infinitely without degradation. They're perfect for building a rich, responsive UI (which includes animation, of course).
However, just because every major browser offers excellent support for displaying SVG graphics doesn't mean that animating them is easy or consistent. Each browser has its own quirks and implementations of the SVG spec, causing quite a few challenges for animators. For example, some browsers don't support CSS animations on SVG elements. Some don't recognize CSS transforms (rotation, scale, etc.), and implementation of transform-origin is a mess. Don't worry; GSAP smooths out the rough spots and harmonizes behavior across browsers for you. There are quite a few unique features that GSAP offers specifically for SVG animators. Below is a list of common challenges along with GSAP solutions. This page is intended to be a go-to resource for anyone animating SVG with GSAP. Before moving on, make sure you download the latest GSAP.
Challenge: scale, rotate, skew, and move using 2D transforms
No problem. 2D transforms work exactly like they do on any other DOM element.
TweenLite.to("#gear", 1, {x:100, y:100, scale:0.5, rotation:180, skewX:45});
Challenge: set the transformOrigin (the point around which rotation and scaling occur)
Another unique GSAP feature: use the same syntax you would with normal DOM elements and get the same behavior. For example, to rotate an SVG <rect>
that is 100px tall by 100px wide around its center you can do any of the following:
TweenLite.to("rect", 1, {rotation:360, transformOrigin:"50% 50%"}); //percents TweenLite.to("rect", 1, {rotation:360, transformOrigin:"center center"}); //keywords TweenLite.to("rect", 1, {rotation:360, transformOrigin:"50px 50px"}); //pixels
The demo below shows complete parity between DOM and SVG when setting transformOrigin
to various values. We encourage you to test it in all major browsers and devices.
See the Pen SVG + CSS Transform Timeline by GreenSock (@GreenSock) on CodePen.
Challenge: set transformOrigin without unsightly jumps
You can run into some unexpected (yet "according to spec") results when changing the transformOrigin
after an element has been transformed. In simple terms, once you scale or rotate an SVG element and then change its transformOrigin
, the new transformOrigin
is aligned to where it would have been according to the elements un-transformed state. This forces the element to be re-positioned and then the transforms are applied – leading to some awkward results. With smoothOrigin
enabled CSSPlugin applies some offsets so that the transformOrigin will be placed where you want without any jumps. It's a tough concept to explain with mere words so we made a nice little video for you and an interactive demo.
Study the demo below and scrub slowly.
See the Pen smoothOrigin demo by GreenSock (@GreenSock) on CodePen.
Challenge: transform SVG elements around any point in the SVG canvas
Sometimes it's useful to define the transformOrigin in the SVG's global coordinate space rather than relative to the element itself. GSAP has you covered. Our CSSPlugin recognizes a svgOrigin
special property that works exactly like transformOrigin
but it uses the SVG's global coordinate space instead of the element's local coordinate space. This can be very useful if, for example, you want to make a bunch of SVG elements rotate around a common point.
//rotate svgElement as though its origin is at x:250, y:100 in the SVG canvas's global coordinates. TweenLite.to(svgElement, 1, {rotation:270, svgOrigin:"250 100"});
The demo below shows how transformOrigin
and svgOrigin
compare.
See the Pen svgOrigin demo: SVG tips article by GreenSock (@GreenSock) on CodePen.
Challenge: animate SVG attributes like cx, cy, radius, width, etc.
CSSPlugin handles pretty much any CSS properties like fill, stroke, strokeWeight, fillOpacity, etc. but to animate attributes you can use AttrPlugin which handles any numeric attribute. For example, let's say your SVG element looks like this:
[code lang="html"]
You could tween the "x", "y", "width", or "height" attributes using AttrPlugin like this:
TweenLite.to("#rect", 1, {attr:{x:100, y:50, width:100, height:100}, ease:Linear.easeNone});
Don't forget to load the AttrPlugin (it's already included inside TweenMax). Check out the JS tab in the demo below to see the syntax used for CSSPlugin and AttrPlugin.
See the Pen SVG CSSPlugin and AttrPlugin by GreenSock (@GreenSock) on CodePen.
Challenge: use percentage-based x/y transforms
Another "gotcha" in the world of SVG is that percentage-based transforms are not accounted for in the SVG spec. When building responsive sites it can be very handy to move or simply position an element based on a percentage of its own native width or height. In the demo below four boxes of varying widths are all translated along the x-axis based on 100% of their width. No need to manually plug in unique pixel values for unique tweens of each element. All the animation runs off 1 line of code (see js tab).
See the Pen SVG Percent-based translation by GreenSock (@GreenSock) on CodePen.
Challenge: drag SVG elements (with accurate bounds and hit-testing)
There are quite a few tools out there that allow you to drag DOM elements, but few are optimized for SVG elements. With GreenSock's Draggable, you can drag and drop SVG elements, confine movement to any axis and/or within bounds, do hitTest() detection, and throw or spin them too (with ThrowPropsPlugin). Impressive fact: it even works inside nested transformed elements. Each interactive element below is a <g> contained in a single SVG canvas.
See the Pen SVG Draggable by GreenSock (@GreenSock) on CodePen.
Challenge: animate SVG strokes
DrawSVGPlugin allows you to progressively reveal (or hide) the stroke of an SVG <path>
, <line>
, <polyline>
, <polygon>
, <rect>
, or <ellipse>
. It does this by controlling the stroke-dashoffset
and stroke-dasharray
CSS properties. You can even animate the stroke in both directions.
See the Pen DrawSVGPlugin Animation by GreenSock (@GreenSock) on CodePen.
See the Pen SVG Tips: DrawSVGPlugin Values by GreenSock (@GreenSock) on CodePen.
DrawSVGPlugin is a bonus plugin for Club GreenSock members.
Challenge: morph SVG paths with differing numbers of points
MorphSVGPlugin provides advanced control over tweens that morph SVG paths.
See the Pen MorphSVG - sequence by GreenSock (@GreenSock) on CodePen.
MorphSVGPlugin is a bonus plugin for Club GreenSock members (Shockingly Green and Business Green).
Other SVG Gotchas
GSAP does a lot to remove the hurdles of animating with SVG, but there are still a few things to keep in mind:
- The current SVG spec does not account for 3D transforms. Browser support is varied. Best to test thoroughly and have fallbacks in place.
- There are quite a few browser bugs related to CSS transforms on SVG elements, some of which can interfere with GSAP's ability to animate things properly so we'd strongly recommend only using GSAP to apply transform-related properties like scale, rotation, x, y, etc.
-
In Chrome (at least as of June 2015),
getComputedStyle()
returns the WRONG transform values on SVG elements. It doesn't recognize any non-identity values. So, for example, if you apply a class to an SVG element and it hastransform: scale(0)
, Chrome will say its computed scale is 1. Doh! The same goes for any transforms - if you rotate or move or whatever in CSS, Chrome reports it as scale:1, rotation:0, translate:0, etc. So when GSAP asks the browser for the current value, it'll get bogus data. -
In Firefox, if you apply a CSS transform to an SVG element, it overrides any transform that is applied via the
transform
attribute. So if you inspect the element in Dev Tools, you'll see that GSAP is animating the values perfectly in the SVG's transform attribute, but visually you'll see no changes because the CSS class defines something liketransform: scale(0)
which takes precedence over the transform attribute. As far as we know, there's no way for GSAP to work around this, so it's best to just avoid defining transforms via CSS and use GSAP directly, likeTweenLite.set(..., {scale:2, rotation:30, ...})
- Most browsers don't GPU-accelerate SVG elements. GSAP can't change that.
- SVG is lightweight and resolution-independent, but that also can be costly when it comes to performance because rather than just shoving rasterized pixels around (which GPUs are really good at), browsers have to calculate the geometry/paths on each frame. Flash developers will remember converting vectors to bitmaps using cacheAsBitmap. In Flash Player this led to considerable performance gains. Will be interesting to see if browsers offer developers a similar option.
Browser support
All SVG features in this article will work in IE9+ (IE8 doesn't support SVG) and all other major desktop and mobile browsers unless otherwise noted. If you find any cross-browser inconsistencies please don't hesitate to let us know in our support forums.
Inspiration
The SVG Animations collection above is just a small sampling of Chris' work. Be sure to also check out Chris Gannon's full portfolio on CodePen and follow him on Twitter for a steady influx of inspiration.
Awesome SVG Resources
- A Compendium of SVG Information - Chris Coyier
- Understanding SVG Coordinate Systems and Transformations - Sara Soueidan
- Weighing SVG Animation Techniques (with Benchmarks) - Sarah Drasner
- SVG Immersion Podcast - Rob Levin
- Circulus.svg - Sara Soueidan
- Making SVGs Responsive with CSS - Sara Soueidan
- How to Scale SVG - Amelia Bellamy-Royds
- Transforms on SVG Elements - Ana Tudor
- Ways to use SVG Sprites in Animation - Sarah Drasner
Get Started Quickly with GSAP
Below are a few resources that will get you up and running in no time:
Recommended Comments
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now