Jump to content
steve1628

reset Draggable position to it original position

Recommended Posts

Hi there,

 

First of all I like to say i love your product and have been actively using the AS version along time and when a js version came out, it was like a god set.

 

I have a issue with the Draggable class, basically i am using the class to drag a custom slider.

When I then proceed to another section of my web application and then come back to the page which has the slider class there is no way to reset the slider drag handle position back to 0,

 

I have tried making the instances of the draggbable item to null and have even clear the style attr, but for some reason when I recreate new Drag instances the transform matrix data is of the old data

 

this is how I try to get rid of the old instances:

 

 

 

for (var i = 0; i < this._draggables.length; i++) {
 
this._draggables.disable(); //disable the instance. 
this._draggables=null;
}
$(".drag_handle").attr("style","")
this._draggables=null;
 
and this is how I create it
 
this._draggables =Draggable.create("#allocate_people .drag_handle",{type:"x",bounds:$('#allocate_people .drag_handle').parent()})
 
any suggestion as to what I can do to reset it back to it original position
 
thanks,
 
Steve

 

 

 

Share this post


Link to post
Share on other sites

Sorry to hear about the trouble - are you saying that you're first using Draggable to move the element, but then you manually change its position (outside of Draggable or GSAP) and you want those changes to get recognized/applied? 

 

Keep in mind that GSAP tracks/records its transforms in a custom object attached to the element (_gsTransform) in order to make things perform better and work around some browser bugs, so if you apply a transform with GSAP and then manually edit the inline css and then try doing a tween with GSAP, it will use the old/recorded values unless you specifically set parseTransform:true in your tween (which tells GSAP to ignore any recorded values and force a re-parse). It's very rare that it's ever necessary, but maybe in your case it is. The other solution would be to just make sure that you make your css changes through GSAP, like TweenLite.set(element, {....}); so that the values are always kept up to date. 

 

You can also clear certain inline css properties (or all of them) using the clearProps feature, like:

TweenLite.set(element, {clearProps:"transform"});
//or to clear them all:
TweenLite.set(element, {clearProps:"all"});

(maybe I misunderstood your question though - if so, please post a very simple codepen or jsfiddle that demonstrates the issue so we can take a peek)

Share this post


Link to post
Share on other sites

Jack beat me to it...

 

Yep clearprops is the way to go, I set up a simple codepen:

 

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

 

Best,

Rodrigo.

  • Like 2

Share this post


Link to post
Share on other sites

Hi Jack,

 

Thanks for the reply.

 

Basically I drag a handle on a custom slider that I created with Javascript, that slider being inside a div which act as a page.

 

Now when I hide that div and come back to it later by toggling the div visibility, when I re-do the Draggable.create function the drag handle position is that of the old recorded position where I previously left it, it doesn't reset to 0px. I will try the solution you outlined and see if it work.

 

stee

Share this post


Link to post
Share on other sites

I had a similar issue where the user slides from one view to another - when returning to the old view, just a click at the view's draggable instance would fire a dragComplete event with the coordinates of the throwProps x.min or x.max value - 
Thanks to this post I tried a bit and finally found my solution:
 
After a page has fininshed displaying, I'll manually set   

 TweenMax.set(this.element.content_wrapper, { x : 0 } ); 

instead of 'clearProps' (which had other side effects in my case)

Share this post


Link to post
Share on other sites

Hi Conrad and welcome to the GreenSock forums.

 

Is great that you could solve your issue.

 

Also keep in mind that clearProps can be specific about each property you're tweening, so in your case the code would be:

TweenMax.set(this.element.content_wrapper, { clearProps:"x" } ); 

clearProps removes any inline style applied by GSAP to the target element in order to restore the original CSS style of the element.

 

Rodrigo.

  • Like 2

Share this post


Link to post
Share on other sites

Jack beat me to it...

 

Yep clearprops is the way to go, I set up a simple codepen:

 

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

 

Best,

Rodrigo.

 

After I click "Draggable Slider" once it resets the position, but then it can no longer be dragged anymore. Is there a way to keep all the functionality, but just reset the current position?

Share this post


Link to post
Share on other sites

Hi,

 

I've updated the codepen and is working properly again. Thanks for bringing that to our attention.

 

Rodrigo.

Share this post


Link to post
Share on other sites

Hmmm...  I am trying to modify the code all of you have supplied and make the dragged item bounce back to it's original position when the drag is completed.  Here is a forked codepen which is partially working:

 

See the Pen qucai by PawleyBoboli (@PawleyBoboli) on CodePen

 

The first drag is not bouncing back at all, but subsequent drags are bouncing back to incorrect coordinates.  I'm not sure why, but if you open the console while dragging a box and releasing it (both on top of another box or on top of nothing), you will see output of the starting coords matching the output of the bounce-back-to coords, but the dragged box seems to have a mind of its own.  

 

I'm sure this problem has something to do with scope, but not sure what I'm missing (?).

 

Thanks for any info

--Kevin

Share this post


Link to post
Share on other sites

Hi Kevin,

 

First thanks for providing the codepen!!

 

By default Draggable sets the type to "x,y", since you're not defining the Draggable type is set to that.

 

In your pen the instance being created onDragEnd uses top/left, hence tweening the element to the wrong position. Just change it to x/y and it'll work fine:

TweenLite.to(this.target, 0.5, {x: boxX +"px", y: boxY +"px", ease: Bounce.easeOut});

Rodrigo.

  • Like 2

Share this post


Link to post
Share on other sites

Hi Folks,  I am back to this "bounce back" version of a draggable instance because my testers have found a slight bug with it.  Here is the codepen for my version: 

See the Pen EaneH by PawleyBoboli (@PawleyBoboli) on CodePen

 

The problem occurs if a user clicks the draggable item inadvertently a second time while it is still in motion.  This seems to reset the originating boxX and boxY numbers to new locations.  Opening the console for this codepen will display messages of the starting point for each drag.  To see the failure, drag the box to the right a few pixels and then quickly click/drag on it again before it reaches the home position.  Do this enough times and the new home position is far from the original location.

 

Here's a capture from my project:

draggable_badbounce.jpg

 

Any ideas on how I can keep this 'resetting' from occurring?  Thanks for any advice!

 

--Kevin

Share this post


Link to post
Share on other sites

Without going back over the earlier posts, what is the point of saving the boxX/boxY onPress? That's what's "resetting" the box position. The default x/y values for an object are always 0,0 so you could just be tweening back to 0,0 and avoiding this entirely.

  • Like 1

Share this post


Link to post
Share on other sites

There's an issue with your onDragEnd callback. You're animating the object back to a value that could change every time you click on the element.

 

Ha, Jamie beat me to it.

 

He's right every time you click on an element, the onPress callback sets a new value for those properties, creating the issue. Also besides the onDrop() function, I don't see that this values are used elsewhere in your code, I don't know how your app is structured, but perhaps you could remove those values and use 0 for both as Jamie points.

 

Another solution is to create a boolean and in the onPress callback change it and restore it's value using the onThrowComplete callback, in order to prevent the user from clicking the element before the throw has ended.

var allowDrag = true;

Draggable.create(element, {
  type:"x,y",
  throwProps:true,
  onPress:function(){
    if(allowDrag){
      //code here

      allowDrag = false
    }
  },
  onThrowComplete:function(){
    allowDrag = true;
  }
});

You weight which alternative fits better in your particular scenario.

 

Finally you're using a somehow old version of the engine (1.11.5), see if you can update it.

 

Rodrigo.

 

EDIT: Originally I suggested to use the onThrowComplete callback, that won't fix the issue. You should reset the boolean using an onComplete callback in the Tween that gets the element back to the BoxX and BoxY values:

Draggable.create(droppables, {
//code here

onDragEnd:function(e) {
      var i = droppables.length;
      while (--i > -1) {
        if (this.hitTest(myTarget, overlapThreshold)) {
          onDrop(this.target, myTarget);
        }
		      }
    console.log("we dragged from : " + boxX +"px" + ", "+ boxY +"px")
      TweenLite.to(this.target, 0.5, {x: boxX +"px", y: boxY +"px", ease: Bounce.easeOut, onComplete:resetBoolean});
  	}
});

function resetBoolean(){
  allowDrag = true;
}

Sorry for the lapsus.

  • Like 1

Share this post


Link to post
Share on other sites

Actually, you both had the answer and I learned something new.  I had been setting the beginning x ,y of the dragged object because I thought it needed to grab those values from it's CSS settings.  I totally missed the fact that GSAP considers that point to be 0,0 when dragging, regardless of what the CSS settings are. That's even more embarrassing because the console output was returning "starting position = x: 0 y: 0".  (forehead slap)

 

Removing the storage of boxX & boxY from onDrag ensures that the return position will be the original one, however, if one aggressively clicks the draggable item while dragging it you can still get it to finish in a position other than the original home position.  Adding Rodrigo's allowDrag Boolean helps prevent that, and even though I can still get a failure to return to the home position, it takes a moronically absurd number of rapid clicks to get it to do so.  Also, once the draggable is in the wrong position, any subsequent normal drag now automatically brings it home when released.

 

I've updated my codepen with your fixes and with the new version of GSAP.  Thanks so much for the help!

--Kevin

Share this post


Link to post
Share on other sites

I'm a bit confused by your implementation of the fixes - you've kept boxX and boxY but never modify them now, and you've not added any logic that actually requires the allowDrag boolean, so it's providing no effect at all to the running of your program. There were also a few loops that had no purpose; those code blocks only need to be run once. I've cleaned it up for you and the behaviour is identical

See the Pen 7a38e75e8f214b750cad564a84f255ef by jamiejefferson (@jamiejefferson) on CodePen

 

I am also seeing the bug that locks the draggable in a new position. I can fairly reliably reproduce it with just one or two clicks after dragging a few pixels. Still investigating... If you click on the element without moving the cursor it happens, because there was no drag and onDragEnd is used to 'reset' the element. If you change onDragEnd to onRelease it will always trigger - onDragEnd only triggers if there was an actual drag.

  • Like 1

Share this post


Link to post
Share on other sites

Hi Jamie,

 

You're right, I did not remove the boxX or boxY variables but just set them both to 0.  They are not needed now of course.  As for the allowDrag boolean, I did implement Rodrigo's recommendation (sorry I named it "allowDragging" instead of "allowDrag") and it should be viewable in the codepen  

See the Pen EaneH?editors=101 by PawleyBoboli (@PawleyBoboli) on CodePen

 

Your solution for changing onDragEnd to onRelease is working perfectly.  I can't get it to fail no matter how fast I click on the draggable item.

 

Thanks so much!

--Kevin

Share this post


Link to post
Share on other sites

Ha, don't worry Kevin, we're not that strict regarding naming conventions, it was just a suggestion, that's all ;)

 

Nice job on the code, glad you sort it out.

 

Happy Tweening!!

Share this post


Link to post
Share on other sites

Glad you've gotten it working. I'm not aware if/how you added allowDragging (sorry I misnamed it) to your actual project, but I still maintain that allowDragging is doing nothing in your codepen. There is no code that actually checks the value other than for a console log, and as such dragging is allowed at all times. I believe Rodrigo was just giving you a nudge in the right direction with the "// code here" bit needing some extrapolation. Just having an allowDragging variable exist does not affect the function of Draggable.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.