Carl

SVG Gotchas!

Recommended Posts

Hey all,

 

It should be no secret that GSAP does a ton of work to get around SVG-related browser bugs and some serious heavy lifting to make working with SVG as similar to DOM/CSS as possible. We did our best to outline these strengths here: http://greensock.com/svg-tips

 

However, the workflow of designing an SVG in Illustrator (or other programs) and getting it to play nice can be a little challenging. Why is illustrator renaming my layers? Why did it put a transform on that thing? Why is this thing a path and not a polyline? And of course the SVG spec in general dictates that some things work differently than we may expect and on top of that each browser has its own special quirks. 

 

So if you have a little workflow tip that you think could help others, feel free to post them. I'll leave this post sticky for a week or two and we'll see what we get. If anyone thinks they have enough ammo for a full blog post, feel free to PM me and we can discuss.

 

I'll start by contributing this video by Chris Gannon: 

 

in which he discusses creating a rectangle the same size as your artboard for when you copy elements out of AI and paste them into an editor.

  • Like 12

Share this post


Link to post
Share on other sites

This is really great thread idea.

I especially love to see how others tackle the same issues I come across everyday. 

Chris has a few SVG posts that I found useful. The Knockout Mask one was a good one.

Looking forward to more posts guys.

 

- Patrick

Share this post


Link to post
Share on other sites

Hello Carl,

 

I agree with retropunk that this post is a great idea to find workarounds. But can I conclude from this that Adobe has responded not to solve these problems as I am sure many have requested? Greensock as well I presume. So we all have to keep repeating these corrective actions as Chris Gannon demonstrates and other workarounds?

 

Kind regards,

 

Ad

Share this post


Link to post
Share on other sites

Hi Adone, 

 

I can't really tell you what to conclude about Adobe. We haven't files any formal requests with them yet.

 

If you have particular pain points and proposed solutions perhaps you can consolidate them in a single post in this thread, however I'd really like to keep this thread focused on workflow tips.

Share this post


Link to post
Share on other sites

Hello fellow GreenSockers!

 

I thought i would add my SVG gotcha since this type of thing comes up at least one time a day regarding SVG with GSAP.

 

This is regarding animating SVG elements within an SVG <defs> tag.

  •  If you are trying to animate elements within an SVG <defs> element, then you should use the GSAP AttrPlugin.
     
  • If your SVG elements are not within a SVG <defs>, <symbol>, or <mask> element .. than you should use the GSAP CSSPlugin like your already doing! Which is the default when tweening CSS properties in GSAP.

GSAP is smart enough to know when to use what. But for attributes, wrap your attributes in the attr:{} object when using the GSAP AttrPlugin

 

If you are animating SVG elements and they are nested inside a SVG <defs> element. then you need to animate those nested graphical elements with the GSAP AttrPlugin, instead of the GSAP CSSPlugin. The reason being is that Firefox will honor the SVG spec and will follow web standards whereas webkit browsers like Google Chrome and Apple Safari will allow certain non-standards and non-spec behavior. But will later remove that non-standards and non-spec behavior to line up with the spec, further confusing users / developers.

 

SVG Graphics elements are considered the folllowing:

<circle>, <ellipse>, <image>, <line>, <path>, <polygon>, <polyline>, <rect>, <text>, <use>

 

That is why i always debug and test in Firefox first knowing the expected behavior will line up with the spec, in this case the SVG spec. And then i debug webkit (Chrome and Safari), followed by debugging IE. Doing it that way I guarantee that HTML, DOM and SVG elements will behave according to the web standards, the spec, and cross browser.

 

CSS is not directly rendered inside a SVG <defs> tag. That is why using the GSAP AttrPlugin works, since it animates the attribute values directly.

 

Taken from SVG spec on the MDN (Mozilla Developer Network) website.

 

https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs

  • <defs>
    SVG allows graphical objects to be defined for later reuse. It is recommended that, wherever possible, referenced elements be defined inside of a defs element. Defining these elements inside of a defs element promotes understandability of the SVG content and thus promotes accessibility. Graphical elements defined in a defs will not be directly rendered. You can use a <use> element to render those elements wherever you want on the viewport.

The same goes for the nested elements within an SVG <symbol> element. So as rule of thumb when animating SVG, if the element your animating is within a SVG <defs> or <symbol> element , then please use the GSAP AttrPlugin. But if it is not nested inside a <defs> or <symbol> element, then you can use GSAP as usual, knowing that it will use the CSSPlugin instead.

 

Hopefully this SVG gotcha can help other when using GSAP, especially for SVG.

 

Happy Tweening :)

  • Like 13

Share this post


Link to post
Share on other sites

A quick tip for reversing path points in Adobe Illustrator.


  1. Open path: select the pen tool and click on the first point of your path and it will reverse the points.
  2. Closed path: right click the path and make it a compound path, choose menu-window-attributes and then use the Reverse Path Direction buttons.

(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')


  • Like 6

Share this post


Link to post
Share on other sites

Hello fellow GreenSockers!

 

I thought i would add my SVG gotcha since this type of thing comes up at least one time a day regarding SVG with GSAP.

 

This is regarding animating SVG elements within an SVG <defs> tag.

  • If you are trying to animate elements within an SVG <defs> element, then you should use the GSAP AttrPlugin.

     

  • If your SVG elements are not within a SVG <defs>, <symbol>, or <mask> element .. than you should use the GSAP CSSPlugin like your already doing!

 

This is a great and really important point!

 

It means several things in practice:

  • be careful not to get confused with GSAP's x:
    • when used with the CSSPlugin, it means a translation along the X axis of the element. The element's starting position is the axis origin. If you use x:100 on an element, it will move 100px to the right of its initial position.
    • when used with the AttrPlugin (inside attr:{}), it means a manipulation of the SVG element's X attribute. The axis origin, in this case, is the same as the parent coordinate system's. If you create an element in a vector software and position it at x:100, then using attr:{x:100} on it with GSAP will do nothing.
  • if you want to animate, say, a mask, you can't do it using something like GSAP's rotation: keyword. You have to manipulate its SVG attributes directly. This is easy if you want to simply translate it, but if you want to rotate it, some maths will have to be involved. Here's an example of this: http://codepen.io/Acccent/pen/yYPJOL
  • another thing to keep in mind is that both transformOrigin and svgOrigin are part of the CSSPlugin, so if you're animating the SVG attributes directly with the AttrPlugin, you'll have to do without them.

A general tip when working with Illustrator: always use relative values. If you move an element 100px downwards in Illustrator, then using y:"+=100" or attr:{y:"+=100"} has the same effect, so it's less prone to mistakes. So, when you're planning an animation in your vector software, make sure to note down the start and end positions of all the elements you move, and then use the difference and use that with GSAP. It will save you a lot of trouble.

  • Like 7

Share this post


Link to post
Share on other sites

It's hard to figure out where something is with multiple transforms applied to it. That's why I was disappointed to see the getTransformToElement method removed in Chrome 48.

http://greensock.com/forums/topic/13671-gettransformtoelement-removed-in-chrome-48/

 

And using something like the following is not always accurate with nested transforms...

var x = myElement._gsTransform.x;

Thankfully, the polyfill seems to work great. Notice how I can place the green circle on the top-left corner of the orange box without doing any calculations. Try doing that manually!

 

http://codepen.io/osublake/pen/f4eb73885cf82831fcd8b30539a32901?editors=0010

  • Like 5

Share this post


Link to post
Share on other sites

Hi Adone, 

 

I can't really tell you what to conclude about Adobe. We haven't files any formal requests with them yet.

 

If you have particular pain points and proposed solutions perhaps you can consolidate them in a single post in this thread, however I'd really like to keep this thread focused on workflow tips.

Hello Carl,

 

My pain point is with the export of svg from Illustrator (and to a lesser degree the position of a svg inside Illustrator when you re-open a file). Svg has been around for quite some time now and Adobe is a big company with lots of resources and Illustrator is not a brand new program that still hasn't worked out the starting bugs. But still the svg-export doesn't work correctly. Even after the creation of the extra export option.

 

As I said. Finding workarounds in the mean time is a great initiative. But, the web animation community has some big names like Greensock, Chris Gannon and many others. Why is there no pressure, no formal request to resolve this problem? Preventing is better than curing, isn't it? And it is not like there has to be made a choice, one or the other. Why not both?

 

Kind regards,

 

Ad

Share this post


Link to post
Share on other sites

Another helpful Gotcha is a online svg tool to help clean your Illustrator or vector programs generated SVG code.

 

This link has been lingering in the forum for quite some time. So I though I would post it under the SVG Gotcha Topic.

 

But it will help clean up and optimize your SVG code

 

SVGOMG: https://jakearchibald.github.io/svgomg/

 

After you paste your code, make sure to toggle some of the options on the right:

  • so toggle off Clean IDs
  • and toggle on Prettify code if needed

This will help clean malformed or dirty generated SVG code from vector drawing programs.

 

Also there is a function Jack created to clean up the data (d) attribute:

 

http://greensock.com/forums/topic/13688-awful-morphing-due-to-scientific-float-notation/#entry57447

 

Hope this helps! :)

  • Like 6

Share this post


Link to post
Share on other sites

Hi Ad,

 

I'm not familiar with the positioning bug you mentioned. Have you tried documenting it and reporting it with Adobe? We really don't have the bandwidth to act as a middleman for their support. However, if you can provide a short video of the problem it will help them address it or perhaps I can use it if I decide to formalize some requests with Adobe. They have been kind enough to invite our feedback, but we have a stack of priorities that we need to see to first.

 

thanks for the feedback.

Share this post


Link to post
Share on other sites

Animation/Workflow tip: Don’t forget - you can animate the viewBox attribute

I don’t see this technique in practice (or talked about) very much, but sometimes it may be a better solution than trying to scale elements and center them.

 

To illustrate this easy, but powerful method of SVG animation, I’ve made a simple house tour complete with some GreenSock home décor and a few nods to our great moderators. Take a look:

 

http://codepen.io/PointC/full/OMabPa/

 

 

Some additional detailed tips about this process:

 

How do you know the coordinates to use for the viewBox animation?

Using Adobe Illustrator, you can simply view the entire SVG and hover over your desired areas for the viewBox and note the coordinates from the info panel. You can also add a square/rectangle over the area(s) you wish to zoom (make it transparent with a dashed border) and then use the coordinates of that shape as your viewBox data. You can even leave the rectangle/square in place during the animation process so you know you’re hitting the right target and then delete it before releasing the SVG into the wild.

 

Keep aspect ratio in mind when using this technique

If you start with a square (1:1) SVG, you’ll experience the best results if the areas to which you are cropping/zooming are also square. Likewise, for any rectangular areas - maybe start with a 2:1 ratio and zoom into areas that are also close to that as well. You can certainly zoom/crop to other ratios as seen in my simple demo above (two rooms are square like the SVG, but two rooms are rectangular), but it’s something to keep in mind. Also note that by changing the aspect ratio and/or cropping too close to the edge of the SVG, you can end up with some unwanted white space.

 

As usual, IE hates SVGs

You have to remember to set your SVG to overflow:hidden when animating the viewBox attribute in IE or goofy things will happen.

 

Responsive sizing for static web delivery too

You don’t necessarily have to animate the SVG viewBox either. Using different viewBox sizes, you can also show different sections of your SVG for different screen sizes. Show the whole thing to desktop users and crop to the most important part for mobile delivery etc.

 

Finally, go big or go home

Start with the biggest size you think you’ll need for your SVG. IMHO this goes for any SVG, not just those with a viewBox that will be animated. In my experience, you’ll encounter less trouble scaling down than scaling up.

 

 

Hopefully this gives everyone some new ideas.

 

Happy tweening.

:)

  • Like 14

Share this post


Link to post
Share on other sites

Hey PointC, Great demo of animating the viewbox attribute with GSAP. :D

 

That SVG IE overflow behavior your seeing is only in IE11. Microsoft fixed that behavior in MS Edge:

 

https://connect.microsoft.com/IE/feedbackdetail/view/920757/ies-overflow-behavior-for-svg-elements-doesnt-match-other-browsers

 

Taken from that page:

  • IE11 treats SVG elements like other HTML elements in that overflow content is visible outside its box. All other browsers render this scenario as though the SVG element were clipped (e.g. like overflow: hidden, even though the computed value of overflow is still "visible" in other browsers).

So they only added this fix to MS Edge. But decided to not fix it for IE11. So for IE10 / IE11 you need to set overflow attribute to hidden or set overflow:hidden in your style-sheet.

 

:)

  • Like 2

Share this post


Link to post
Share on other sites

As Jonathan said: Hey PointC, Great demo of animating the viewbox attribute with GSAP.  :D

 

I am very interested in the contents of the books shown in the bonus bookshelf!

  • Like 2

Share this post


Link to post
Share on other sites

Thanks violacase

 

Those books in my demo are the unauthorized  :ph34r: biographies of Blake, Jonathan and Diaco.

 

It's all top secret so don't tell them.  :-P

  • Like 7

Share this post


Link to post
Share on other sites

Hi Ad,

 

I'm not familiar with the positioning bug you mentioned. Have you tried documenting it and reporting it with Adobe? We really don't have the bandwidth to act as a middleman for their support. However, if you can provide a short video of the problem it will help them address it or perhaps I can use it if I decide to formalize some requests with Adobe. They have been kind enough to invite our feedback, but we have a stack of priorities that we need to see to first.

 

thanks for the feedback.

Hello Carl,

 

It was not my intention to use Greensock as a middleman to solve my pain point (and of a lot of other Adobe Illustrator users). It was my suggestion to use the combined influence of Greensock and all the great names in the field of web animation to stimulate Adobe to solve the svg export problem(s) asap. Not just being kind enough to listen to the feedback. It's better to try to close the fosset than keep trying to find better ways to keep mopping up the spill. But no one seems to agree with me, so I'll stop.

 

Thanks for your reply and good luck with the feedback and with this initiative to find better workarounds,

 

Ad

Share this post


Link to post
Share on other sites

Quick Tip: Animating dashed strokes with the DrawSVG plugin

I've seen a few forum questions about animating a dashed line in SVGs. The DrawSVG plugin won’t draw a dashed path. If you try, it will remove your stroke dash array and turn the stroke solid. DrawSVG works by making one big dash and animates the offset. But you can create this effect with one extra step during the SVG creation process. Simply create your dashed stroke(s) as usual and then:

  1. Duplicate your dashed path
  2. Remove the dashes of the duplicate
  3. Make the duplicate solid white (very important).
  4. I also like to add a few pixels to the duplicate stroke width for safety

This new solid path stroke will act as the mask for your dashed stroke. This gives you the ability to animate the appearance or disappearance of the dashed stroke by animating the mask path with the drawSVG plugin and maintain full control of the dashed-stroke color, width, dasharray etc.

 

I’ve created a CodePen to show how this can work for basic shapes, squiggly lines and maps.

Behold the amazing, exciting and groundbreaking dashed lines demo:

 

http://codepen.io/PointC/full/zrQLvO/

 

o.k. – maybe it’s not that exciting :-P  Hopefully it helps someone with this type of effect though. 

 

One additional note: my demo utilizes the DrawSVG and morphSVG plugins. You can experiment with these on CodePen, but to use them in the wild you will need a Club Membership - which I highly recommend.

 

Happy animating everyone. 

:)

  • Like 12

Share this post


Link to post
Share on other sites

Using Gulp is one the best ways to create a frictionless workflow for your SVG animations. Pretty much the antithesis of Mr. Gannon's video. I don't have the time or space to explain how to use it in this post, but for those who are using it, I found a little snippet of code that might be very useful. It uses the gulp-inject plugin.

 

Inject SVG

https://github.com/kiyopikko/inject-inline-svg/blob/master/gulp/injectsvg.js

 

Using that as a task, you will probably never have a reason to ever touch the SVG inside your code editor. Lets say you are working on an SVG named flower in the following path src/svgs/flower.svg

 

To inject it in your HTML, you would create a placeholder like this...

<!DOCTYPE html>
<html>
<body> 
  <!-- src/svgs/flower:svg -->
  <!-- endinject -->
</body>
</html>

Sample gulpfile.js setup

var gulp = require("gulp");
var inject = require("gulp-inject");
var browserSync = require("browser-sync");
var parsePath = require("parse-filepath");
var fileset = require("fileset");

var reload = browserSync.reload;

gulp.task("svg", function() {
  // Run inject svg and other svg related tasks here like SVGO
});

gulp.task("serve", ["svg"], function() {
  browserSync({
    port: 3000,
    server: [".tmp", "dist"]
  });

  gulp.watch(["src/svgs/**/*.svg"], ["svg", reload]);
});

gulp.task("default", ["serve"]); 

Now anytime you change an svg, that task will automatically run, injecting the updated SVG, and then it will reload your browser. The injected SVG will be a copy, so it's not going mess with the original SVG you are working on. NICE!!!

 

Also, using BrowserSync provides an IP address for you to connect other devices, like your mobile devices, so all changes will be synced across all your connected clients. You can even use a proxy for browser sync if you're using a development server for doing stuff like WordPress development.

  • Like 4

Share this post


Link to post
Share on other sites

Have you ever wanted to bring the 3RD dimension into your project with the DrawSVG plugin?

Using a series of masks we can simulate an SVG stroked path navigating around or through a subject in a photo. This path can be solid, dashed, dotted or whatever you like. My new demo uses some things from my post above about animating dashed strokes with masks, but goes a bit further.

 

Get wrapped up in the swirling 3D lines of the DrawSVG plugin:

 

http://codepen.io/PointC/full/ZWEqdK/

 

 

If you want to use this technique, here’s a bit of info:

  • Start with the photo you’re using at the maximum size you think you’ll need. (Note: You can responsively swap to smaller versions as long as you maintain the same aspect ratio.)
  • Create a new AI file the exact same size as you biggest photo.
  • Import the photo for use as the background while designing your SVG. (Be sure to also create a plain rectangle that’s the same size as the SVG so everything lines up at export time)
  • Draw the stroke that will be wrapping around/through the subject to your liking.
  • Duplicate that path and make it #fff – this copy will be the mask. Unlike my earlier post where I mentioned making the mask path wider than the original, this time it needs to be the exact width as the underlying path. If it’s wider, you’ll inadvertently be showing extra parts of the original path at perpendicular intersections.
  • (Note: making a duplicate path for a mask reveal is only necessary if you want to use dashed strokes. If you’re using solid strokes only, you can simply animate them directly with the DrawSVG plugin.)
  • At all points where the stroke should be going behind the subject, draw a polygon over the subject with a color of #000. All these polys will be a part of your SVG mask along with the stroke mask that will animate. The polygons will be static but will scale perfectly.
  • For my demo, I used three separate strokes to create a simple tube effect as it draws and you can see a bit of the perpendicular intersection reveal problem if you watch for it. It’s not too bad, but something to keep in mind. As mentioned above, if you’re using a solid stroke and don’t need dashes, no mask path will be necessary and this isn’t going to be an issue for you. You would just need your subject masking polygons.
  • Finally, I put the image into a containing div and let the image drive the size of it. Place your SVG into the div with absolute positioning and a width of 100% so it can scale along with the image and containing div. All that’s left after that is to control the mask reveal and animate any changes in the stroke that you like.

Note: the demo uses the DrawSVG plugin which is a Club GreenSock perk at the Simply Green membership level. I highly recommend it.

 

Happy tweening everyone.

:)

  • Like 8

Share this post


Link to post
Share on other sites

Really cool PointC!!!

 

If you want to add a more 3D look to your strokes, you should check out these articles.

http://owl3d.com/svg/vsw/articles/vsw_article.html

http://owl3d.com/svg/calligraphy/calligraphy_pen_article.html

 

You'll have to inspect each SVG to get the code, but that's how I made this SVG drawing demo.

  • Like 5

Share this post


Link to post
Share on other sites

Animation/Workflow tip: Don’t forget - you can animate the viewBox attribute

I don’t see this technique in practice (or talked about) very much, but sometimes it may be a better solution than trying to scale elements and center them.

 

To illustrate this easy, but powerful method of SVG animation, I’ve made a simple house tour complete with some GreenSock home décor and a few nods to our great moderators. Take a look:

 

http://codepen.io/PointC/full/OMabPa/

Love this viewbox technique. I want to use something like this for my game Firmament Wars. It's like Risk, so I'd have to focus on selected territories and stuff like that. Is there an easy way to determine the x y w h values for each path you want to focus on? Or does that have to be figured out and hardcoded one by one?

 

Edit: Nevermind, I just read the rest of your comment. So you basically use Inkscape/Illustrator to find the coordinates you need? Very smart. I was thinking about this and the thought of using 3D scaling didn't sit well with me. It would be so much trial and error to get the right positions.

Share this post


Link to post
Share on other sites

Hello,

 

I created my own dashed strokes from Illustrator and applied the code from PointC's example in animating dashed strokes. I like it but, it starts off with a flash of the full path before the animation starts. Is there a way where to avoid this so that the animation will play more smoothly?

 

Here is my codepen link:

 

http://codepen.io/djumeau/pen/pyXwjv

 

Any suggestions to improve on this?

 

Quick Tip: Animating dashed strokes with the DrawSVG plugin

I've seen a few forum questions about animating a dashed line in SVGs. The DrawSVG plugin won’t draw a dashed path. If you try, it will remove your stroke dash array and turn the stroke solid. DrawSVG works by making one big dash and animates the offset. But you can create this effect with one extra step during the SVG creation process. Simply create your dashed stroke(s) as usual and then:

  1. Duplicate your dashed path
  2. Remove the dashes of the duplicate
  3. Make the duplicate solid white (very important).
  4. I also like to add a few pixels to the duplicate stroke width for safety

This new solid path stroke will act as the mask for your dashed stroke. This gives you the ability to animate the appearance or disappearance of the dashed stroke by animating the mask path with the drawSVG plugin and maintain full control of the dashed-stroke color, width, dasharray etc.

 

I’ve created a CodePen to show how this can work for basic shapes, squiggly lines and maps.

Behold the amazing, exciting and groundbreaking dashed lines demo:

 

http://codepen.io/PointC/full/zrQLvO/

 

o.k. – maybe it’s not that exciting :-P  Hopefully it helps someone with this type of effect though. 

 

One additional note: my demo utilizes the DrawSVG and morphSVG plugins. You can experiment with these on CodePen, but to use them in the wild you will need a Club Membership - which I highly recommend.

 

Happy animating everyone. 

:)

  • Like 1

Share this post


Link to post
Share on other sites

Hi David :)

 

Welcome to the GreenSock forum.

 

Nice work on your demo. I'm glad you found my dashed strokes info useful.

 

The quick flash you're seeing is the fromTo() tweens firing immediately. You could solve this by adding immediateRender:false to those tweens like this:

.fromTo(maskPath, 1, {drawSVG: "0% 56%"}, {drawSVG:"0% 100%", ease: Linear.easeNone, immediateRender:false})

I used fromTo() tweens in my original demo, but you could also use .to() tweens and solve the quick flash problem as well. Here's a fork of your pen with that option.

 

http://codepen.io/PointC/pen/JKPrNQ/

 

I also combined your four autoAlpha set()s of steps 1-4 into one set() since you had the same class applied to all of them. Hopefully that makes sense.

 

Just an FYI - please start a new topic for any additional questions. We've been trying to keep this thread focused on tips, tricks and gotchas.

 

Happy tweening and welcome aboard.

:)

  • Like 5

Share this post


Link to post
Share on other sites

A little tip about masking a stroke like PointC is doing. If you notice your masks are being clipped or aren't showing up, try specifying the units like this.

<mask id="mask" maskUnits="userSpaceOnUse">
  <path class="mask-path" d="M100,250 500,250" />
</mask>

In this demo you can't see the vertical and horizontal lines. And in some browsers like Firefox and IE/Edge, the curved path is being clipped 20px on the top and bottom.

http://codepen.io/osublake/pen/394dfe1ade2c3a51d1f3516ecda2b794?editors=1000

 

And here it is after setting the units.

http://codepen.io/osublake/pen/d9b5c4c5204a8bf3e4044c30c813a2c8?editors=1000

  • Like 4

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.