Jump to content
Search Community
Danik test
Moderator Tag

Go to solution Solved by Robert Longson,

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

Hello everyone,

 

I would like to start by apologising for the oh so abstract title, my questions vary quite a bit.

 

I recently began working with SVG animations, started with SMIL, continued to Velocity.js, and then found out about GSAP and its great browser support - so here I am. Bearing this in mind, while looking at my Codepen if you guys find anything I did wrong or simply something you would have done differently be it in the SVG, or the GSAP implementation please do not hesitate to mention it.

 

So in the following Codepen that I am currently working on I ran into a few issues:

 

 

 

1. On Firefox the cup sections fill up and then return to their original state, for those familiar with SMIL it had the option of fill="freeze" in its animate which would stop the animation at its end state. I am looking for something similar in GSAP - or perhaps something else.

 

2. On Firefox one of the gear does a proper rotation around the center transform-origin while two of the gears decided to do their own thing.

 

3. In Internet Explorer, the cup does not even fill up. It doesn't seem to be anything wrong with my linear gradient as the inside of the gears does fill up but has a lower opacity than it should.

 

4. I ended up solving this with adding a negative delay, but what would be the proper way of starting an animation while another one is still in progress in GSAP? Would it be making a new timeline? (I also solved the issue of infinite repeat by creating a new timeline - is this the right approach?)

 

5. And a quickie - which combination of TweenLite + extras would I need to maintain this at minimal file size?

 

 

Any help would be greatly appreciated.

 

 

Thanks in advance!

See the Pen WxJQQr?editors=1010 by anon (@anon) on CodePen

Link to comment
Share on other sites

Welcome to the forums (and GSAP) :)

 

1) This appears to be a bug in Firefox that's completely unrelated to GSAP. Try for yourself - just open DEV tools and plug in your end values of y1="0%" and y2="0%" and you'll see that Firefox doesn't render the fill at all, but if you change y1 to even "0.001%", it renders perfectly. Weird, I know. GSAP is doing exactly what you're asking it to do (the values are correct), but Firefox is spoiling the party. The solution is to just change your tween value to 0.001% or something like that instead of 0%. 

 

Also, to be clear, you don't have to set any special mode (like fill="freeze" in SMIL) to keep its end state. It never tries to revert things unless you specifically tell it to yoyo or something. Another thing that sets GSAP apart is that you don't have to specifically declare the beginning values as a part of the animation - it can just figure out whatever they are at that point dynamically which makes things much easier for developers (sometimes you don't know the starting values, as they'll depend on other things that could be user-initiated).

 

2) Are you saying that you don't see the gears rotating around their centers in Firefox? I can't seem to replicate that. However, I noticed that you didn't set the transformOrigin properly - it's supposed to have 2 values (one for horizontal, the other vertical). "center center" instead of just "center". But even without that change, I saw the gears rotating perfectly around their centers in Firefox so I'm a bit confused. I feel like I must be missing something. Are you on Windows or Mac? What version of Firefox? 

 

3) This one is a bit baffling, but it definitely looks like yet another browser bug that's causing things not to render correctly. You can use dev tools to verify that GSAP is doing exactly what you asked it to do, but IE/Edge isn't rendering it properly. You can even get rid of GSAP and change the values for yourself and see the same behavior. I'm not aware of a way around this yet. If anyone has good ideas, please let me know. 

 

GSAP does its best to work around browser inconsistencies, but it can only do so much. Some things are simply impossible due to browser bugs. Frustrating, I know. Have you thought about using a clipping path or mask to get the same effect? Perhaps avoid linearGradient elements. 

 

4) I would strongly recommend reading/watching these: http://greensock.com/sequence-video and http://greensock.com/position-parameter. I prefer modularizing my code into clearly-named functions that spit back 1 timeline each, and then I nest those into a master timeline and have total control over where things are placed, how much overlap (or gap) there is between them, etc. That way, when you edit a modular chunk, it just flows through to everything else and you don't have to mess with a bunch of delays, etc. Once you grasp this concept, it can completely revolutionize your animation workflow. Carl is going to talk about this technique at the CSS Summit in a couple of weeks :)

 

5) You might want to read http://greensock.com/kilobyte-conundrum/. Typically TweenMax is ideal, especially since it's so well-cached in the wild. But you can include just TweenLite, CSSPlugin, and TimelineLite (or TimelineMax) if you prefer. I doubt you'd really see much of a real-world difference in load times. 

 

Once you get over the learning curve (which really isn't terribly steep), I think you'll find yourself really enjoying the tools even more than the other tech you've tried. 

 

Happy tweening!

  • Like 2
Link to comment
Share on other sites

Hey,

 

Thanks for the reply.

 

I am definitely getting the hang of it as I go here.

 

I took a look at the videos, but there was no mention on how to sequence a tween during a previous tween that is on infinite loop, was I right to create new timelines?

 

I ended up solving my IE issue after hours of trying.. for some reason if the two stop colors are the same then it doesn't work but as soon as I switched the second stop color to anything else it seemed to do the trick (along with some minor tweaking of y %).

 

Firefox is still being a pain though... I did what you suggested and added values to the y tweens, but it still seems to do the same thing.

 

Also I was using Firefox 35 on Windows 10 - ended up upgrading to the newest 47 version which didn't change a thing. I see the big gear rotating properly around its center but the two smaller ones do a 360 around what seems to be 0,0. Does it work properly on yours? Maybe something on my end is just messed up.

Link to comment
Share on other sites

Yeah, if you've got an infinitely-repeating tween in a timeline and you're trying to do some sort of relative positioning, that's gonna be tough because that tween literally takes almost forever to finish. You can definitely work around that by simply using a variable or use absolute values or use the recent() method that spits back the most recently-added child. So if you wanted to tweens to overlap by 1 second, here's some pseudo code:

tl.to("#id", 2, {repeat:-1});
tl.to("#otherID", 3, {...}, 1); //absolute value
tl.to("#otherID", 3, {...}, tl.recent().startTime() + tl.recent().duration() - 1); //using recent()
var time = 0; //variable for tracking insertion point
time += 2; //after inserting each tween, add its duration to the time
tl.to("#otherID", 3, {...}, time - 1); 

So there are 3 different ways to handle it. But frankly, I'm the biggest fan of using the nested timelines like you mentioned because I think it affords even more flexibility and it keeps your code more modularized and easy to read. 

 

Glad you got the IE stuff solved. Browsers are still a little weird these days about little SVG quirks like that. 

 

I was looking at Firefox 47.0.1 on a Mac. All the gears rotated around their centers. Did you make sure you were setting transformOrigin:"50% 50%" or "center center"? It looked like you were defining only one part of the value, like "center". Not sure that'll solve anything for you, but it's worth a try. Like I said, things looked fine on my system. 

  • Like 1
Link to comment
Share on other sites

  • Solution

1. When y1=y2 the gradient vector length is 0 (because for your gradients x1=x2). The SVG specifiation says this:

 

 

If ‘x1’ = ‘x2’ and ‘y1’ = ‘y2’, then the area to be painted will be painted as a single color using the color and opacity of the last gradient stop.

 

So what's your last gradient stop? It's this:

<stop offset="1%"  stop-opacity="0" stop-color="red" />

0 opacity means no drawing of anything so no Firefox bug there.

 

2. As for the rotation origin. The rotation box is the view-box and not the fill-box per the specification

 

Chrome gets this wrong and uses the fill-box but Firefox does not. Given a different box size the placement of the centre of that box can be different.

  • Like 3
Link to comment
Share on other sites

Hey Robert,

 

Thanks for the info, I managed to fix the stop-color fill thanks to you.

 

As for the rotation I am still quite confused.. maybe I am missing something important.

 

Do I apply transform-box:fill-box; in my CSS to the path I am trying to get the trasform-origin of? to the whole SVG? Something else?

 

Also - what doesn't make sense to me the most is that one of the gears is properly rotating around its center, all gears have the same animation, and practically the same code. Why would you reckon that one works perfectly yet the others do not?

 

 

Cheers!

Link to comment
Share on other sites

I don't think any browsers currently support the CSS transform-box property. Firefox has a complete implementation of transform-box but it's hidden behind the svg.transform-box.enabled pref which is off by default. You can enable the pref by typing about:config in the Firefox address bar and then typing in some of the pref text.

 

Since Chrome's implementation of transform-origin does not match the appropriate specification the Firefox implementors don't know whether the specification will change to match Chrome or whether Chrome will change to match the specification.Once that's decided we'll match whatever the specification says and enable our transform-box code.

 

As to your paths, I assume one of them is drawn centred on the viewBox centre so that rotates about itself (for that object the viewBox centre and fill-box centre coincide), the others are not drawn at the centre of the viewBox. Of course each path is roughly round so its fill-box centre is the centre of the shape which is why they rotate round their individual origins in Chrome.

 

The fill-box centre is the centre of the shape's bounding box, the view-box centre is the centre as defined by the viewBox attribute on the nearest ancestor <svg> element.

  • Like 2
Link to comment
Share on other sites

So the only way to make an object rotate around its own center is to match the object's center (fill-box) to that of the SVG's center (viewBox)? Meaning that you can not have an object not in the center of the SVG and be able to achieve a rotation around the object's center until the transform-box property becomes readily available?

 

My object's fill-box center does not match the SVG's viewBox center... yet it is rotating around its own center in both Chrome and Firefox, while the other two objects are identical and behave differently.

 

I can't even use exact values for the transform-origin since if I match it to Firefox then both chrome and IE will not work properly.

 

If I change the viewBox and move the center then I can only ever achieve the rotation on one object according to this, while I have three.

 

Am I understanding this correctly? Is there a workaround?

 

Please take a look at the Codepen if you have a minute and see that the object is not centered as you assumed (unless I am wrong here too)

 

See the Pen WxJQQr by anon (@anon) on CodePen

 

 

Thank you.

Link to comment
Share on other sites

You can nest svg elements and therefore have separate viewboxes.

 

<svg>

   <svg viewBox="<something>">

       <path/>

   </svg>

   <svg viewBox="<something else>">

       <path/>

   </svg>

   <svg viewBox="<something else again>">

       <path/>

   </svg>

</svg>

  • Like 6
Link to comment
Share on other sites

  • 2 weeks later...

Hey guys,

 

I ran into another small problem.

 

I am now trying to add a restart button which works.. but there are a couple of weird glitches. Since there are multiple timelines nested it seems to record the state of one of them and reverts to in some parts instead of to the beginning.

 

I thought that honoring the delay on the restart would be a fix.

 

Is there a way to restart a whole function instead of each timeline separately?

 

I tried a few other ways as a workaround the infinite repeat + starting the next timeline (as stated by Jack above)  but none of them worked properly / would it even matter in this scenario?.

 

Suggestions?

 

I updated the CodePen to this:

 

See the Pen LkrpYL by anon (@anon) on CodePen

 

 

Cheers.

Link to comment
Share on other sites

Hi Danik,

 

In the future it would help if you could reduce the demo to have as few tweens / timelines as possible to replicate the issue so that there is much less code to sift through. Also, please explain which animations aren't working. After watching a few times it seems the cup's rotation was the issue.

 

The solution is to use Jack's solution of nesting each timeline in a parent timeline. This way you don't have to restart each one individually.

The issue had to do with the fact that you are rotating the cup in multiple timelines at different times to different values.

When you restart(true) to honor delays, the playhead immediately goes back to time(0) of those timeline but then honors the delay. I believe that immediately forcing the playhead to time(0) on these timelines is what caused the cup to stay rotated at 12 when the animation restarted.

 

To implement Jack's solution you would remove the delay from each timeline and add them to a parent like this:

 

main.add(headTimeLine1)
      .add(headTimeLine2, 3.5)
      .add(headTimeLine3, 4.5)
      .add(headTimeLine4, 5.5)

demo: http://codepen.io/GreenSock/pen/jAXAoA  From what I understand of your animation it appears to be working.

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