Jump to content
Search Community

Using Draggable from Outside.

iDad5 test
Moderator Tag

Go to solution Solved by iDad5,

Recommended Posts

Hi,

I don't know if I'm just not finding my error or if I try to do something that just isn't meant to be.

I try to build a volume-control for a video with a Draggable element (aka 'the handle') being moved up and down inside a container that is responsive. Everything works just fine - but as the user changes their browser window the size of  the 'track' changes. Draggable takes care that even after that change the handle moves correctly (cool!) but as the position of the Draggable.target (the handle) is fixed absolutely the relative position of the handle inside the track (that also indicates the current volume)  is wrong.

What I would like to do is correct that position from outside like that: 

var handle = Draggable.create('#handle', {...});  //that works - kind of

 

 and later on to calculate the new position inside my delayed window-resize handler:

 

let oldPlace =  handle.y

 

hoping to move handle.target later to the required (just calculaded) position.

 

already the first step gives me undefined... (I also tried "new Draggable()" instead of "Draggable .create()" to no avail). 

 

I like to work in Typescript and structure my classes a bit. I hate to write lots of anonymous functions. It works fine with tweens (or gsap) and timelines to store them in private members in my classes and call them from any method inside. Not so with  Draggable. Any ideas?

 

Link to comment
Share on other sites

Hey @mikel,

tanks a lot, I see what you are doing. But actually that wasn't what I wanted to know. It wasn't so much about the actual problem (I solved it an other way already).

I don't like the concept of anonymous functions a lot.

so what I like to do is this; (TypeScript, but applies to pus JS also - I )  

 

class DragExamle{
 
    private dragHandle : Draggable;
 
    constructor (idstring){
        //this.dragHandle = Draggable.create('#'+id, {type: 'y'});
        this.dragHandle = new Draggable('#'+id, {type: 'y'});
        document.body.addEventListener('click'this.getDragY); 
    }
    private getDragY = (e:Event=> {
        console.log(this.dragHandle.y);
    }
}

 

according to my understanding that should work, and the otherwise excellent type-definitions seem to think the same. Still i get logged 'undefined'...

(the line I out-commented works the same as the following line, but I would need to typecast it for the definitions - but in the end it gives the same problem.)

 

 

The concept works for Tweens and Timelines just not for draggable. So my question is: am I making a (conceptual) mistake  here or is it simply that the Draggable class is missing some functionality it should have or simply is implemented an other way...

 

 

 

 

Link to comment
Share on other sites

I read your question at least 3 times and I'm still kinda fuzzy on exactly what you're asking. At first, it seemed like you're asking how to create particular draggable functionality, but then it seemed like you were asking about TypeScript and an undefined property.

 

A few notes:

  1. Draggable.create() returns an Array whereas new Draggable() obviously creates a new Draggable instance. So you shouldn't expect Draggable.create() to behave the same way. 
  2. Are you saying that console.log(this.dragHandle.y); is literally logging "undefined"? Can you please provide a minimal demo as a CodePen so we can see the issue in context? 
  3. If you want to get the "y" of a particular element, is there a reason you're trying to do so with yourDraggable.y instead of gsap.getProperty(element, "y")? That may be an alternative to try if you're struggling. 
  • Like 1
Link to comment
Share on other sites

  • Solution

Thank you Jack for your answer. 

 

First of all I have to report that I made a CodePen (my first) and I got it to work the way I wanted and expected.

 

to 1: I thought exactly that way, but I found multiple answers that suggested that create() would be the same as the constructor and as both worked / not worked the same way for me I grew uncertain. And create was said to be the preferred method of creating a Draggble (?) The documentation is - at least for me - not to clear either.

to 2: I did (

See the Pen jOVqdWv by mdrei (@mdrei) on CodePen

) and it worked. I have to see if there is something I couldn't fin in hours of searching in  my code that was wrong, or if my setup (locally hosted gsap) is buggy in a strange way.

to 3: I resorted to Draggable.get('#id').y in the end, but just wanted to understand... 

 

THX again

Link to comment
Share on other sites

There are no real issues there, thanks.

Unfortunately when I tired to incorporate the "new Draggable" variant in my more complex programming instead of Draggable.create() I got a "Uncaught TypeError: Cannot read property 'getComputedStyle' of undefined" console error from Function 'Ja'.

 

I still wonder is there a way to retrieve the actual Draggable instance of a Draggable  that was created with Draggable.create(); ? 

But as I have at least two work arounds it's not a pressing matter at all for me.

 

If someone with deeper understanding of the Draggable programming could add a more in depth clarification to the docs about the return types and the differences between new Draggable and  Draggable.create() I would welcome that a lot.

 



 

Link to comment
Share on other sites

7 hours ago, iDad5 said:

Unfortunately when I tired to incorporate the "new Draggable" variant in my more complex programming instead of Draggable.create() I got a "Uncaught TypeError: Cannot read property 'getComputedStyle' of undefined" console error from Function 'Ja'.

 

That sounds like maybe you're calling gsap.registerPlugin(Draggable) (and your other code) BEFORE the window is even defined. Draggable needs the window/document in order to function of course. :)

 

7 hours ago, iDad5 said:

I still wonder is there a way to retrieve the actual Draggable instance of a Draggable  that was created with Draggable.create(); ? 

Absolutely - since it returns an Array, you can grab the first element in that Array like:

let myDraggable = Draggable.create(...)[0];

The reason Draggable.create() returns an Array is because you might pass selector text in which may return MULTIPLE elements, like Draggable.create(".box") would make ALL the elements with the "box" class draggable. That's much more convenient than selecting them all, looping through each one and doing new Draggable() for each one. That's really the only difference. 

  • Like 1
Link to comment
Share on other sites

Thanks a lot for your answer.

20 hours ago, GreenSock said:

That sounds like maybe you're calling gsap.registerPlugin(Draggable) (and your other code) BEFORE the window is even defined. Draggable needs the window/document in order to function of course. :)

No I don't. I call everything from an inti function that is is called by jQuery document.ready.

Not a lot of things would work otherwise. 

 

No error happens if i use Draggabel.create() instead of  New Dragable. Everything else is exactly the same. All works well using create nothing with the constructor. And there is exactly one target HTMLnode ('#id').

I'm satisficed  with my working solution I just don't get it why it would not work with the constructor. 

Link to comment
Share on other sites

20 minutes ago, iDad5 said:

No error happens if i use Draggabel.create() instead of  New Dragable. Everything else is exactly the same. All works well using create nothing with the constructor. And there is exactly one target HTMLnode ('#id').

I'm satisficed  with my working solution I just don't get it why it would not work with the constructor. 

It's pretty tough to troubleshoot blind - do you have a minimal demo where we can see the error being generated? 

 

Did you register the plugin? Like:

gsap.registerPlugin(Draggable);

If you look at the raw source code, you'll see that create() simply loops through the targets and does the same thing - new Draggable(...)

  • Like 1
Link to comment
Share on other sites

First of all I really appreciate your taking the time to care for my small troubles. And I do understand how hard it is for you to troubleshoot blindly. As I have a working solution and my problem only occurs (as far as I know) in the under my specific circumstances. (it did not in my simplified  CodePen example I'm not sure if it is worth more of your time.
I'm a great fan of greensock since the early flash days and in case you suspect that what i stumbled upon might help solve a hidden problem I more than willing to build one or better two versions of my project striped down for you to debug.
 

16 hours ago, GreenSock said:

If you look at the raw source code, you'll see that create() simply loops through the targets and does the same thing - new Draggable(...)

That is what I suspect (although I have to admit I was to lazy [or to shy ;-)] to check the source code for my self).
 

 

17 hours ago, GreenSock said:

Did you register the plugin? Like:


gsap.registerPlugin(Draggable);

No I didn't before, as I host the library myself (old ways and the European privacy laws...) I just embed the plugin file. Worked well so far. After you suggested it  I did call registerPlugin, but it didn't change a thing.

Thanks again for your great work!

Link to comment
Share on other sites

Ok, I did surgery and cut out the troubled piece and placed it in a lonely page so that you can examine it...
While doing so I found a third variant :-/ 

 

Background: What your going to see is part of a (German) website, an ongoing non-profit cultural project about a literary figure. The whole site is a replacement for a PHP4. website with some Flash from years ago, that went totally out of business some weeks ago... 
So I've thrown together a wordpress based site as replacement and a video and text animation replacing a small Flash element much liked on the old site.
I wanted to build a HTML5 video player from scratch (with draggable handles) for a while and tested out the concept in the element in question in parts, but in a little hurry.

 

Under https://dev.thewebworks.de/debug/ you will find three variants of that element. One working, one not working at all and one breaking when dragging the volume handle. (You have to start the animation and hover over the volume icon in the lower right corner...) 
Sorry I couldn't provide those in a CodePen each, I just not proficient enough with the CodePen stuff and it would know how to make it work, if you cannot work with the links I'll be happy to send you a zip or even give it another try with CodePen.

 

All three share exactly the same (rusty) programming save one line (and changed class-names not to confuse VS-Code).

That line in the 'initVolumeControls' method is:


working:

this.volumeHandle = Draggable.create('#walk-volume-handle', { type: 'y'bounds: jQuery('#walk-volume-handle').parent(), onDrag:function(){
            walk.react2VolumeHandleMove(this.ythis.maxYthis.minY);


throwing an error on initializing (not working):

this.volumeHandle = new Draggable('#walk-volume-handle', { type: 'y'bounds: jQuery('#walk-volume-handle').parent(), onDrag:function(){
            walkB.react2VolumeHandleMove(this.ythis.maxYthis.minY);

 

throwing an error and breaking when dragging(partly working):

        this.volumeHandle = Draggable.create('#walk-volume-handle', { type: 'y'bounds: jQuery('#walk-volume-handle').parent(), onDrag:function(){
            walkC.react2VolumeHandleMove(this.ythis.maxYthis.minY)[0];

 

I'm rather sure that something with the scope of the anonymous onDrag function causes this behavior and I freely admit that one reason why I like to avoid those is, that in even in mildly complex situation understanding the scope sometimes makes my head explode.
Revisiting my hastily built stuff to isolate it for you I am sure that there are better ways to built this starting with the DOM and CSS. Also I regained a better understanding of gsap by now - I grew rusty in recent years. Still I am very curious how those three seemingly identical ways of trying to do the same thing have three different outcomes. Please enlighten me. :-) 

 

Link to comment
Share on other sites

The third situation has nothing to do with GSAP, it just has to do with what your react2VolumeHandleMove function is returning.

 

I am able to see the issue on the page that you provided for us in the second case. However not being able to debug myself makes this harder :) Can you please try removing parts of the Draggable vars (like type, bounds, and onDrag) one by one and see if the issue still occurs? 

 

Past that, the more code you can cut out, piece by piece, in the rest of your page until the error goes away would be greatly appreciated. I'm not able to recreate the issue from scratch.

Link to comment
Share on other sites

Thanks @Zach,
 

just to be sure: I know the Whole programming we are taking about was quite hasty and I already have not only the one old version work but also a better structured (at least more to my liking) version that runs smoothly.

Back to the (theoretical) issue at hand:
 

3 hours ago, ZachSaucier said:

The third situation has nothing to do with GSAP, it just has to do with what your react2VolumeHandleMove function is returning.

I know you are a god of programming compared to my humble self, but still I dare to have my doubts there. 😬
1. react2VolumeHandleMove returns noting and receives only 3 numbers via GSAP

2. As it wasn't usable, due to my ****** work, I do not use the volumeHandle property anywhere, so the fact hat in case one I assign the whole arry to it and in case 3 only the fist element shouldn't matter. (?)
3. Besides that one line quoted in my last post everything else (aka my bad code) ist exactly the same in all three versions. Therefore by my thinking all the difference in the whole thing must be caused by the way the (in the end) anonymously instantiated Draggable instance is created. (Or do I have a logical flaw in my thinking here?)

 

3 hours ago, ZachSaucier said:

Past that, the more code you can cut out, piece by piece, in the rest of your page until the error goes away would be greatly appreciated. I'm not able to recreate the issue from scratch.

As I am really interested in solving that puzzle I will try to create it in a or better three CodePens.

Thank you again for your support.


 

Link to comment
Share on other sites

I don't understand sorry. It does not return anything (or undefined as you point out) in version 1 too. And as the function is called, I cannot see where its. return value is used?

 

What difference does it make that the first (and only) instance of the obviously successfully created Draggable(s) is assigned to a never used property, or h arry wit this one element?

Link to comment
Share on other sites

4 minutes ago, iDad5 said:

It does not return anything (or undefined as you point out) in version 1 too

Correct. But in version 1 you're not trying to get the 0th index of the return value :) 

walk.react2VolumeHandleMove(this.y, this.maxY, this.minY)[0]; // This throws an error
walk.react2VolumeHandleMove(this.y, this.maxY, this.minY); // This does not

 

Link to comment
Share on other sites

Oh **** thank you for your patience. Now I see it! what I meant to do with that '[0]' was to put it at the end of the whole line, not inside the Dragabble.create() - my only and weak excuse is my hate for those inline callback function and therefor my inexperience.

I owe you .

 

Here is a CodePen for version 1 (working on getting the fonts (and icons right):

See the Pen GRNNyOL?editors=1111 by mdrei (@mdrei) on CodePen

Link to comment
Share on other sites

I haven't had time to look at your previous posts but the CodePen is definitely incorrect - you're doing: 

Draggable.create(...)  as unknown as Draggable

But like I said earlier, Draggable.create() returns an Array, not a Draggable instance. I assume you meant to do Draggable.create(...)[0] as Draggable

 

If you could please create just the absolute minimal demo in CodePen that throws the error, we'd sure appreciate that. No need to have all the other animation code in there, etc. It really, really helps to focus things as much as possible. 

 

Thanks!

Link to comment
Share on other sites

23 minutes ago, GreenSock said:

But like I said earlier, Draggable.create() returns an Array, not a Draggable instance. I assume you meant to do Draggable.create(...)[0] as Draggable

I know, I just had that in to avoid  TypeScript compile errors in my hurry... 

 

All that is already fixed. and that lazy casting and recasting is bad form but doesn't cause a thing.


I'm working to reproduce the problem with minimal code.

Link to comment
Share on other sites

I made a very stripped down version now - but I forgot (and didn't know how) to fork the CodePen. You can see it for your self in the previous one if you comment in and out the lines 26 and 27 everything works. It does not in the example on my server (https://dev.thewebworks.de/debug/) which I also stripped down.
Is it possible that in the downloadable zip for local use is a difference to the version used with CodePen. (I stole my settings from mikel...)

Link to comment
Share on other sites

3 minutes ago, iDad5 said:

I made a very stripped down version now - but I forgot (and didn't know how) to fork the CodePen. You can see it for your self in the previous one if you comment in and out the lines 26 and 27 everything works. It does not in the example on my server

I'm lost - I commented in/out lines 26 and 27 (alternated) and see absolutely no difference nor do I see any errors in the console. What am I missing? 

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