Jump to content
Search Community

Repositioning Draggable while dragging

Chuck Taylor test
Moderator Tag

Go to solution Solved by OSUblake,

Recommended Posts

I am working on a combination lock where there will be multiple dials with numbers from 0-9. To simulate a rotatable dial - similar to that found on luggage, I am using the Draggable plugin along with the InertiaPlugin. In my demo, there are a couple things to quickly note. First, in the end, the overflow on the dial portion will be hidden. I just show everything right now so that it is easier to understand what is happening. Second, while this demo results in an array of numbers which becomes eventually needlessly long, I plan to recreate a properly sized array at the end of the drag - perhaps in onThrowComplete callback. (Open to suggestions :) )

 

So the basic idea is this: I start off with an array of numbers. As the user drags up on the list of numbers, new digits are pushed to the end of the array. Dragging in this up direction works in the demo. The challenge is the other direction. When the user drags down on the number list, I need to add a number to the beginning of the array, while at the same time moving the draggable list up the same height. This is what I have not quite cracked. I have tried with limited success to get this work by calling Draggable.endDrag() followed shortly after by Draggable.startDrag() while the draggable item is being repositioned, but I was losing the inertia feeling.

 

Going back to the array of numbers getting long, I was also doing something along the lines of

numList.unshift(numList.pop()) and

numList.push(numList.shift())

However, this will require the draggable element to be repositioned during both up and down drags.

See the Pen yLMYxgP by chucktaylor (@chucktaylor) on CodePen

Link to comment
Share on other sites

Thank you kindly for the quick response and for taking the time to share this solution with me. It has been well over a year since I have used GSAP, so I apologize if this is really basic. I tried to first move the older syntax to the newer - to hopefully better understand the code while refactoring. Looks like I muddled it somehow. I went through the docs v2 and compared it with the newer v3 docs, but I seem to have messed something up. Would someone be willing to take a peek at this and what @OSUblake was kind enough to share? I'm guessing it is something super obvious to anyone who uses this on a regular basis.

 

What @OSUblake has put together is really nice, and certainly has the right feel on both desktop and mobile touch devices for what I am trying to achieve. I just need to get it to cycle through the numbers, and adjust the look so I'm only able to see 1 number and maybe a portion of the previous and next at any given time. I guess the last thing will be identifying the currently 'active' number. But baby steps!

 

I believe in his example, he is piece by piece creating a larger timeline, and then 'scrubbing' that timeline with the drag functions?

 

See the Pen qBrOvYo by chucktaylor (@chucktaylor) on CodePen

Link to comment
Share on other sites

3 hours ago, Chuck Taylor said:

I believe in his example, he is piece by piece creating a larger timeline, and then 'scrubbing' that timeline with the drag functions?

 

Yep.

 

You're conversion over to newer syntax looks good, so I don't know what's going on. I'll look more at more in depth later and try to figure it out. 

 

Link to comment
Share on other sites

Thanks again @OSUblake! The kiddos are in bed now, so I am going to fork what I had above and try a bit more this evening. My initial suspicion is with the chained add method when the 'animation' timeline is created. Mostly because I don't really understand what tweenFromTo is doing, but I'll read that a little closer now. .add(baseTl.tweenFromTo(1, 2))

Link to comment
Share on other sites

Well. Some progress. First, I made a rather silly mistake in the css. The .cell classes had originally had a position: absolute, which I had 'temporarily' commented out as the numbers were not visible while working. 🙄

 

With that out of the way, at least the dial is a lot closer to what @OSUblake had already put together. The two 'gotchas' I am now facing are:

  1. The dial is blank on load - shows no numbers until we first start to drag down.
  2. Dragging up is problematic. I am currently console logging the value of this.y in the updateProgress(). Anytime y < 0, it locks up. I'm guessing the timeline is not 'repeating backwards' from 0?

In the meantime, here is the pen with the css correction.

 

See the Pen mdWeNBJ by chucktaylor (@chucktaylor) on CodePen

Link to comment
Share on other sites

  • Solution
29 minutes ago, Chuck Taylor said:

Dragging up is problematic. I am currently console logging the value of this.y in the updateProgress(). Anytime y < 0, it locks up. I'm guessing the timeline is not 'repeating backwards' from 0?

 

I think wrap might be a good one for that.

 

const wrap = gsap.utils.wrap(0, 1);

console.log(wrap(-0.75)) // 0.25

 

32 minutes ago, Chuck Taylor said:

The dial is blank on load - shows no numbers until we first start to drag down.

 

It might need a little jump start to do the first render.

const animation = gsap.timeline({ repeat: -1, paused: true, id: 'animation'})
  .add(baseTl.tweenFromTo(1, 2))
  .progress(1)
  .progress(0);

 

  • Like 1
Link to comment
Share on other sites

@OSUblake That's the trick! I didn't know about the wrap utility. I'm going to check out the others. You have been a huge help! I am going to progress with the other functionality I aim to implement, but you have provided me with a big head start. Thank you again so much for your time!

 

I did figure out the 'nudge' with .progress(0). That seemed to solve the loading. However, if you suggest both progress(1).progress(0), I'll go with that.

 

Other question: What is the 'proxy' div doing in your code? It's not attached to the DOM. Just curious how it contributes.

 

See the Pen RwpWXOa by chucktaylor (@chucktaylor) on CodePen

Edited by Chuck Taylor
Further question.
Link to comment
Share on other sites

12 minutes ago, Chuck Taylor said:

After a bit more tweaking:

 

That is awesome! Thanks for sharing.

 

2 hours ago, Chuck Taylor said:

Other question: What is the 'proxy' div doing in your code? It's not attached to the DOM. Just curious how it contributes.

 

Well, we're really don't need to drag anything. What we need is something more like gestures i.e. swipe. So the trigger: dial is how the gesture gets initiated, and then draggable just applies the user's movement to the proxy element. From there, we can read the changes made to the proxy and then apply them to something else, like scrubbing a timeline.

 

Does that make sense? It can be bit confusing at first.

 

  • Like 3
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...