Jump to content
Search Community

Apply transforms with transform attr instead of inline style on SVG

ciquar test
Moderator Tag

Warning: Please note

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. 

Recommended Posts

I've noticed that GSAP applies transform properties to SVG elements via the inline style attribute instead of the native SVG transform attribute: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform. This tends to be a browser compatibility issue, especially with IE. I cross referenced Velocity JS, and it looks like there's some feature detection built in that deals with this issue.


Am I missing something? Or does GSAP have a method of accomplishing this easily? I should note that I already have some functional code, but it's a lot more verbose than I'd like it to be; onUpdate functions running after every tween.


To be sure I'm clear, I want:


transform="translate(40, 60)"



instead of

style="transform: matrix(1, 0, 0, 1, -45, 75)"


(ignore number values)



Thanks for the help

Link to comment
Share on other sites

Hello ciquar, and Welcome to the Greensock Forum!


Since you are explicitly trying to animate the transform attribute.. you need to add that transform within the attr:{} object

// uses the CSSPlugin to animate the css transform property 
TweenLite.to("#element", 1.5, {transform:"translate(40, 60)"});
// or another GSAP css way
TweenLite.to("#element", 1.5, {x:40, y:60});

// uses the AttrPlugin to the transform attribute with attr: {} object
TweenLite.to("#element", 1.5, {attr:{transform:"translate(40, 60)"}});


When animating attributes, GSAP uses the AttrPlugin:




Below is taken from AttrPlugin Docs:


Tweens any numeric attribute of a DOM element. For example, let's say your DOM element looks like this:

<rect id="rect" fill="none" x="0" y="0" width="500" height="400"></rect>


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});


You can tween an unlimited number of attributes simultaneously. Just use the associated property name inside the attr:{} object.

AttrPlugin is NOT intended to be used with css-related properties because the CSSPlugin already handles those.


Note: a common mistake is to forget to wrap attributes in a attr:{} object which is essential for specifying your intent.


TweenMax includes both the AttrPlugin and the CSSPlugin.. plus so much more!


Hope that helps! :)

  • Like 2
Link to comment
Share on other sites

Thanks for the reply, Jonathan.


Things aren't quite coming together yet. Looking at this little piece of code...

attr: { transform: "translate(0, -110)" }

...I was under the impression that a string like "translate(0, -110)" was untweenable and thus necessitated breaking them into their own properties, such as x and y. Am I wrong? Up until now, I had so strongly assumed that that wouldn't work that I didn't even try. I'll get a couple of test cases ready tomorrow, but haven't seen this working yet. Of course, I'd love this to work.


I've used some of the other methods you've mentioned above, such as using the attr plugin to tween the x and y properties of SVG components, and that's worked wonderfully. I'm at the point where I am now because x and y aren't options with <path> or <g>, both of which I need translation control over. And CSS transforms applied to SVG elements is limited to webkit, for viable results.


Thanks again

Link to comment
Share on other sites

Thanks so much. It's true, my workflow isn't too beautiful right now, and I'm the one on the project who was pushing to use GSAP.


I feel like there's a good solution just out of my reach. I mean, the exact values I need are already being generated in the case of a CSS transform, I just need that to move into another attribute.

Link to comment
Share on other sites

Thanks Jamie,


The technique you mention is probably the most concise method of handling the issue. Though, it doesn't seem ideal from a performance standpoint. It sounds like it'll be a compromise one way or the other until, as you said, an in-built solution comes out.

Link to comment
Share on other sites

I have attached a preview of the upcoming GSAP 1.14.0 release that should smooth this out for you. Not only does it sense SVG elements and apply the transforms to the "transform" attribute in IE, but it takes it one step further - it does the math to adjust the matrix so that transformOrigin is honored. This is a big deal because I'm sure you want things to animate the same in all browsers, including IE but if you try to rotate, for example, with Velocity it'll act like the origin (pivot point) is in a completely different spot in IE. This isn't necessarily a bug in Velocity - it's just that SVG itself applies the "transform" attribute in that manner that the origin is in the element's parent's origin! With this version of GSAP, it'll honor whatever you set with transformOrigin, even things like "bottom right" or "50% 50%" or whatever. 


Let me know if this works well for you. I'm still making some changes to other portions of GSAP (unrelated to SVG or CSSPlugin), but I wanted to get this early version into your hands so that you could kick the tires and let us know if it works well for you. Of course anybody else is encouraged to test it out too and provide feedback. 


  • Like 3
Link to comment
Share on other sites

This sounds PERFECT! Great news Jack! I will give it a go tomorrow as we try to knock out some other bugs.


I am curious how it works under the hood... In my experiments I was animating an off DOM element and copying the transform's matrix. I too ran into the issue with transform-origin. But I didn't get a chance to see if translating the matrix would fix it.


I am assuming there is some underlying matrix math going on in TweenMax. Are you just handling internally with TweenMax and applying the attribute from this matrix?


Also there might be one more thing you want to add to your SVG workflow... Firefox (some versions?- not sure) has a known bug with percentage based transform origins on SVG elements. There is a workaround by using pixel based transform origins instead. Would be another nice-to-have... ;)


Thanks again for this! Can't wait!

Link to comment
Share on other sites

Yep, CSSPlugin is doing the math under the hood to adjust the matrix() to incorporate the transformOrigin. It should be seamless and transparent to the user. But yeah, if you looked at the actual style.transform value in a Webkit browser and compared it to the "transform" attribute in IE for the exact same animation, you'd see that they're different (just the last 2 components of the matrix()). 


Did you see a problem with the way it's handling things in Firefox? I didn't notice anything odd yet, but I haven't done extensive testing. Please let me know if you notice anything strange. 


And for the record, it only populates the "transform" attribute in IE browsers and non-chrome Android. Everywhere else, it just uses normal CSS transforms. 

Link to comment
Share on other sites

Fantastic work, Jack!


I'm testing everything out right now. I've already seen a couple of odd behaviors, so I set up a reduced test case here: 

See the Pen 7db9a3f2fcd0b945c566007971c68efc by kkrueger (@kkrueger) on CodePen


Chrome looks perfect.

Firefox is translating correctly, as expected, but the transformOrigin is being applied to the top left instead of 50% 50%.

IE11 doesn't appear to be translating at all, but is applying the rotation. transformOrigin is off here too, rendering at 0% 50% instead of the specified value.


Quick question: is there a performance gain in applying transforms with the inline style attribute versus using the transform attribute within SVGs?

Link to comment
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.
  • Create New...