Jump to content
GreenSock

barklund

SVG and DOM transform vs CSS transform

Recommended Posts

Hi there,

(newly registered, but long time user)

I have a problem with SVG transitions. If I have a SVG object with a CSS transform and try to tween it, the tween will set an (ignored) DOM transform attribute and nothing happens.

Using force3D has no effect, as it still only sets the DOM attribute and not the CSS property.

Something is clearly wrong here.

When is this an issue? When using Draggable, as Draggable sets the CSS property. Once a Draggable has been updating the value, I can no longer tween it - even if I kill the Draggable.

Regards,
Morten

See the Pen bqreKO by barklund (@barklund) on CodePen

Link to comment
Share on other sites

I can see that Draggable internally use an applyObj to update the SVG position (which I assume is what sets the CSS property and not the DOM attribute), but even copying this internal variable out to the global scope (via debugging), setting applyObj.data.x and then invoking applyObj.setRatio(1) (exactly as Draggable appears to be doing internally in the render method) still only sets the DOM attribute.

I can't for the love of everything sacred figure out how Draggable internally is able to set the CSS property. Nor what I should do to do the same thing.

Help, please?

Regards,
Morten

Link to comment
Share on other sites

Hello barklund and Welcome to the GreenSock Forum!

 

In order to animate SVG with GSAP you must animate the cx attribute of your <circle> element with the GSAP AttrPlugin :

 

See the Pen qrXaJM by jonathan (@jonathan) on CodePen

TweenMax.to(".circle", 2, {
  attr:{
    cx: 40
  }
});

You cant use force3D: true, since 3D transforms do not work on SVG 1.1.

 

Not sure about your Draggable question since i do not see any Draggable instances in your example.

 

Resources:

AttrPlugin: https://greensock.com/docs/#/HTML5/GSAP/Plugins/AttrPlugin/

 

:)

Link to comment
Share on other sites

Hi Jonathan,

In reality, my SVG child is a group (as is most often the case for any non-trivial SVG object). The codepen have been updated to reflect this:

See the Pen bqreKO by barklund (@barklund) on CodePen



Group elements have no x (or cx) attribute and can only be moved/transformed with transforms (either CSS or DOM).

In this case, what is the correct approach?

And regarding Draggable, it's merely a consequence of the above. I can create an example if you like, but it's besides the point right here. I have made a workaround locally, but I still believe the above is a bug.

Regards,
Morten

 

Link to comment
Share on other sites

Here's the dilemma: you can technically define the transform in two completely different places for an SVG element: in the CSS styles or on the "transform" attribute, but what if BOTH are defined (and different)? Some browsers prioritize the CSS, others prioritize the attribute, and some don't even support the CSS at all (like Microsoft browsers). 

 

The SVG spec itself clearly supports the "transform" attribute, and there are many programs that spit out SVG that indeed use that attribute. There are quite a few bugs related to the CSS-level transforms on SVGs, so in GSAP we use the "transform" attribute. Better support, fewer bugs. But in your case, Chrome is saying "wait, there are BOTH defined...gotta choose one to render, and we're gonna choose the CSS." Doh!

 

So it's not really a bug in GSAP at all; it's a logic dilemma and a browser behavior thing. 

 

I'd strongly recommend avoiding CSS transforms on SVG elements (for all the reasons I mentioned above). 

 

If you really need to define them in the CSS instead, you could set CSSPlugin.useSVGTransformAttr = false; so that GSAP tries to set things via CSS instead of the transform attribute, but that's not bulletproof because some browsers just don't support CSS or they've got bugs in its implementation. See what I mean? 

 

Is there a particular reason you must use CSS instead of the transform attribute? I'd definitely recommend just setting all transforms-related stuff through GSAP because it'll perform better, and you'll get cross-browser support. 

  • Like 2
Link to comment
Share on other sites

Just to throw my two little cents worth in:

 

There is something weird happening with that pen. You should be able to animate the 'circle' group x position. For some reason when the group class name is circle, the group doesn't move. The console is showing the transform matrix animating, but it doesn't move. If you use any other class name other than 'circle', the group does animate. I'm a bit confused by that behavior.  :blink:

 

BTW - Yes - you can tween a draggable element even after you've dragged it around.

 

Happy tweening.

:)

Link to comment
Share on other sites

Here's the dilemma: you can technically define the transform in two completely different places for an SVG element: in the CSS styles or on the "transform" attribute, but what if BOTH are defined (and different)? Some browsers prioritize the CSS, others prioritize the attribute, and some don't even support the CSS at all (like Microsoft browsers). 

I completely agree. I don't know what the browser should do either ;)

 

So it's not really a bug in GSAP at all; it's a logic dilemma and a browser behavior thing. 

 

I'd strongly recommend avoiding CSS transforms on SVG elements (for all the reasons I mentioned above). 

 

If you really need to define them in the CSS instead, you could set CSSPlugin.useSVGTransformAttr = false; so that GSAP tries to set things via CSS instead of the transform attribute, but that's not bulletproof because some browsers just don't support CSS or they've got bugs in its implementation. See what I mean? 

 

Is there a particular reason you must use CSS instead of the transform attribute? I'd definitely recommend just setting all transforms-related stuff through GSAP because it'll perform better, and you'll get cross-browser support. 

The only reason I have a css transform property on my element is because of GSAP's draggable. I'm currently trying to re-create my setup, but it clearly seems I need to do more that what I have in this simple example. Now adding Snap.svg and other stuff. The error is most likely between all the libs, but the result is that Draggable works on the css property and TweenMax works on the dom attribute. I'll try to demo it ;)

 

There is something weird happening with that pen. You should be able to animate the 'circle' group x position. For some reason when the group class name is circle, the group doesn't move. The console is showing the transform matrix animating, but it doesn't move. If you use any other class name other than 'circle', the group does animate. I'm a bit confused by that behavior.  :blink:

That's because of the transform property in the css on the .circle class. That's exactly the behaviour I wanted to illustrate.

 

BTW - Yes - you can tween a draggable element even after you've dragged it around.

 

Not in my particular setup ;)

Link to comment
Share on other sites

Ha! I need to get my eyes checked. Yeah - you're right. I clearly didn't read your entire question or look at your CSS. I was only looking at the JS panel. I see that .circle class in there now.  :rolleyes:

 

Though I'm still unclear why you can't tween after dragging?

Link to comment
Share on other sites

Hm, any chance you could provide an example that shows it not working with Draggable? I checked the codepens you provided and they seemed to work fine (once that CSS class was removed). Maybe I'm missing something? 

 

For the record, Draggable taps directly into TweenMax/CSSPlugin for the rendering, so I can't think of any reason why one would render to CSS and the other to the transform attribute. 

 

You are using the latest version(s), right?

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.
×