Jump to content
Search Community

Creating a loopable Carousel (without using a proxy)

Johnny 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



So this issue is related to http://forums.greensock.com/topic/8221-infinite-draggable/.


I'm trying to create a carousel that can loop. This was proving fine with a "placeholder" DOM element, because I can simply assign the placeholder DOM element with Draggable and do the loop magic within the update callbacks to the actual carousel container.


However, on iPad we have discovered that using this method causes the motion to noticeably stutter when grabbing the coords from the _gstransform object and passing them through via the onUpdate callback to the actual carousel container. But, if we pass the actual container of the carousel into Draggable.create instead of the placeholder DOM element - it immediately removes the stutter on iPad 2 and 3. I know you use requestAnimationFrame for this, so I'm not sure why this is the case.


So... I removed the placeholder element and passed the carousel DOM element to Draggable.create. I tried something like this instead where onUpdate is being called with both 'onThrowUpdate' and 'onDrag' and I catch the current X position and try to set the carousel container to the loop point.


Although, it seems the position I set is overwritten  on the next render cycle (which I guess would make sense) because it has no effect:


this.onUpdate = function( e ){
    var itemsX = this.$draggableEl[0]._gsTransform.x;  
    if (itemsX > 0 && this.loopDirection != -1)
        var tx = -this.$draggableEl.width() + itemsX + (this.itemMargin);
        this.loopDirection = -1;
        TweenMax.set( this.$draggableEl, {x: tx } );

Can I do this somehow without using a proxy or null object that passes the coords? Because it runs silky smooth on iPad by passing the actual DOM element to Draggable.create. Just need that loop functionality.


Anyways, thanks for an awesome library - and also for tweeting the McDonald's Myburger project. Draggable and throw props saved me on that project ;)




Link to comment
Share on other sites

Hi Johnny,


First, glad to know you worked on the My Burger project. I thoroughly enjoyed using it and also showcased it in a recent GSAP seminar. A perfect example of beautiful animation and interactivity in the post-Flash world. Congrats!




As for your performance issues, its really hard to diagnose from a few lines of code but here are some thoughts:


1: Draggable automatically sets force3d:true on the target, which iOS devices really benefit from. So perhaps in your version where you use the placeholder element you could try

TweenLite.set(container, {force3D:true})

2: in your loop, depending on how many elements you have, this operation here:


var tx = -this.$draggableEl.width() + itemsX + (this.itemMargin);
        this.loopDirection = -1;
        TweenMax.set( this.$draggableEl, {x: tx } );

Can actually be quite costly as you are using jQuery to read the width() and then TweenMax.set() reads and writes the x as well. We have run tests that show that doing sequential read/write/read/write operations (even on different properties of different elements)can be extremely slow as they force the entire page to run layout routines again.


The good news is we are about to release an update to GSAP (v1.12.0) that accounts for this with a new lazy render mode that batches all writes (renders) to the end of the tick cycle allowing for very impressive gains. 


When 1.12.0 you can try

TweenMax.set( this.$draggableEl, {x: tx, lazy:true } );

A full blog post with speed comparison tests and videos will explain how this works in great detail. Should be out in the next 24 hours. Attached is a pre-release version you can try.




let us know if you see any improvements using the code above.



  • Like 2
Link to comment
Share on other sites

Ahh yea - that was pretty dumb for me to use that in the example, shouldn't use jquery width on a render frame indeed. 


By any means, still seeing a performance difference for some reason. Quite odd. I will try to get a codepen together, in this case we were able fall back to native scrolling just for iPad.


Great that you're using Myburger in your seminar! I'll mail you our latest work in a couple weeks - it has tweenmax and three.js all over it :)


Thanks a lot!!

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