Jump to content
GreenSock

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

Paging

Recommended Posts

Hi,

 

I'm having high hopes of being able to replace other touch/scroll libraries such as iScroll or FTScroller (both being good projects but sorely lacking in certain areas) with the Draggable and ThrowProps plugins.

 

So far, the only thing I'm missing from GSAP is the possibility to limit the snap to the closest item, thus being able to implement proper "paging". FTScroller has a "strict" property to achieve this behaviour and these examples give a good explanation of the difference:

 

http://ftlabs.github.io/ftscroller/examples/horizontalpaged.html

http://ftlabs.github.io/ftscroller/examples/horizontalpaged-strict.html

 

Except from updating the bounds and snap values after each "page" switch, I can't seem to find a way to implement this behaviour using the current API. Any chances of an implementation of this type of functionality?

 

 

 

Link to post
Share on other sites

I'm not sure if this is exactly what you need, but Rodrigo has a

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

of Draggable slides. It has a bit extra in there for the animations triggered on each page, but it might give you some idea of how you could achieve this with the current Draggable API.

 

The discussion that led to it is here.

Link to post
Share on other sites

If you mean something to avoid multiple slides moving on hard throws, yep the codepen has that in place.

 

Although Jamie is being quite humble about it ;), since He's the one that came up with a solution for that particular issue as you can see in this post:

 

http://forums.greensock.com/topic/8349-get-throwprops-end-value-before-snap-triggers/

 

And this codepen:

 

See the Pen FnKba by jamiejefferson (@jamiejefferson) on CodePen

  • Like 1
Link to post
Share on other sites

Nice, thanks! It's a bit different from the solution I came up with that simply updates the bounds after each throwComplete:

 

See the Pen dAFzG by membla (@membla) on CodePen

 

To my solution's advantage it does honor the edgeResistance setting but we both share the same issue I could not come up with a good way of adressing:

 

Both solutions lacks support for "fast-swiping" between slides, meaning that another "throw" before the first "throw" has finished would actually make you jump two slides. If you compare to how for example iScroll and native iOS handles this the limitation becomes apparent.

 

In any case - as of now I think using draggable and throwprops is the best solution for achieving this functionality currently available but it would be really cool, and certainly attractive for other developers as well (judging by the popularity of iScroll etc.) to implement more of this functionality in the Draggable/Throwprops plugins.

Link to post
Share on other sites

Actually Jamie's code does have a way to prevent a new swipe while there's another happening:

Draggable.create(div1,
{
	type:'left',
	throwProps:true,
	maxDuration:1,
  resistance: 10000,
	snap: {
    left: function(endValue) {
      //if there's another animation in place, snap is true, so the element will be thrown but it won't advance to the next snap point
      if (!snapping) {
        snapping = true;
        var lastEndValue = snapPoints[snapIndex];
        if (endValue > lastEndValue+56 && snapIndex < snapPoints.length-1) {
          snapIndex++;
        } else if (endValue < lastEndValue-56 && snapIndex > 0) {
          snapIndex--;
        }
      }
      return snapPoints[snapIndex];
    }
  },
	onDragStart:function() {
    snapping = false;
  },
	onDragEnd:function() {
    snapping = false;
		div1.html('End value: ' + this.endX);
	}
});

The same logic is applied in the Greensock Swipe Slides codepen, but with a different code:

var containerDraggable = Draggable.create($("#slide-container"),
{
	type:'left',
	throwProps:true,
	maxDuration:1.25,
	minDuration:.75,
	edgeResistance:.8,
	onDragStart:function()
	{
		dragTextTween.play();
	},
	onThrowComplete:function()
	{
		//we allow the snapping again
		snapping = false;
		startAnimations(count);
		//if all the slides animations are completed show the drag indicator
		if(allLinesComplete)
		{
			dragTextTween.reverse();
		}
	},
	snap:
	{
		left:
		function(endValue)
		{
			if(!snapping)
			{
				snapping = true;
				//the las value to be used as a snap point
				var lastEndValue = snapPoints[count];
				//going forward
				if(endValue <  lastEndValue + 560 && count < limit)
				{
					count++;
				}
				
				if(endValue > lastEndValue - 560 && count > 0)
				{
					count--;
				}
			}
			
			return snapPoints[count];
		}//function end
	}//snap variable end
});//draggable end
Link to post
Share on other sites

But I was looking for another behaviour - One single swipe should never advance you more than one swipe. But another swipe whilst the first swipe was still in motion would get you two steps forward.

 

It's kind of hard to explain and hard to test using a mouse, but if you study the behaviour of for example the iOS springboard this is how paged controls behave under iOS.

Link to post
Share on other sites

Ahh right sorry about that.

 

What you could do is remove the conditional logic from the snap function but keep the snapping in order to advance just one slide at a time.

 

Perhaps use this might do the trick:

snap:
	{
		left:
		function(endValue)
		{
			//the last value to be used as a snap point
			var lastEndValue = snapPoints[count];
			//going forward
			if(endValue <  lastEndValue + 560 && count < limit)
			{
			        count++;
			}
				
			if(endValue > lastEndValue - 560 && count > 0)
			{
				count--;
			}
			
			
			return snapPoints[count];
		}//function end
	}//snap variable end

Rodrigo.

Link to post
Share on other sites

Hm - I think that would only destroy the whole "not advance more than one step" functionality in that example.

 

I think, that in order to :

 

A: Limit a single swipe to a single page slide

B: Keep the edgeresistance intact 

C: Support multiple page slides on more than one consecutive swipes

 

my theory is:

 

* Start with setting up all snappoints - these do not need to change.

 

* Update bounds on each throwcomplete

 

* On drag - check if there is already some motion going on (in the "correct" direction) and if so, simply extend the bounds in that direction.

 

 

I'll try to make time to check that theory tommorow.

Link to post
Share on other sites

Yep I see what you mean, sorry I didn't catch it before.

 

Well the solution is quite simple, just remove the change of the snapping boolean from throwEnd to dragStart, like this:

var containerDraggable = Draggable.create($("#slide-container"),
{
	type:'left',
	throwProps:true,
	maxDuration:1.25,
	minDuration:.75,
	edgeResistance:.8,
	onDragStart:function()
	{
		dragTextTween.play();
		//we allow the snapping again
		snapping = false;
	},
	onThrowComplete:function()
	{
		startAnimations(count);
		//if all the slides animations are completed show the drag indicator
		if(allLinesComplete)
		{
			dragTextTween.reverse();
		}
	},
	snap:
	{
		left:
		function(endValue)
		{
			if(!snapping)
			{
				snapping = true;
				//the las value to be used as a snap point
				var lastEndValue = snapPoints[count];
				//going forward
				if(endValue <  lastEndValue + 560 && count < limit)
				{
					count++;
				}
				
				if(endValue > lastEndValue - 560 && count > 0)
				{
					count--;
				}
			}
			
			return snapPoints[count];
		}//function end
	}//snap variable end
});//draggable end

Like that the slides advance one at a time and you can swipe before the throw has completed.

 

Rodrigo.

  • Like 1
Link to post
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.

×