Jump to content
Search Community

Issue with SVG Vertical Text

Kenneth Evans test
Moderator Tag

Recommended Posts

I am new to GSAP so this issue may be owing to my ignorance.  I am trying to animate some items in a logo, including vertical text.  gsap.from doesn't work for the vertical text as shown in the CodePen.  I am using an SVG created in Inkscape.  I have removed most of the unnecessary things, but the text is still somewhat complicated.   Sorry.  I am unsure what is non-essential.

 

If you comment out the timeline calls in the Javascript, it displays correctly.

 

There is also a problem with the horizontal text.  It is not in the same position as it is with the timeline calls commented out (just the SVG image).

See the Pen NWqNxyb by KennethEvans (@KennethEvans) on CodePen

Link to comment
Share on other sites

Hey Kenneth and welcome to the GreenSock forums!
 

The tween is actually working as it should. It just seems like its not because you can't see the text (because it's white on white). If you change the vertical text color to another color you'll see what I mean :)  You attempting to set the transformOrigin places the white text in a different location than it otherwise would be. 

 

There are a lot of ways to fix the issue. Probably the best would be to remove the transforms applied to the SVGs in Inkscape. You can keep them in the same position, just have Inkscape use the actual coordinates instead of transforms. Learn how to do that here

 

Side note: you should try using GSAP 3's defaults and shortened ease form :) You could write the exact same JS that you currently have like this:

let timeline = gsap.timeline({defaults: {duration: 2, opacity: 0, ease: "none", transformOrigin: "50% 50%"}});
timeline.from("#green, #vertical, #horizontal", {stagger: 2});

Cool, right?

  • Like 1
Link to comment
Share on other sites

Thanks Zach, but the white text is not the problem.  It is on top of the green box.  And I would still have the problem if it weren't white.

 

I have simplified what I actually want to do.  I was using another ease and changed it to this for the example.  I appreciate, though, your information that there is a better way to do none.  And I guess I could just have left it off.

 

I need the transform, because I also want to translate and rotate.   However, taking it off fixes the problem.  But then rotate does nothing and also ease:Back.easeOut does nothing.  Possibly I need a different transform, but at the moment I don't know how to determine one.

 

BTW I have looked at x, y, and rotate before and after the tween.  They are the same, so I don't see what the transform is doing.  Also it didn't hurt the horizontal text.

 

I looked at the link for trying to fix it in Inkscape.  I will work on that; however, I would like to understand why it is not working as is.

 

I have a question about the CodePen.  If I change it on CodePen will it change in this topic, or is this a copy?  (It doesn't look like it is.)  I'm new to CodePen, too. 😉

 

Added later: I looked at the Inkscape fixes.  Those seem to be to remove a transform for a group (g element).  My g element doesn't have a transform.  I think I need to learn how to do it right in GSAP.

 

Thanks.

Link to comment
Share on other sites

Again, this is because of your SVG's structure, not an error in GSAP. GSAP should have full control over the transforms, which means that you should set all transforms that you have with GSAP. 

 

Here's a hastily done version that shows it working just fine with transforms set with GSAP:

See the Pen JjdXRBw?editors=0010 by GreenSock (@GreenSock) on CodePen

 

1 hour ago, Kenneth Evans said:

also ease:Back.easeOut does nothing

What do you mean? It animates the values past the target values and then to the target as seen in the ease visualizer. An opacity can't have a value more than 1 if that's what you're trying to do.

 

1 hour ago, Kenneth Evans said:

I would like to understand why it is not working as is.

Again, it's working, just not how you expect it to work. I'm guessing that the difference between your expectation and reality comes from how setting the SVG transform attribute doesn't actually change the reported size and placement of the SVG element which is what GSAP uses when it considers what the transform origin should be. 

 

1 hour ago, Kenneth Evans said:

If I change it on CodePen will it change in this topic, or is this a copy?  (It doesn't look like it is.)  I'm new to CodePen, too. 😉

Yes, if you're editing the same version. If you make changes we request that you click the "fork" button in the bottom right so that the changes are saved to a new version.

 

1 hour ago, Kenneth Evans said:

I looked at the Inkscape fixes.  Those seem to be to remove a transform for a group (g element).  My g element doesn't have a transform.  I think I need to learn how to do it right in GSAP.

Again, you need to remove the transforms from the SVG for it to work in a way that you expect :) There's no other way unless you do the math to compensate for the transforms you have applied which is definitely more work.

Link to comment
Share on other sites

Zach, thanks for the detailed reply.

 

Ok, I see the ease:Back.easeOut is changing the opacity in the example.  The better statement is that I can't see any effect, rather than it isn't working. 

 

I want it to bounce, and that would seem to require a transform of some sort (i.e changing y).

 

The problem is that it is a matrix transformation which has both a -90 degree rotation and a scale:

transform="matrix(0,-0.95087276,1.0516654,0,0,0)"

 

 So the question is how to determine transformOrigin to use in GSAP.  "50% 50%" is supposed to be the center of its bounding box, I believe.  (I haven't found transformOrigin in the docs.)  I don't see why "50% 50%" doesn't work.  The -90 degree rotation should not affect the center of rotation.  So how do you do the math to determine the percents that GSAP wants.  (I can do the math to figure out the scale, knowing it is a -90 deg rotation.  Actually it looks like sy = -.95087276 and sx = -1.0516654. )

 

The scale is near 1, so I would expect it to be "approximately" right with "50% 50%" though.  In reality, you don't see the text at all.  Also timeline.from() is supposed to return to its original state.  Why specifying a transformOrigin would affect its final state is not something I understand.

 

I also don't see why a transformOrgin would affect opacity one way or the other either (there is no transform), but empirically it doesn't work unless I remove it.

 

To be clear, I am not saying GSAP has an error.  I might say it is unclear to me how to use it in this case, however.  

 

Thanks.

Link to comment
Share on other sites

Ok, I found the doc:

https://greensock.com/docs/v2/Plugins/CSSPlugin

 

It says the default should be "50% 50%", so leaving it out should be the same as including it.  But it isn't. 

 

I changed the text to red and the opacity to 1 so I could possibly see where it actually is.  I haven't found any combination of  parameters where it is visible at all (except leaving out the transformOrigin).

 

So I don't understand what is happening.

 

BTW according to getParameter

"scaleX=" "0.9509"
"scaleY=" "1.0517"
"rotation=" "-90"

so I got the signs wrong. (Apparently rotation is in the clockwise direction, rather than what it usually is in math.)  I'm learning. 😎

Link to comment
Share on other sites

11 hours ago, Kenneth Evans said:

The problem is that it is a matrix transformation which has both a -90 degree rotation and a scale:

Again, we strongly suggest that you set all transforms related to animated elements using GSAP itself. 

 

11 hours ago, Kenneth Evans said:

The -90 degree rotation should not affect the center of rotation.  So how do you do the math to determine the percents that GSAP wants.  (I can do the math to figure out the scale, knowing it is a -90 deg rotation.  Actually it looks like sy = -.95087276 and sx = -1.0516654. )

GSAP calculates the transformOrigin using the element that you apply the transformOrigin to. In the case of your demo in the first post, that is the <text> container of the <tspan>. But since you have additional offset of the tspan, that throws the origin off from what you expect it to be because it's no longer the center of the text (which is what you it seems you are expecting it to be) because it is displaced. It would likely be best to remove the offset on the <tspan> so that the <text> is aligned with the <tspan> so that the transformOrigin on the <text> aligns with your expectations. Again, this is an issue caused by the setup of your SVG not being what you are expecting it to be. It is not a miscalculation of any sort. 

 

11 hours ago, Kenneth Evans said:

you don't see the text at all

This is because it's white on white or because it's positioned out of the viewport. GSAP is not hiding it.

 

11 hours ago, Kenneth Evans said:

I also don't see why a transformOrgin would affect opacity one way or the other either (there is no transform), but empirically it doesn't work unless I remove it.

transformOrigin does not affect the opacity in any way. It affects the transform that you have set on the element. If you just remove the transform but don't compensate for removing it by changing the position values, then it won't be aligned with where it currently is and will likely be positioned outside of the viewport or on white to where white on white is not visible. 

 

1 hour ago, Kenneth Evans said:

It says the default should be "50% 50%", so leaving it out should be the same as including it.  But it isn't.

I think the docs are incorrect there. @GreenSock can check me on that.

 

 

I highly suggest that you clean up your SVG: remove all transforms. Remove any offset that your <tspan> has. Then position them where you need them to be and make sure that Inkscape doesn't use transforms or offsets on the <tspan>. I'd offer to do it for you but apparently Inkscape doesn't work on Catalina at the moment.

 

Once the text is where you want it to be, set the transform origin using GSAP and and rotate it just like I did in the demo above. That will make it much more simple to animate your elements as you need. 

  • Like 1
Link to comment
Share on other sites

Zach,

 

Thanks for the detailed help.

 

The reason for using Inkscape is that it is easy to design and line things up there.  I am interested in animating SVG, so using what you get from the SVG file would be preferable.  Your method would work in simple cases, though.

 

I have determined the problem is that the vertical text has a negative x (y="88.710289" x="-57.960464").  I don't know why Inkscape did that nor why it works normally,  It looks like using transformationOrigin causes something to wake up and use that.

 

I can fix it by setting  y="73" x="76.5" (determined by trial and error).  I did it in both places.   It now works with GSAP.  But it doesn't work if I don't use any animation (comment out the timeline calls).

 

I will try experimenting with the tspan as you suggested, and try to figure out what is happening.  I don't mind taking things out of the SVG, but I don't want to have to change values like x and y.

 

Link to comment
Share on other sites

After more study:

 

The x and y values are what they are because the matrix is rotating -90 deg about the viewBox origin.  It needs a big swing to do this, so the bounding box starts at those values,  y="88.710289" x="-57.960464" in a viewBox that is 100 x 60.

 

After thinking about it I believe GSAP is, in fact, not handling matrices, and possibly any initially rotated elements, correctly.  The telling argument is that from() is not returning to the original values.

 

There is also the fact that if I use x and y values that work in GSAP, then they don't work outside of it.

 

There is no mention of matrices in the CSSPlugin doc.  They don't seem to have been thought about, or at least implemented.  I would guess that it works when transformOrigin is not specified because it leaves things alone in that case, and the SVG transform works as it should.

 

My conclusion (which I'm willing to change) is that GSAP doesn't play well with matrices, and the solution is to not use them.  In my case presumably the matrix could be replaced with a scale and a rotate.  I'm not sure how to get Inkscape to do this, but [also presumably] I could do the math and do it manually.

 

I would, of course, be happy if I am wrong, and there is a way to handle this situation in GSAP.

Link to comment
Share on other sites

5 hours ago, ZachSaucier said:
6 hours ago, Kenneth Evans said:

It says the default should be "50% 50%", so leaving it out should be the same as including it.  But it isn't.

I think the docs are incorrect there. @GreenSock can check me on that.

 

That should say that it only applies the HTML elements. SVG elements are have a default origin of 0 0.

 

49 minutes ago, Kenneth Evans said:

After thinking about it I believe GSAP is, in fact, not handling matrices, and possibly any initially rotated elements, correctly.  The telling argument is that from() is not returning to the original values.

 

Rotation is hard to get from a matrix because it's really scale and skew. That's why you should use gsap to set transforms so it can keep track of stuff like rotation.

 

54 minutes ago, Kenneth Evans said:

There is no mention of matrices in the CSSPlugin doc.  They don't seem to have been thought about, or at least implemented.  I would guess that it works when transformOrigin is not specified because it leaves things alone in that case, and the SVG transform works as it should.

 

You don't need to worry about matrices. Transforms and transform origin don't work the same in every browser. That's what gsap fixes. Check out this article.

https://css-tricks.com/svg-animation-on-css-transforms/

 

1 hour ago, Kenneth Evans said:

My conclusion (which I'm willing to change) is that GSAP doesn't play well with matrices, and the solution is to not use them.  In my case presumably the matrix could be replaced with a scale and a rotate.  I'm not sure how to get Inkscape to do this, but [also presumably] I could do the math and do it manually.

 

GSAP uses matrices for SVG, the problem is interpreting what the initial values for each component are supposed to be, like scale and rotation. It is best to remove transforms on elements that you plan to animate with gsap. Check out this SO question about ways to remove transforms.

https://stackoverflow.com/q/13329125/2760155

 

 

Link to comment
Share on other sites

@OSUBlake

 

That isn't the problem.  That article is about removing transforms on the g element.  Mine doesn't have a transform on the g element.

 

The problem is worse than I said before.  I had decided to just not use transformOrigin on the rotated text.  However, that makes the other problem more noticeable:  The horizontal text gets moved from its original position.  I modified the CodePen to:

  1. Have an if(true) around the timeline stuff to make it easy to see what happens with that compared to the SVG alone.
  2. I also removed the tspan stuff from the HTML.  It doesn't change the behavior but makes the HTML cleaner.

To see the difference, run it with true, then run it with false.  You can see the text jump.

 

We are sort of down to GSAP doesn't play well with SVG text.  In particular, from() doesn't return you to the original layout if you use transforms.

 

However, maybe the solution in the CodePen Zach showed is a way around it.  I'll look into that.

Link to comment
Share on other sites

22 minutes ago, Kenneth Evans said:

That isn't the problem.  That article is about removing transforms on the g element.  Mine doesn't have a transform on the g element.

 

It's not just about groups. But groups are you friend. It this what you are trying to do?

 

See the Pen f3d85f267b74cd5d65915accb5397b4e by osublake (@osublake) on CodePen

 

 

  • Like 3
Link to comment
Share on other sites

@OSUblake,

 

Yes, it looks like it.

 

Why not just do that on the text elements.  That is similar to what Zach did and what I have been working on.  Also, you only did rotation.  There is scale, and the horizontal ones have to be fixed, too.

 

I have been writing something to parse all the SVG elements and fix the text ones doing something like what you both did.  That requires extracting the rotation, scale, and translation from the matrix, which I can now do.  It got late.

 

So it looks positive it can be made to work.

 

Thanks.

Link to comment
Share on other sites

21 minutes ago, Kenneth Evans said:

Why not just do that on the text elements.

 

There might be a problem with how GSAP is calculating the position of SVG text. @GreenSock might want to check and confirm that it is working as intended.

 

I'll just say that SVG is a pretty complicated beast. For example, here's a post I made about how positioning works in SVG, and how <g> elements are treated differently by the browser.

https://greensock.com/forums/topic/13681-svg-gotchas/page/2/?tab=comments#comment-72060

 

Perhaps GSAP is doing the wrong type of calculation on text. I haven't tested, so it's just a theory. I do know that getting the bounds of svg text can be kind of quirky in some browsers. I'll wait for Jack to confirm.

 

  • Like 1
Link to comment
Share on other sites

After sleeping on it I had already decided to convert the text to paths in Inkscape.  This seems the most robust solution, does not involve kludges, and has the advantage that there are no fonts that may not be on the user's computer.

 

That was easy to do, and it seems to work.

 

Thanks for all the help.  I also learned some things. 😎

 

  • Like 1
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...