Jump to content
Search Community

Multiple Timelines That Update the Same Property

Donna 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'm loving the GSAP library so far. Nice work! The problem I've just come up against is in determining the best way to structure my tweens and timelines given what I want to do.

 

Essentially, I have a table which contains rows that are not all visible. After pausing for 5 seconds, the table will start scrolling until it reaches the bottom, at which point it will wait another 5 seconds before taking 2 seconds to scroll back to the top. This is achieved by simply altering the top margin, and uses two tweens that are added to the same timeline. It works perfectly.

 

The problem is that I have added event handlers so that a user can use their mouse or finger to swipe the table up or down. When it does so, the main timeline will be paused and a new timeline gets created to handle the swipe. This will, of course, put the main timeline out of sync once it resumes, and the table will jump when the main timeline resumes. I want it to continue scrolling from its current position, not from the position in the main timeline.

 

I thought to use the progress method to set the main timeline to the appropriate spot by dividing the top margin by the total scroll height, but the position still jumps when the main timelines resumes. I'm assuming the reason it doesn't work is because this calculation of progress doesn't account for the second tween that is responsible for scrolling back to the top. However, even if i remove the second tween, it still doesn't work.

 

Here's a CodePen to illustrate - 

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

 

I'm wondering if there is a better way for me to structure this (perhaps using the same timeline for all tweens?) that would prevent the table from jumping?

 

Thx.

  • Like 1
Link to comment
Share on other sites

Hi Donna and welcome to the GreenSock forums.

 

I believe that the best choice for this type of app would be GSAP's ScrollTo Plugin:

 

http://api.greensock.com/js/com/greensock/plugins/ScrollToPlugin.html

 

The reason is that the ScrollTo Plugin has two neat features.

 

First if you want to scroll that element to it's bottom using the string "max". Also lets say that later that the element's children height will vary dynamically, you don't need any math at all, just kill the tween and create it again and the plugin does all the job for you. The syntax is very straight forward:

// this instance will scroll the element to the bottom
TweenLite.to("#elementID", time,
{
  scrollTo:
  {
    y:"max"
  }
});

Second it has an autokill feature, which basically kills the animation if an external event changed the element's scroll, for example mouse or touch event in this case.

 

Finally you could check GSAP Draggable tool as well, since it works with mouse and touch events. Also it can be used to scroll content as well and with the ThrowProps Plugin in the mix you get a sweet kinetic motion and deceleration. Check the last example here:

 

http://www.greensock.com/draggable/

 

Draggable docs:

 

http://api.greensock.com/js/com/greensock/utils/Draggable.html

 

Rodrigo.

Link to comment
Share on other sites

Hi,

 

I've refactored my code to use both the Draggable and ScrollTo plugins, but I'm still having the same results as I did with my previous code. Namely, if I swipe to the middle of the table with my mouse, the tween will scroll beyond the bounds that I have set for it. I'd thought the autokill feature would prevent that, but that doesn't seem to be the case.

Here's my latest CodePen - 

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

 

Any thoughts?

Thx.

Link to comment
Share on other sites

In order for Draggable to do its magic, it has to create a special scrollProxy object internally that basically wraps the content in a <div> and applies transforms when necessary in order to do the overscolling (browsers don’t let you scroll past the end – we’re faking it with x/y transforms). So technically there are two different objects in play here in that example – the original <div> that has a scrollTo tween, and then the scrollProxy object that would have the throwProps tween applied to it (and that Draggable is editing).

 

Here’s the solution: 

http://codepen.io/GreenSock/pen/f4ffb4d679facd0251e806827f7cbbcf/?editors=001

 

Is that what you're looking for? 

  • Like 2
Link to comment
Share on other sites

Hello Donna,

 

You could try to use the set() method to apply the overflow:hidden after it creates the Draggable and ScrollProxy

TweenLite.set("#scroll-body",{"overflow":"hidden"});

Or you could declare !important on your #scroll-body in your style sheet:

#scroll-body {
    overflow: hidden !important;
}

!Important tells the browser to overide the inline styles.. in this case overflow-y is set to auto inlne on the #scroll-body div. So adding !important will override the inline style on the tag.

 

**Just remember that you should use !important with caution, and as a last resort.

 

Hope this helps! :)

  • Like 1
Link to comment
Share on other sites

 

Hi,

 

Have you tried overflow-y:hidden in the stylesheet?

element
{
  overflow-Y:hidden;
}

Yes, I have. It's getting overridden by something in the GSAP libraries. I'd prefer to avoid the use of the !important attribute, but I was just wondering if there was a better way (a configuration parameter that I may have missed)?

Link to comment
Share on other sites

Hello Donna,

 

You could declare !important on your #scroll-body:

#scroll-body {
  overflow: hidden !important;
}

!Important tells the browser to overide the inline styles.. in this case overflow-y is set to auto inlne on the #scroll-body div

 

**Just beware that you should use !important with caution, due to it being able to override styles inline on the tag.

 

Or you could try to use the set() method to apply the overflow:hidden after it creates the Draggable and ScrollProxy

TweenLite.set("#scroll-body",{"overflow":"hidden"});

Hope this helps! :)

Thanks. Was hoping there was a config parameter I could use as I'm not a big fan of !important or putting CSS in the Javascript, but if not then I'll just have to suck it up. :P Cheers!

Link to comment
Share on other sites

Mhh I believe Draggable set's the particular direction overflow (x or y) as visible in the element's inline style.

 

Two options. First, as Jonathan pointed create a set() instance to override the style created by Draggable:

TweenLite.set("#scroll-body",{overflowY:"hidden"});

Second, use a set() instance to pass a clearProps to the element, in order to remove the overflow-y inline style:

TweenLite.set("#scroll-body", {clearProps:"overflowY"});

As for the onComplete and onReverseComplete issue, is just a scope thing. Turns out that you're using the delayed call method, but this method lives inside a TweenLite instance, so in there this refers to that particular TweenLite instance and not the ScrollTo Plugin instance. If you change it to this, it works:

TweenLite.delayedCall(5, function()
{
  scrollToBottom.timeScale(2.5).reverse();
});

Finally for the onReverseComplete delayed call, you have this:

TweenLite.delayedCall(self.interactivityTimeout, function()
{
  this.timeScale(1).play();
}

This self.interactivityTimeout is undefined, better set it up in a variable and the pass it when is needed.

 

Rodrigo.

  • Like 1
Link to comment
Share on other sites

Oops. Forgot to change that variable when pasting it in from my code. Your changes worked perfectly though. Thanks again for the excellent support on this forum!

 

Cheers.

  • Like 1
Link to comment
Share on other sites

You knew I'd be back.  ;)

 

Thanks to the replies from this thread, I've got my table to scroll to the bottom continuously and to support swipe - http://goo.gl/wvE60x

 

I'm now working on doing a similar thing, but with a scroll transition that shows a "page" of content at a time. So in the previous CodePen, at first rows 1-9 are visible. I then want to show rows 10-18, pause, and so on until the bottom is reached. Will this require me to create multiple tweens? Or can I somehow manipulate the configuration of the existing tween? Please keep in mind this is a very simple example. In Production we may have 1000 rows in a table. Just looking for some guidance as to the best approach to take.

Thx.

Link to comment
Share on other sites

I believe that the best approach would be create a timeline and determinate dynamically the height of every group of rows you want to show (1-9; 10-18; 19-27, etc) and for each of those groups add a scrollTo instance to tween that specific amount, pause the timeline and then resume it. Then using an onComplete callback in the timeline you can go backwards. Also I'd advice to add labels to each instance, this can come in very handy if you need to modify something later in the timeline or if for some reason you need to scrub the timeline to a specific position.

Link to comment
Share on other sites

I actually ended up using the onUpdate function to check to see if the content had scrolled the height of the viewable area (i.e. a "page"). If it had, I paused the tween, calculated a new position at which to pause the tween again, and then resumed auto-scrolling after a brief pause.

 

It works very well. As usual though, I have another problem that I haven't been able to solve. It once again has to do with the position at which the tween resumes scrolling after it has been swiped. Here's my CodePen - 

See the Pen lLpCg by donnapep (@donnapep) on CodePen

 

If I let it auto-scroll twice until row 19 is showing at the top, and then I swipe it back to the very top, I would expect that when scrolling resumes, it would resume scrolling a page at a time; instead it scrolls to the very bottom. I'm not sure why it's doing that since I'm recalculating the progress in the onRelease event. I must be calculating this incorrectly?

 

Any insights into this particular problem?

 

Thx!

Link to comment
Share on other sites

I'm such a fool. I just realized that I need to reset pauseHeight after a swipe. Works great now!

 

We purchased the Business Green plan last week so that we can use the throwProps plugin. It makes it so much smoother. This is going to look great on customers' digital signage, which is where we plan to use it.

 

I've also packaged this functionality up into a jQuery plugin and I will be putting it on Github for whoever wants to use it. 

 

Cheers!

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