Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
xmark

How to apply a draggable item within a scroller

Recommended Posts

Hi All,

 

I have a site where I have a horizontally styles un-ordered list (<ul>), my site dynamically adds items to the list based on user interactions. For each new item in the list, I have applied a Draggable.create call to make them draggable in the Y axis (vertical), I also apply an animation Tween on the item so it bounces into place. This all works fine!

 

Im using this code for that:

//add to the UL
$(".cardList").prepend(newDiv);

//animate the card into place
TweenLite.from(newDiv, 0.5, { y: -250, ease: Elastic.easeOut });

Draggable.create(newDiv, {
            type: "y",
            onDrag: function () {
                //my code...
            },
            
            onDragEnd: function () {
                //my code...
            }
        });

However, when there are a lot of items in the list, I would like to scroll the list horizontally, so I wrapped up my list into a DIV container and called:

var scroller = new Draggable("#cardsContainer", { type: "scrollLeft", edgeResistance: 1.0 });

...which 'kind of' works. I currently have 2 issues:

 

1) I can add a new item into the list and I can see that the scrollbar on the scroller increases, but from time to time, the scroller "snaps back" prematurely, so effectively you can never scroll to the end of the list. It simply stops scrolling, it looks like the animation I am using to add the new items to the list could have some effect on the calculation of the width of the scroller?

 

2) When I click and drag the scroller (when it does work), the items in the list which can scroll vertically move slightly up/down, can I have some kind of check to see if the user is scrolling left/right and NOT enable the vertical scroller based on some threshold?

 

I hope that makes sense

Link to comment
Share on other sites

Update #1

 

I think I have found a bug in the calibrate() function.

 

When I added items to my UL and I debugged why my scroller was not behaving correctly, I found that, on line 655:

 

if (widthMatches && element.clientHeight === elementHeight && content.offsetHeight === contentHeight && !force) {
return; //no need to recalculate things if the width and height haven't changed.
}
 
was always returning. Meaning that the width/height were not getting re calculated, so I commented this out and now it works. But this is obviously an issue with the framework.
 
Can someone please help me with this?
Link to comment
Share on other sites

Hi and welcome to the GreenSock forums.

 

For the first question I'm a little lost. You could try killing the Draggable instance and creating a new one, like that this new instance will have the updated dimensions of the target element:

var scroller = new Draggable("#cardsContainer", { type: "scrollLeft", edgeResistance: 1.0 });
//add the following code in the function that adds the new cards
//first kill the original instance
scroller.kill();

//then create a new one with the new dimensions
Draggable.create("#cardsContainer",
{
  type:"scrollLeft"
});

Draggable has a lockAxis feature that... well allows you to lock the drag axis based on the direction the user is currently dragging. Is a simple boolean:

Draggable.create(target,
{
  type:"y",
  lockAxis:true
  //rest of your code
});

Also is very important and useful to see reduced samples of the issues users report, so please take a look at the following post and fork the base codepen with the Draggable tool to recreate the issue you're having, it'll help us to pinpoint the problem a lot faster:

 

http://forums.greensock.com/topic/9002-read-this-first-how-to-create-a-codepen-demo/

 

Rodrigo.

  • Like 2
Link to comment
Share on other sites

xmark, I'd echo Rodrigo's request for a reduced test case that demonstrates the issue - a codepen is ideal. I'd really like to see what's going on. I can't figure out why the browser reports the element's width and heigh are unchanged when that isn't true. 

 

Also, in the mean time, you could call yourDraggable.scrollProxy.calibrate(true) anytime to force that calibration, but beware that there's a bit of a performance penalty (hence the conditional logic that skips it when it seems unnecessary). 

  • Like 1
Link to comment
Share on other sites

Yep, the calibrate() method solves it.

 

See the Pen KosCB by rhernando (@rhernando) on CodePen

 

Jack in terms of performance, what's better, using calibrate() or kill() the instance and create a new one?. Does calibrate() applies for any type of Draggable instance?

 

Rodrigo.

Link to comment
Share on other sites

Hi All,

 

Thanks for the help so far, I will try the calibrate() method for now, but another issue is that when I try to fork the codepen, I cant reference draggable since I can only add 1 JS reference with my codepen account, unless Im missing something?

 

Fixed it, sorry dont know what went wrong there!

 

See this:

See the Pen lLEed by markmacumber (@markmacumber) on CodePen

 

Load it up, then click Add Item a few times, then scroll over to the right so that your scroll bar moves, then add more items and you can replicate the bug.

 

Perhaps it has something to do with how Im adding a LI to my list? (using the prepend() method?)

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