_:nb32a9d8319934cc4bc368026352b21bdxb0
<http://schema.org/articleBody>
"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).\n \n\n\n\tHowever, 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.\n \n\n\n\tDon'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 we cover some of the things that GSAP does for you and then we have a list of other things to watch out for. This page is intended to be a go-to resource for anyone animating SVG with GSAP. \n \n\n\n\tOutline\n \n\n\n\n\t\tChallenges that GSAP solves for you\n\n\t\t\n\n\t\t\t\tScale, rotate, skew, and move using 2D transforms\n\t\t\t \n\t\t\t\n\t\t\t\tSet the transformOrigin (the point around which rotation and scaling occur)\n\t\t\t \n\t\t\t\n\t\t\t\tSet transformOrigin without unsightly jumps\n\t\t\t \n\t\t\t\n\t\t\t\tTransform SVG elements around any point in the SVG canvas\n\t\t\t \n\t\t\t\n\t\t\t\tAnimate SVG attributes like cx, cy, radius, width, etc.\n\t\t\t \n\t\t\t\n\t\t\t\tUse percentage-based x/y transforms\n\t\t\t \n\t\t\t\n\t\t\t\tDrag SVG elements (with accurate bounds and hit-testing)\n\t\t\t \n\t\t\t\n\t\t\t\tMove anything (DOM, SVG) along a path including autorotation, offset, looping, and more\n\t\t\t \n\t\t\t\n\t\t\t\tAnimate SVG strokes\n\t\t\t \n\t\t\t\n\t\t\t\tMorph SVG paths with differing numbers of points\n\t\t\t \n\t\t\n \n\t\n\t\tTips to Avoid Common Gotchas\n\t \n\t\n\t\tLimitations of SVG\n\t \n\t\n\t\tBrowser support\n\t \n\t\n\t\tInspiration\n\t \n\t\n\t\tAwesome SVG Resources\n\t \n\t\n\t\tGet Started Quickly with GSAP\n\t \n\n\n\tChallenges that GSAP solves for you\n \n\n\n\tGSAP does the best that it can to normalize browser issues and provide useful tools to make animate SVG as easy as it can be. Here are some of the challenges that using GSAP to animate SVG solves for you:\n \n\n\n\tScale, rotate, skew, and move using 2D transforms\n \n\n\n\tWhen using GSAP, 2D transforms on SVG content work exactly like they do on any other DOM element.\n \n\n\ngsap.to(\"#gear\", {duration: 1, x: 100, y: 100, scale: 0.5, rotation: 180, skewX: 45});\n\n\n\tSince IE and Opera don't honor CSS transforms at all, GSAP applies these values via the SVG transform attribute like:\n \n\n\n&lt;g id=\"gear\" transform=\"matrix(0.5, 0, 0, 0.5, 100, 0)\"&gt;...&lt;/g&gt;\n\n\n\tWhen it comes to animating or even setting 2D transforms in IE, CSS simply is not an option.\n \n\n\n#gear {\n  /* won't work in IE */\n  transform: translateX(100px) scale(0.5);\n}\n\n\n\tVery few JavaScript libraries take this into account, but GSAP handles this for you behind the scenes so you can get amazing results in IE with no extra hassles.\n \n\n\n\tSet the transformOrigin (the point around which rotation and scaling occur)\n \n\n\n\tAnother unique GSAP feature: use the same syntax you would with normal DOM elements and get the same behavior. For example, to rotate an SVG &lt;rect&gt; that is 100px tall by 100px wide around its center you can do any of the following:\n \n\n\ngsap.to(\"rect\", {duration: 1, rotation: 360, transformOrigin: \"50% 50%\"}); //percents\ngsap.to(\"rect\", {duration: 1, rotation: 360, transformOrigin: \"center center\"}); //keywords\ngsap.to(\"rect\", {duration: 1, rotation: 360, transformOrigin: \"50px 50px\"}); //pixels\n\n\n\tThe 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.\n \n\n\n\t\n\t\t\n\t\n\n\n\tAccording to the SVG spec, the transform origin of an element is relative to its parent SVG canvas. So if you want to rotate an SVG child element around its own center, you need to manually plot that point in relation to the top-left corner of the SVG canvas. This can be rather cumbersome with multiple elements or if you ever change the position of the element. In contrast, a DOM element's transform-origin is relative to its own top left corner. Most developers expect (and most likely appreciate) the behavior they are accustomed to in the DOM – transform-origin is relative to the element itself.\n \n\n\n\tAmong other transform-origin related browser bugs (like zooming in Safari) we also found that Firefox doesn't honor percentages or keyword-based values. To learn the technical details of how GSAP fixes these transformOrigin issues behind the scenes, check out this CSS-Tricks article.\n \n\n\n\tSet transformOrigin without unsightly jumps\n \n\n\n\tYou 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.\n \n\n\n\tWith 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.\n \n\n\n\t\n\n\n\n\tStudy the demo below and scrub slowly.\n \n\n\n\t\n\t\t\n\t\n\n\n\tWhen changing the transformOrigin (or svgOrigin) of an SVG element, CSSPlugin will automatically record/apply some offsets to ensure that the element doesn't \"jump\". You can disable this by setting CSSPlugin.defaultSmoothOrigin = false, or you can control it on a per-tween basis using smoothOrigin:true | false. smoothOrigin only applies to SVG elements. \n \n\n\n\tTransform SVG elements around any point in the SVG canvas\n \n\n\n\tSometimes 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.\n \n\n\n//rotate svgElement as though its origin is at x:250, y:100 in the SVG canvas's global coordinates.\ngsap.to(svgElement, {duration: 1, rotation: 270, svgOrigin: \"250 100\"}); \n\n\n\tThe demo below shows how transformOrigin and svgOrigin compare.\n \n\n\n\t\n\t\t\n\t\n\n\n\tFor the majority of use cases where setting a point of origin is necessary, transformOrigin is ideal, as it delivers behavior consistent with normal DOM elements in all major browsers. No headaches. However, there will be times when svgOrigin will come in handy too. Sara Soueidan used this feature in her excellent Circulus tool demo. svgOrigin only supports px-based values (no percentages).\n \n\n\n\tAnimate SVG attributes like cx, cy, radius, width, etc.\n \n\n\n\tCSSPlugin handles pretty much any CSS properties like fill, stroke, strokeWeight, fillOpacity, etc. but to animate attributes you can use the built in AttrPlugin which handles any numeric attribute. For example, let's say your SVG element looks like this:\n \n\n\n&lt;rect id=\"rect\" fill=\"none\" x=\"0\" y=\"0\" width=\"500\" height=\"400\"&gt;&lt;/rect&gt;\n\n\n\tYou could tween the \"x\", \"y\", \"width\", or \"height\" attributes using AttrPlugin like this:\n \n\n\ngsap.to(\"#rect\", {duration: 1, attr: {x: 100, y: 50, width: 100, height: 100}, ease: \"none\"});\n\n\n\tCheck out the JS tab in the demo below to see the syntax used.\n \n\n\n\t\n\t\t\n\t\n\n\n\tIf you want to specify a particular unit (px or percentages) in your AttrPlugin tween it is important that the element already use the same units. AttrPlugin doesn't do unit conversion (like between % and px).\n \n\n\n//Given the following element with percentage-based position:\n&lt;rect id=\"rectangle\" x=\"0%\" y=\"0%\" class=\"element\" width=\"200\" height=\"100\"/&gt;\n\n//The following tween would put the top left corner of the  exactly in the center of its parent's coordinate space.\ngsap.to(\"#rectangle\", {duration: 1, attr: {x: \"50%\", y: \"50%\"});\n\n\n\tBy combining percentage-based positional attributes and percentage-based transforms you could center the &lt;rect&gt; in its parent like so:\n \n\n\ngsap.to(\"#rectangle\", {duration: 1, attr: {x: \"50%\", y: \"50%\"}, x: \"-50%\", y: \"-50%\"})\n\n\n\tSee the demo.\n \n\n\n\tUse percentage-based x/y transforms\n \n\n\n\tAnother \"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 the JS tab).\n \n\n\n\t\n\t\t\n\t\n\n\n\tTo make this happen GSAP converts the percentage values you provide to pixel values. There is one important caveat: the value are not “live” like normal percentage-based CSS transforms are. GSAP has to do the math to bake the pixel values into the matrix(), thus if you change the element’s width or height AFTER you apply a GSAP percentage-based transform, the translation won’t be adjusted.\n \n\n\n\tDrag SVG elements (with accurate bounds and hit-testing)\n \n\n\n\tThere 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 InertiaPlugin). Impressive fact: It even works inside nested transformed elements. Each interactive element below is a &lt;g&gt; contained in a single SVG canvas.\n \n\n\n\t\n\t\t\n\t\n\n\n\tMove anything (DOM, SVG) along a path including autorotation, offset, looping, and more\n \n\n\n\tGSAP's MotionPathPlugin makes it a breeze to animate DOM or SVG elements along a path. It has a lot of features like autorotation, offset, and looping in additional to very useful helper functions for converting between coordinate systems.\n \n\n\n\t\n\t\t\n\t\n\n\n\tAnimate SVG strokes\n \n\n\n\tDrawSVGPlugin allows you to progressively reveal (or hide) the stroke of an SVG &lt;path&gt;, &lt;line&gt;, &lt;polyline&gt;, &lt;polygon&gt;, &lt;rect&gt;, or &lt;ellipse&gt;. It does this by controlling the stroke-dashoffset and stroke-dasharray CSS properties. You can even animate the stroke in both directions.\n \n\n\n\t\n\t\t\n\t\n\n\n\tUnlike most \"pure CSS\" solutions that only allow you to animate what percentage of a stroke is visible, DrawSVGPlugin allows you to animate both the starting and ending positions of the stroke segment that is being animated. This allows you to make more advanced animations:\n \n\n\n\t\n\n\t\t\tIncrease/reveal stroke segment from beginning, end, center or any position.\n\t\t \n\t\t\n\t\t\tDecrease/hide stroke segment to beginning, end, center or any position.\n\t\t \n\t\t\n\t\t\tMove a segment of a stroke along a path for that snake in a maze effect.\n\t\t \n\t\n\n\n\n\t\n\t\t\n\t\n\n\n\tDrawSVGPlugin is a bonus plugin for Club GreenSock members. \n \n\n\n\tMorph SVG paths with differing numbers of points\n \n\n\n\tMorphSVGPlugin provides advanced control over tweens that morph SVG paths.\n \n\n\n\t\n\t\t\n\t\n\n\n\t\n\t\tWith MorphSVG, you can\n\t \n\n\t\n\n\t\t\tMorph &lt;path&gt; data even if the number (and type) of points is completely different between the start and end shapes! Most other SVG shape morphing tools require that the number of points matches.\n\t\t \n\t\t\n\t\t\tMorph a &lt;polyline&gt; or &lt;polygon&gt; to a different set of points\n\t\t \n\t\t\n\t\t\tConvert and replace non-path SVG elements (like &lt;circle&gt;, &lt;rect&gt;, &lt;ellipse&gt;, &lt;polygon&gt;, &lt;polyline&gt;, and &lt;line&gt;) into identical &lt;path&gt;s using MorphSVGPlugin.convertToPath().\n\t\t \n\t\t\n\t\t\tOptionally define a \"shapeIndex\" that controls how the points get mapped. This affects what the in-between state looks like during animation.\n\t\t \n\t\t\n\t\t\tSimply feed in selector text or an element (instead of passing in raw path data) and the plugin will grab the data it needs from there, making workflow easier.\n\t\t \n\t\n\n\n\n\tMorphSVGPlugin is a bonus plugin for Club GreenSock members (Shockingly Green and Business Green).\n \n\n\n\tTips to Avoid Common Gotchas\n \n\n\n\tThere are some things that GSAP can't solve for you. But hopefully this part of the article can help prepare you to avoid them ahead of time! Here are some things to keep in mind when creating and animating SVGs.\n \n\n\n\tVector editor/SVG creation tips:\n \n\n\n\n\t\tWhen creating an SVG in Illustrator or Inkscape, create a rectangle the same size as your artboard for when you copy elements out of your vector editor and paste them into a code editor (how-to here).\n\t \n\t\n\t\tHow to quickly reverse the direction of a path in Illustrator (Note: If the Path Direction buttons are not visible in the attributes panel, click the upper right menu of that panel and choose 'Show All'): \n\t\t\n\n\t\t\t\tOpen path: Select the pen tool and click on the first point of your path and it will reverse the points.\n\t\t\t \n\t\t\t\n\t\t\t\tClosed path: Right click the path and make it a compound path, choose menu-window-attributes and then use the Reverse Path Direction buttons.\n\t\t\t \n\t\t\n \n\t\n\t\tIf you're morphing between elements it might be useful to add extra points yourself to simpler shapes where necessary so that MorphSVG doesn't have to guess at where to add points.\n\t \n\t\n\t\tYou can think of masks as clip-paths that allow for alpha as well. \n\t \n\t\n\t\tWhen using masks, it's often important to specify which units to use.\n\t \n\t\n\t\tUse a tool like SVGOMG (or this simpler tool) to minify your SVGs before using them in your projects.\n\t \n\n\n\tCode/animation-related tips:\n \n\n\n\n\t\tAlways set transforms of elements with GSAP (not just CSS). There are quite a few browser bugs related to getting transform values of elements which GSAP can't fix or work around so you should always set the transform of elements with GSAP if you're going to animate that element with GSAP.\n\t \n\t\n\t\tAlways use relative values when animating an SVG element. Using something like y: \"+=100\" allows you to change the SVG points while keeping the same animation effect as hard coding those values.\n\t \n\t\n\t\tYou can fix some rendering issues (especially in Chrome) by adding a very slight rotation to your tween(s) like rotation: 0.01.\n\t \n\t\n\t\tIf you're having performance issues with your issue, usually the issue is that you have too many elements or are using filters/masks too much. For more information, see this post focused on performance with SVGs. \n\t \n\t\n\t\tYou might like injecting SVGs into your HTML instead of keeping it there directly. You can do this by using a tool like Gulp.\n\t \n\t\n\t\tYou can easily convert between coordinate systems by using MotionPathPlugin's helper functions like .convertCoordinates().\n\t \n\n\n\tTechnique tips/resources:\n \n\n\n\n\t\tYou can animate the viewBox attribute (demo)!\n\t \n\t\n\t\tYou can animate (draw) a dashed line by following the technique outlined in this post.\n\t \n\t\n\t\tYou can animate (draw) lines with varied widths by following the technique outlined in this post.\n\t \n\t\n\t\tYou can animate (draw) handwriting effects by following the technique outlined in this post.\n\t \n\t\n\t\tYou can create dynamic SVG elements!\n\t \n\t\n\t\tYou can animate (draw) a \"3D\" SVG path.\n\t \n\t\n\t\tYou can fake nested SVG elements (which will be available in SVG 2) by positioning the inner SVG with GSAP and scaling it (demo).\n\t \n\t\n\t\tYou can fake 3D transforms (which will be available in SVG 2) in some cases by either\n\t\t\n\n\t\t\t\tFaking the transform that you need. For example sometimes rotationYs can be replaced by a scaleX instead.\n\t\t\t \n\t\t\t\n\t\t\t\tApplying the transform to a container instead. If you can limit the elements within the SVG to just the ones you want to transform, this is a great approach. For example, applying a rotationY to the &lt;svg&gt; or &lt;div&gt; containing a &lt;path&gt; instead of applying it to the &lt;path&gt; itself. \n\t\t\t \n\t\t\n \n\n\n\tLimitations of SVG\n \n\n\n\n\t\tThe current SVG spec does not account for 3D transforms. Browser support is varied. Best to test thoroughly and have fallbacks in place.\n\t \n\t\n\t\tMost browsers don't GPU-accelerate SVG elements. GSAP can't change that.\n\t \n\n\n\tBrowser support\n \n\n\n\tAll SVG features in this article will work in IE9+ 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.\n \n\n\n\tInspiration\n \n\n\n\t \n\tThe Chris Gannon GSAP Animation collection is great for seeing more SVG animations made with GSAP. Be sure to also check out Chris Gannon's full portfolio on CodePen and follow him on Twitter for a steady influx of inspiration.\n \n\n\n\tAwesome SVG Resources\n \n\n\n\n\t\tSVG Tutorials - MotionTricks\n\t \n\t\n\t\tThe SVG Animation Masterclass - Cassie Evans\n\t \n\t\n\t\tUnderstanding SVG Coordinate Systems and Transformations - Sara Soueidan\n\t \n\t\n\t\tImproving SVG Runtime Performance - Taylor Hunt\n\t \n\t\n\t\tSVG tips - Louis Hoebregts\n\t \n\t\n\t\tA Compendium of SVG Information - Chris Coyier\n\t \n\t\n\t\tMaking SVGs Responsive with CSS - Sara Soueidan\n\t \n\t\n\t\tviewBox newsletter (SVG focus) - Cassie Evans and Louis Hoebregts\n\t \n\n\n\tGet Started Quickly with GSAP\n \n\n\n\tBelow are a few resources that will get you up and running in no time:\n \n\n\n\n\t\tGetting Started Guide with Video\n\t \n\t\n\t\tSequence Animations like a Pro (video)\n\t \n\t\n\t\tGSAP Documentation\n\t \n\n"
<https://greensock.com/svg-tips>