Jump to content
Search Community

I have a setInterval function in which I have many element positions being updated. Is there a way I can benefit from GSAP?

rotaercz test
Moderator Tag

Go to solution Solved by jamiejefferson,

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 have the following code and cachedSets is a list of elements.

 

    setInterval(function() {

 

        // more code here

 

        $.each( cachedSets, function(i, elem) { 

            elem.offset({ left: elem.offset().left+(goalX - elem.offset().left)/moveSpeed });

        });

 

    }, 22);

 

Is there a way to convert the above to GSAP?

Link to comment
Share on other sites

Hi

 

I'm having trouble imagining what that code does. Does goalX or moveSpeed update while that code is running? 

The best thing to do is create a simple CodePen demo as described here: http://greensock.com/forums/topic/9002-read-this-first-how-to-create-a-codepen-demo/

 

I'm guessing you can make a simple demo with only 3 simple divs that move around. 

 

Thanks

Link to comment
Share on other sites

goalX continuously updates, moveSpeed doesn't change. I'd like to share it when I'm done but at the moment I'd like to keep it private.  :mrgreen:

 

EDIT: I guess I feel secretive during development but you can actually see an example here on my old flash site. www.typographist.com (it's the tsunami wave menu. The new one is vertical though and it's not Flash.)

Link to comment
Share on other sites

Hello rotaercz,

 

Here is a GSAP equivalent of setInterval() and setTimeout() in GSAP that jamiejefferson posted awhile ago:

 

http://greensock.com/forums/topic/8424-clearinterval-equivalent/#entry32844

 

And another post in that same Topic by the mighty Carl, about delayedCall()

 

http://greensock.com/forums/topic/8424-clearinterval-equivalent/#entry32834

 

A link to the GSAP docs about delayedCall() :

 

http://greensock.com/docs/#/HTML5/GSAP/TweenLite/delayedCall/

 

:)

  • Like 2
Link to comment
Share on other sites

Hi,

 

I don't think you need a timeline element, in order to create an interval loop, delayedCall() can do that as well.

 

Keep in mind that a delayedCall will return a TweenLite object that will have an onComplete callback, which is the function you pass as the second argument. So you can use any method that works with TweenLite, like for example restart(), so your code will look like this:

var interval = TweenLite.delayedCall(1, function(){

  // stuff

  // after the stuff gets done, restart the timer
  interval.restart(true);

  // also you can use this code, it'll have the same result
  this.restart(true);

});

Rodrigo.

  • Like 2
Link to comment
Share on other sites

Ahh, I neglected that part, sorry.

 

Well, as you can use any TweenLite method you can pause() the delayed call. 

var interval = TweenLite.delayedCall(1, function(){

  // stuff

  // after the stuff gets done, restart the timer
  interval.restart(true);

  // also you can use this code, it'll have the same result
  this.restart(true);

});

// if it happens when clicking a button
var stopBtn = document.getElementById("stopButton");

stopBtn.onclick = function(){

  interval.pause();

};

As I said in the first post, with a delayedCall() you can use any method you can use with a TweenLite instance:

 

http://greensock.com/docs/#/HTML5/GSAP/TweenLite/

  • Like 2
Link to comment
Share on other sites

Just tested it. It's very smooth.

 

I have a few more questions in no particular order.

 

1. Is it possible to do something like this?

 

    interval.kill();? 

 

2. Is there a way to see the fps?

 
3. Is it better to do it this way?
 
        TweenLite.to(elem, 0, { left: elem.offset().left+(goalX - elem.offset().left)/moveSpeed });
 
    Compared to?
 
        elem.offset({ left: elem.offset().left+(goalX - elem.offset().left)/moveSpeed });
 
    Or is there no difference here?

4. How do you highlight your code like that?

5. Sorry for asking so many questions. I'm just psyched about GSAP!

Link to comment
Share on other sites

1. Is it possible to do something like this?

 

    interval.kill();? 

 

Absolutely, every TweenLite method will work with a delayedCall.

 

 

2. Is there a way to see the fps?

 

Mhh, not that I'm aware of. Chrome dev tools has a fps meter, but is not completely reliable. In general measuring the fps is not very reliable (Jack has stated that several times and I've also read the same elsewhere). In order to see how things are going in terms of performance, you could check this video by Paul Irish:

 

 

 

3. Is it better to do it this way?

 

        TweenLite.to(elem, 0, { left: elem.offset().left+(goalX - elem.offset().left)/moveSpeed });

 

    Compared to?

 

        elem.offset({ left: elem.offset().left+(goalX - elem.offset().left)/moveSpeed });

 

    Or is there no difference here?

 

Absolutely, GSAP is way better than using offset. Mainly because GSAP has a very smart way of working with your animations. First you can pass your animation to the GPU in order to get better performance. Also if you use transforms like x or y instead of left and top, GSAP passes the transforms into a 3D matrix, so it goes automatically to the GPU, for better performance. GSAP also can work and keep stuff in complete sync if for some reason the CPU gets bogged. Lets say that while you're testing an animation you're opening another app, that process consumes a lot of CPU for half a second. Most animation tools will have a nightmare trying to keep things in sync and you'll basically loose that half second, but not with GSAP. The engine will detect that and keep things right on track so the animation happens in the screen and the user doesn't have to experience a jumpy animation. Those among others are very good reasons to stick with GSAP, even for the most simple animations.

 

 

4. How do you highlight your code like that?

 

In the second icons line in the editor's tool bar you'll see an icon like this </> that brings a popup when you can type/paste your code and select the specific code you're using (HTML, CSS, JS, PHP and others).

 

 

5. Sorry for asking so many questions. I'm just psyched about GSAP!

 

 

It's OK, we're here to answer, welcome aboard.

 

Happy Tweening!!

  • Like 2
Link to comment
Share on other sites

  • Solution

By the way, I have a feeling I've discussed this in another thread somewhere, but the reason I recommend a Timeline as a good analog for setInterval (instead of delayedCall) is that it prevents drifting over time. e.g.
 
Let's say our interval function takes a variable time between 0.2s and 0.4s to run, and the interval time is 1 second:
 
with Timeline or setInterval ( |** = function running ):

0                 1                 2                 3                 4
------------------|****
-------------|******-----------|********---------|

 
no matter how long the function is taking, it doesn't affect the fact that you've asked it to be called once per second. The exact point that it is called can be slightly variable (probably off by a few ms based on the CPU time given to the browser and JavaScript), however the general idea is that in 10 000s the function should be called 10 000 times.

with recursive delayedCall or setTimout:
 
0                 1                 2                 3                 4                 5
------------------|****-----------------|******-----------------|********-----------------|

 
as you can see, by running the function, then saying "ok do this again in 1 second", there is a lot of room for time drift to occur. My example is exaggerated for effect, but this still occurs at smaller scales.
 
 
Now, in your Timeline you had the call duration as 0.02; that only gives 20ms for both the function to run and any browser layout/painting operations to occur before that function is called again. I imagine that Chrome is just not keeping up with all of that.
 
When you change it to the delayedCall then restart version, you've now got infinite time for the function and browser layout/paints, then patiently wait for 20ms and do it again.
 
Up to you if this drift is important to your animation or not. I would however recommend this improvement

var offset = elem.offset();
TweenLite.set(elem, { left: offset.left + (goalX - offset.left) / moveSpeed });

as calling .offset() one less time per frame could improve performance, and using TweenLite to set the values allows them to be synchronised with the GSAP ticker, so you don't end up pushing more layout adjustments than the browser can keep up with.
 
The next recommendation would be to consider using x/y transforms as they may improve performance by reducing layout thrashing (especially if you have lots of elements) and offloading some rendering to the GPU.

var offset = elem._gsTransform || 0; // || 0 just in case _gsTransform hasn't been set yet
TweenLite.set(elem, { x: offset.x + (goalX - offset.x) / moveSpeed });
  • Like 4
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...