eo en en en en en en en en en en en en en en en en en fa en en fr hbs_lat en en en es en en en ms en de en fr en en en ca en en en en en en en en ms eo en eo en en en en en sv en en en en en en en en en en en en fr en en en en en en en en en en en en en en en en en en en en en en en ru en en fr en en en en en en en en en en en en en en en en en en en en en en en en en en en en fr en en en en en en en en en en en sv en en en en en en en en en en en en en en uk en en en en fa en en en en en en en fr en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en fr en en en en en en en en en en en en fr en en en en en en en en en en en en en en en sv en en en pt en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en fr en en en en en en en en en en en en en en en sv en en en en en en en en en en en en en en en it en fr en en en en en en en en en en en en en sv en en en en en en en en en en en en en en en en en en en en en en en en en en en en fr en en en en en en en en en en pt fr en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en en sv en en en en en en en en en en en en en en en pt en en en en en en en en en en en en en en en en en en en en en en en sv en en en en en en en en en en en de en en en en en en en en en en en en en en en en hsb en en en en fr en en en en en en sv en en en en en en en en en en en en en en en en en en en ms eo en en en it en hu en en en pl en de en en en nl en en en en en en en en en fr cv es tr es en en en en ms en en en en en en fr en hbs_lat en en en en en en en fr cv es tr es en en en en de en en en ca en en en en en
This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax.
The color of a mask defines its opacity. White is opaque, black is transparent.
See the Pen 2bd6924c63437578626edb9d5b8fcdb9 by osublake (@osublake) on CodePen
Johan ⚡️ Nerdmanship    35 Likes (Newbie)
I'm not sure this is a gotcha, but it's definitely a confusing matter that has been very time-consuming for me. Dropping it here to maybe save someone else.
See the Pen ALoWpk by nerdmanship (@nerdmanship) on CodePen
using the same path for both masking and clipping to compare the two. I expected the exact same result, but the mask clearly includes all the attributes and the clipPath is ignoring the stroke attributes and just renders the inside of the path (like a fill would).
"For the clipping, every path inside the clipPath is inspected and evaluated together with its stroke properties and transformation."
Mozilla Docs: Clipping and Masking
I don't think the doc is wrong, but it's definitely confusing. I understand this as the stroke properties will be included.
"A clipping path is conceptually equivalent to a custom viewport for the referencing element."
This, to me, means never do anything fancy with clipPath. Just use it to define a "viewport".
On my recent handwriting demo (
See the Pen MpLVvO by PointC (@PointC) on CodePen
), I hit a little oddity in Chrome involving the bounding box of a SVG group and incorrect data.
Chrome seems to be calculating the group BBox based on the child elements plus the Bezier handle positions of the path(s).
You can check it for yourself:
See the Pen vxqgrr by PointC (@PointC) on CodePen
Wow, great find Craig. Thanks for sharing the details.
I believe this to be the webkit getBBox() svg bug report for what you are describing:
Bug 53512 - [CG] getBBox() on a SVGPathElement with curves incorrectly includes control points
It looks like it affects SVG   elements with cubic bezier curves that calculate more than what the actual getBBox() is.
It shows as RESOLVED FIXED in the above bug report, but with webkit that doesn't mean anything since webkit is a groundhogs day of fun feelings!
Here is a new Chrome webkit bug report ticket regarding this webkit bug, - ticket status is STARTED
Issue 230599 getBBox() on a SVGPathElement with curves incorrectly includes control points
Issue 646525 SVG path and g element return incorrect values in getBBox result for some arcs
Share on other sites
PointC    14,034 Likes (Superhero)
Posted April 13, 2017
If they ever did have that fixed, they must have brought it back for Throwback Thursday.
Strangely, the BBox of the path itself is accurate. It's only when it's calculated in a group or as part of the entire SVG that it's wrong.
Share on other sites
Jonathan    5,380 Likes (Superhero)
Posted April 13, 2017
Hi Craig, I added the below ticket to my post which affects when using   element as well as   element. Looks like they merged it to the first open ticket.
Issue 646525 SVG path and g element return incorrect values in getBBox result for some arcs
Share on other sites
OSUblake    18,414 Likes (Superhero)
Posted April 17, 2017
Everything about getBBox is a gotcha. For those that don't know what it is, it's a method on SVG elements that will return its position and size...
var bounds = someElement.getBBox(); // => { x: 0, y: 0, width: 100, height: 100 }
Sounds pretty useful as positioning is an important part of animation. The problem is that it reports its bounding box without any transforms applied. What does that mean? If you have an element at 0,0 and tween it to 100,100 using x and y, and then get it's bounding box, it will say it's still at 0,0. This goes for all transforms, x, y, scale, rotation, etc. Not very useful considering most animations use transforms.
Things get even more confusing with group   elements, which don't have a fixed bounds like other elements. They are calculated based on the size and position of their children. If you call getBBox on a group, and it has transformed children inside of it, it will take into account those transforms.
Look at this example. The green box is the bounds of the group. The red box is the bounds of the blue square. As you can see, the blue square is nowhere near the red box. It uses transforms to calculate some things, but not others, which can be really confusing.
Check it out for yourself....
See the Pen a6ba567d431f4b767942fd91afc0bb42?editors=1111 by osublake (@osublake) on CodePen
Another confusing thing about bounds is that they are axis-aligned (AABB), meaning they are parallel to the x and y axis. Take a look at what happens when you rotate an element. The blue boxes are the original bounds of the element, but they are no longer aligned, so a new bounds is created around them to make them aligned. This causes the bounds to separate and move away from the element. Look at how the green boxes don't even touch the elements on the left and right.
You really need to see it in action to fully understand how it works. The red boxes are the bounds getBBox reports. The blue box is the transform being applied to the red box. And the green box is the transformed bounds, which is calculated by drawing an axis aligned box around the blue box. Notice how large the transformed bounds become at the end. That can cause stuff like hit testing with Draggable to fail.
See the Pen ZKGjRo by osublake (@osublake) on CodePen
So there's a little info about bounds and why getBBox isn't that useful. Well, unless you want to find the original position and size of your element. But it's not a total loss. It just needs to be improved, so I made a little getBBox helper function that will calculate transformed bounds, which is what's needed to get correct positioning.
/** * @param {SVGElement} element - Element to get the bounding box for * @param {boolean} [withoutTransforms=false] - If true, transforms will not be calculated * @param {SVGElement} [toElement] - Element to calculate bounding box relative to * @returns {SVGRect} Coordinates and dimensions of the real bounding box */ function getBBox(element, withoutTransforms, toElement) { var svg = element.ownerSVGElement; if (!svg) { return { x: 0, y: 0, cx: 0, cy: 0, width: 0, height: 0 }; } var r = element.getBBox(); if (withoutTransforms) { return { x: r.x, y: r.y, width: r.width, height: r.height, cx: r.x + r.width / 2, cy: r.y + r.height / 2 }; } var p = svg.createSVGPoint(); var matrix = (toElement || svg).getScreenCTM().inverse().multiply(element.getScreenCTM()); p.x = r.x; p.y = r.y; var a = p.matrixTransform(matrix); p.x = r.x + r.width; p.y = r.y; var b = p.matrixTransform(matrix); p.x = r.x + r.width; p.y = r.y + r.height; var c = p.matrixTransform(matrix); p.x = r.x; p.y = r.y + r.height; var d = p.matrixTransform(matrix); var minX = Math.min(a.x, b.x, c.x, d.x); var maxX = Math.max(a.x, b.x, c.x, d.x); var minY = Math.min(a.y, b.y, c.y, d.y); var maxY = Math.max(a.y, b.y, c.y, d.y); var width = maxX - minX; var height = maxY - minY; return { x: minX, y: minY, width: width, height: height, cx: minX + width / 2, cy: minY + height / 2 }; }
The function takes 3 parameters. The first one is required, which is the element you want to get the bounds for. The second one, calculateWithoutTransforms, will calculate the bounds without any transforms if set to true. And the third parameter is an element to calculate the bounds relative to. By default it uses the SVG document the element is in, which is usually what you want, as it's kind of like the global space.
I also have another version that will work around the Chrome bug that PointC came across. I was able to get around the bug by manually calculating the bounds of all the children in a group element instead of calling getBBox.
So here's a pen of the original version...
See the Pen YVXvgR by osublake (@osublake) on CodePen
And the one with the Chrome workaround...
(EDIT - looks like Chrome fixed the bug so this isn't necessary anymore)
See the Pen BRNPrL by osublake (@osublake) on CodePen
And one last tip. You can set outlines on SVG elements in your CSS in Chrome. This is really helpful as it will let you see where stuff is, like a group element, which is usually invisible. That makes positioning so much easier. You can even see it incorrectly apply an outline on paths inside a group, just like with PointC issue.
g { outline: 1px dashed red; } path { outline: 1px solid blue; }
Putting it all together:
Share on other sites
Carl    10,907 Likes (Superhero)
Posted April 17, 2017
Amazing stuff, Blake. Love the demos and clear explanation. My vote is that you create a CodePen Blog Post (you can easily embed the demos) with this info. More people need to see this stuff.
Share on other sites
PointC    14,034 Likes (Superhero)
Posted April 17, 2017
I'm with Carl - please write that up for a CodePen blog post. The more people over there that realize how smart you are and that you hang out here in GreenSock Land, the better it could be for the GS community.
Bring on the new Club Members. Just think how full your $1/answer tip jar could be with a bunch of new GSAP users.
Share on other sites
kvnmcwebn    12 Likes (Newbie)
Posted June 7, 2017
Carl's video tutorial on the first page of this thread is brilliant. I found the copy and paste from Illustrator artwork to SVG code works in Adobe Brackets as well as Sublime text.
Share on other sites
Dipscom    3,362 Likes (Superhero)
Posted October 3, 2017
Yay! I get to contribute here
But not without a hat tip to @OSUblake
You can nest an SVG into another SVG - That's quite handy for a number of reasons,  one quick example would be: You have a super complex drawing with some text inside it. You can have an inline SVG that holds the text and then, nest the other SVG in with an  . That'll keep the text reachable with CSS and JS without having a wall of code for the rest of the drawing.
However - If you end up nesting an SVG inside another one you will not be able to transform the nested root SVG element (for now).
See the Pen 11a819dd170f2f0079307289f60cefa5 by dipscom (@dipscom) on CodePen
Share on other sites
PointC    14,034 Likes (Superhero)
Posted October 3, 2017
While we wait for SVG 2 and the ability to transform nested SVGs, you can currently fake a scale() for a nested SVG. By animating the width/height/x/y attributes we can create the illusion of animating scale(). If you don't have those attributes on the nested SVG, you can add them via a TweenMax.set(). You can then gain some control and fake the scale along with changing the point of origin.
See the Pen BwwEyK by PointC (@PointC) on CodePen
Not a perfect solution, but if you only want to scale a nested SVG from a specific point, it works.
Share on other sites
OSUblake    18,414 Likes (Superhero)
Posted October 3, 2017
The last example in @Dipscom's demo is a good work around. Wrap the nested svg in a   and scale that.
TweenMax.to('.circle', 1, { scale: 0 });
Share on other sites
PointC    14,034 Likes (Superhero)
Posted October 3, 2017
Oh, I wasn't questioning the solutions.
Grouping is probably the best/easiest way to go in most cases. I was just curious if I could push some attributes on it and get any sort of control.
Share on other sites
OSUblake    18,414 Likes (Superhero)
Posted October 3, 2017
26 minutes ago, PointC said:
Oh, I wasn't questioning the solutions.
Hehe. I was thinking of the same work around as you. I didn't even think of doing what  @Dipscom did with the group.
Share on other sites
mikel    4,758 Likes (Superhero)
Posted October 3, 2017
Already a Greek mathematician said: Noli turbare circulos meos!
Share on other sites
Dipscom    3,362 Likes (Superhero)
Posted October 4, 2017
If one is not as smart as @PointC or @OSUblake to come up with nice calculations and/or is lazy enough, one just cheats with
Share on other sites
francis789    6 Likes (Newbie)
Posted April 10, 2018
Having watched Chris Gannon's video I'd like to suggest a slightly different workflow.
After some trial and error I find the easiest is to keep all the graphic editing in Illustrator, do export as an SVG file, that leave it unchanged. Then in the html page I load the svg file using ajax, with a recipe found here: http://plnkr.co/edit/LneUEK?p=preview .
I did a CodePen to illustrate the method, with a "this works / this does not work" example, to show the utility of those lines of code:
See the Pen vRzYQd by fvila (@fvila) on CodePen
I've got rid of "_1" ids by attributing names to the layers in the Illustrator's layer panel. Or at least, to any object I will need to animate or manipulate later.
The advantage is that you don't have to do any of the copy-pasting described by Chris. You can keep the exported SVG file in the text editor for reference. Each time you do another export the text editor asks you whether you want to load the new version, and all you have to do is click OK.
The only drawback I see is that it doesn't work in CodePen. If you want to share your code, you have to do the copy-paste the SVG into the html section of Codepen. But you would typically do that once or twice, not all the time as you would when you are trying to get things to work.
Share on other sites
PointC    14,034 Likes (Superhero)
Posted May 5, 2018
SVG Mask Animations and a slight rotation
This has popped up several times in the forum so I thought I'd drop it into this thread. Some of the browsers are getting fussy with SVG mask animations. This is especially true of DrawSVG stroke masks. You should add a slight rotation to the mask element as it animates to force the browser to redraw the mask. Right now Edge is the biggest offender, but the way Chrome has been adding bugs with each release, it may not be long before they call it a feature.
If you look at this pen in all the browsers, you'll see that most of them handle both mask animations just fine, but in Edge the right one will not work correctly. Try resizing the window in Edge and then using  DevTools to scrub the timeline. You'll see that right mask get rather funky.
See the Pen yjzLLL by PointC (@PointC) on CodePen
I've also seen this in Edge with a rectangular gradient mask so my recommendation is to add that slight rotation to any and all mask animations just to be safe. Happy tweening everyone.
Share on other sites
Friebel    88 Likes (Contributor)
Posted May 26, 2018
Nice thread! I'm gonna read this one on my phone after work, lying in the park
Share on other sites
ZachSaucier    7,086 Likes (Superhero)
Posted January 15, 2020
The SVG specifications currently do not support 3D transforms (including perspective, transformPerspective, rotationY, rotationX, rotationZ, translate3d, rotate3d, and matrix3d) on elements within SVGs. Some browsers go rogue and implement them anyway but it isn't reliable to do in a cross-browser way. This is not a limitation with GSAP, it's a limitation with browsers themselves.
You can work around the lack of 3D transform support of elements within SVGs in some cases by
Faking the transform that you need. For example sometimes rotationYs can be replaced by a scaleX instead.
Applying 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   or   containing a   instead of applying it to the   itself.
Use 3D transforms on SVG elements at your own risk. A browser may choose to remove support at any time given it's not currently part of the official SVG specifications.
Share on other sites
ZachSaucier    7,086 Likes (Superhero)
Posted January 30, 2020
Is your SVG animation performing poorly? Take a look at this post regarding SVG performance. There are likely several things that you can do to increase your SVG's performance.
Share on other sites
ZachSaucier    7,086 Likes (Superhero)
Posted July 7, 2020
@Mamboleoo has been publishing some super handy SVG tips recently. Check them out!
Share on other sites
PointC    14,034 Likes (Superhero)
Posted July 22, 2020
If you want to morph a drip or melt from a straight edge, you'll probably need to add some points to the edge. The problem is that Adobe Illustrator strips the points out of your starting shape when you export because it thinks you don't need them. It's super helpful that way.
I have an entire post about this problem and solution here:
Don't export your paths. Select the paths (and background rectangle) and copy/paste the data into your code editor. The extra points along the straight edge will remain intact giving you a buttery smooth result. Side by side comparison of stripped points vs all points coming through.
See the Pen 5319aa1c56ee55e2978eda9772167c21 by PointC (@PointC) on CodePen
Share on other sites
1 yr ZachSaucier unpinned this topic
Page 2 of 2
Create an account or sign in to comment
You need to be a member in order to leave a comment
Sign up for a new account in our community. It's easy!
Register a new account
Already have an account? Sign in here.
Sign in to follow this   Followers 13
Go to topic listing
Recently Browsing   0 members
No registered users viewing this page.
“GreenSock has encouraged me to play with the code, to dream up new and exciting things to do.”
“The best thing about GSAP is that it just works, and it works well. On every single browser I’ve tested.”
“GSAP hosts what is in my experience, the most welcoming, patient and helpful support forum I've ever come across. I've yet to see a question flat out ignored and the patience you all have in putting people on the right track, if not flat out solve their p”
“Every time a new GSAP plugin is introduced, I'm close to bursting from excitement. The simplicity of the GreenSock API makes learning and applying these tools in projects such a dream.”
“GSAP is just miles and miles ahead of any animation library out there. Great work!”
“@greensock it’s a great library that many people love, and I know you care deeply about performance :)”
“GSAP and CSS Transitions: I've done both, and its like comparing an F16 to a horse. Take like 10 minutes to try.”
“This is why I have absolutely no issues with paying for a subscription to GSAP, great product and awesome forum!”
“The GreenSock animation platform is one of the most useful sets of tools in existence when it comes to web animation.”
Sign Up For Our Newsletter
Get the latest updates on GreenSock products, exclusive offers, and more right in your inbox.
Your information will always be kept confidential.
Thanks for signing up!
Now you'll begin receiving the latest GreenSock updates, exclusive offers, and more right in your inbox. Welcome aboard.