Picture of Henrik Aabom
Draggable with GSAP not working
by Henrik Aabom - Sunday, 19 March 2017, 6:23 PM
 

Hello everyone!

I'm trying to make a Drag-n-drop component, using GreenSock API.

Everything has been working this far.

I'm importing the two needed Javascripts by writing this in the top of my component's javascript-file:

var GSAP = require('libraries/TweenMax.min');
var GSAPdraggable = require('libraries/Draggable.min');

The animation tweens work just fine, but when I try dragging the elements I get the following error message in the browser console (Chrome, EI11 does not show any error messages, but the script still doesn't work):

 

UncaughtTypeError: Cannot read property 'pageX' of undefined (Draggable.min.js:15)
at Xa (Draggable.min.js:15)
at Function.Ta.hitTest (Draggable.min.js:15)
at Ta.hitTest (Draggable.min.js:14)
at Ta.onDrag (adapt.min.js:5)
at ja (Draggable.min.js:14)
at Array.Za (Draggable.min.js:14)
at Object.P (Draggable.min.js:14)
at Object.h.dispatchEvent (TweenMax.min.js:16)

 

I tried creating the drag-n-drop exercise on Codepen before transferring it to Adapt, and it worked fine there.

I found a GitHub thread on a similar issue about the "UncaughtTypeError: Cannot read property 'pageX' of undefined"-error here:

https://github.com/taye/interact.js/issues/251

But they are talking about that the issue has something to do with a interact.js script, but this script doesn't exist in Adapt, as far as I know, and the error-messages I get doesn’t seem to mention the interact.js, but rather the issues seem to come from Draggable.min.js and adapt.min.js. Maybe there are some conflicting functions in these scripts or something...?

But yeah, the funny thing is that the exercise works fine on Codepen, so either, I'm doing something wrong when transferring the code into the component's scripts or GSAP draggable, just doesn't work with the Adapt framework (which would be sad).

The pen is here:

https://codepen.io/HenrikAabom/pen/QpOePL?editors=0010

 

Any help much appreciated.

Henrik

Picture of Matt Leathes
Re: Draggable with GSAP not working
by Matt Leathes - Monday, 20 March 2017, 10:02 AM
 

It's mostly likely something wrong in transferring the code over to work inside of an Adapt view... if you could share that code?

Picture of Henrik Aabom
Re: Draggable with GSAP not working
by Henrik Aabom - Monday, 20 March 2017, 11:50 AM
 

I've uploaded component to GitHub here:

https://github.com/HenrikAabom/adapt_dnd

This is a very early draft, so please remember that nothing is DRY'd up or anything ;)

Picture of Matt Leathes
Re: Draggable with GSAP not working
by Matt Leathes - Monday, 20 March 2017, 3:23 PM
 

I think it's most likely that you're running into scoping errors with this in your onDrag and onDragEnd functions i.e. this refers to a different object when used inside those functions.

A fairly easy way of sorting out these sorts of problems is to add a line of code like var that = this; (or var self = this; if you prefer) on about line 26 - and then to use that (or self) when referring to properties of the component e.g.

if (this.hitTest(that.dropArea, that.overlapThreshold))

(In that example, hitTest belongs to Draggable and not DnD so it's correct to refer to it as this.hitTest rather than change it to that.hitTest)

Also where you have code like this.dropArea = $(".drop-target-image"); you're going to have problems if you try to use multiple instances of your component in the same page; change these to this.dropArea = this.$(".drop-target-image"); so that the selector will only search within the current component not within the page. This is particularly important when you do something like $("img") as currently that will target every single <img> on the page... in that particular instance it would need to be that.$("img"); of course because it is used inside onDrag/onDragEnd.

Picture of Henrik Aabom
Re: Draggable with GSAP not working
by Henrik Aabom - Monday, 20 March 2017, 4:19 PM
 

Thanks Matt!

I'll give it a go and get back :)

Picture of Henrik Aabom
Re: Draggable with GSAP not working
by Henrik Aabom - Wednesday, 22 March 2017, 2:16 PM
 

Yes, that was it!

Thanks Matt, I'll go have fun with "this" and "that" :D

Picture of Matt Leathes
Re: Draggable with GSAP not working
by Matt Leathes - Wednesday, 22 March 2017, 3:28 PM
 

Heh, not exactly what I'd call 'fun' - definitely one of the more annoying parts of JavaScript. Hopefully we can soon drop support for IE8/9/10 and that should allow us to look at being able to use ES6 in Adapt. Specifically helpful to this situation would be the ability to use Lambda Expressions AKA '(fat) arrow functions'.

Picture of Henrik Aabom
Re: Draggable with GSAP not working
by Henrik Aabom - Thursday, 23 March 2017, 7:10 AM
 

Yeah I read about that yesterday and it sounds like a neat little feature, which is most welcome :D

Picture of Henrik Aabom
Re: Draggable with GSAP not working
by Henrik Aabom - Monday, 22 May 2017, 7:49 AM
 

Hi again

I've run into a new problem with loading in GSAP libraries through require()...

Up until now, the component has been based on the adapt-contrib-text component, and the lines:

var ComponentView = require('coreViews/componentView');
var Adapt = require('coreJS/adapt');
var GSAP = require('libraries/TweenMax.min');
var GSAPdraggable = require('libraries/Draggable.min');

have been working just fine.

Now I want to convert it to a question component. To do that I've added the two required() lines to the adapt-contrib-mcq, like so:

var QuestionView = require('coreViews/questionView');
var Adapt = require('coreJS/adapt');
var GSAP = require('libraries/TweenMax.min');
var GSAPdraggable = require('libraries/Draggable.min');

and added a libraries-folder in the root of the mcq component with the two GSAP scripts. However, the code fires an error when the course is running.

Am I using the require() wrongly?

The funny thing is, that if I use a web-link for the scripts, everything is working fine:

var QuestionView = require('coreViews/questionView');
var Adapt = require('coreJS/adapt');
var GSAP = require('https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/TweenMax.min.js');
var GSAPdraggable = require('https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/utils/Draggable.min.js');

The problem with using web-links is that I can't be sure that our client's servers will allow outside scripts to be loaded, so it would be better if I could include them as part of the component's source files.

Any help much appreciated.

Henrik

Picture of Henrik Aabom
Re: Draggable with GSAP not working
by Henrik Aabom - Monday, 22 May 2017, 12:19 PM
 

Okay, a bit embarrasing, but I found that the reason why the above code worked with the web-links and not with relative paths, was that the two scripts were loaded into my browser's cache files...

When clearing the cache files, the code stopped working, just like with the relative paths... Back to square one :/

Picture of Dan Storey
Re: Draggable with GSAP not working
by Dan Storey - Monday, 22 May 2017, 12:59 PM
 

Hi Henrik,

Have you tried: require("core/js/libraries/yourFile.js"); ?

 

 

 

Picture of Henrik Aabom
Re: Draggable with GSAP not working
by Henrik Aabom - Wednesday, 24 May 2017, 3:29 PM
 

Hi Dan

Yeah, I tried that, but with no luck...

 

However, I think I found the reason to my error. It's not that the scripts aren't loaded, but they are loaded in the wrong order.

I tried using the adapt-contrib-match component instead of mcq, because it already has a "library" folder to put the scripts into. In the js file I've turned this:

define([
'core/js/adapt',
'core/js/views/questionView',
'libraries/select2'
],function(Adapt, QuestionView) {

into this:

define([
'core/js/adapt',
'core/js/views/questionView',
'libraries/select2',
'libraries/TweenMax.min',
'libraries/Draggable.min'
],function(Adapt, QuestionView) {

which did the trick!

Just for testing, I tried switching my two scripts around inside the define function, and then I got the error again. It makes sense as Draggable is dependent on TweenMax.

My question now is: Can I always be certain that scripts will be loaded in the same order as their position inside the define([..])?

If not, is there a way to make sure that TweenMax is always loaded before Draggable?

Thank you

Picture of Henrik Aabom
Re: Draggable with GSAP not working
by Henrik Aabom - Friday, 2 June 2017, 12:47 PM
 

So it turns out, that you cannot be sure that scripts will be loaded in the order they are placed inside define([...]).

I have:

define([
'core/js/adapt',
'core/js/views/questionView',
'libraries/select2',
'libraries/TweenMax.min',
'libraries/Draggable.min'
],function(Adapt, QuestionView) {

and it seems that it starts loading TweenMax.min.js before Draggable.min.js, but sometimes it seems as if TweenMax isn't done loading before Draggable. Because one out of 3 times when I refresh the page I get the following errors in the browser console:

- GET http://localhost:9001/TweenLite.js 
- Uncaught Error: Script error for "TweenLite" http://requirejs.org/docs/errors.html#scripterror
- GET http://localhost:9001/CSSPlugin.js
- Uncaught Error: Script error for "CSSPlugin" http://requirejs.org/docs/errors.html#scripterror


Which to me looks like the TweenMax isn't done loading when Draggable needs it...?

Is there any other way to load in my two scripts in a way that I can be completely sure that one of them is loading before the other?

Any help here would be hot! :D

Thanks

Henrik

Picture of Oliver Foster
Re: Draggable with GSAP not working
by Oliver Foster - Friday, 2 June 2017, 7:14 PM
 

Hej Henrik,

Require normally works by having each library independently declare its own dependencies, as such, it becomes a little harder to declare dependencies after the libraries have been published.

You've a few options.

1. You can use Modernizr.load as is used in the core/src/scriptLoader.js

2. You can nest a require statement inside your define (require example)

3. You can try using require.config({ shim: { lib1: { deps: [ 'lib2' ] } } }); 

4. You can edit the library and add the correct dependency to its define statement
    

I hope that helps.

 

Ollie