Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using ScrollMagic as an AMD module or shim #160

Closed
gabriel-amram opened this issue Sep 16, 2014 · 16 comments
Closed

Using ScrollMagic as an AMD module or shim #160

gabriel-amram opened this issue Sep 16, 2014 · 16 comments

Comments

@gabriel-amram
Copy link

Hello,
Is there a way to use the ScrollMagic plugin as an AMD module?
I see it defines two variables in the window level :
window.ScrollScene = ScrollScene;
window.ScrollMagic = ScrollMagic;

but using it with requirejs requires these to be defined otherwise.

Using requirejs shim syntax doesn't work because ScrollMagic exports 2 variables as far as I know. Is there a way to use ScrollMagic as an AMD module?

@janpaepke
Copy link
Owner

Without knowing too much about AMD it should go something like this:

define('ScrollMagic', ['ScrollScene'], function (ScrollScene) {
    return window.ScrollMagic;
});
define('ScrollScene', ['ScrollMagic'], function (ScrollMagic) {
    return window.ScrollScene;
});

I dunno - that's just a guess.
Feel free to figure it out and let me know.

@gabriel-amram
Copy link
Author

Hey, Thanks for the reply!
The problem with that approach as far as I know is that it makes me load jQuery, TweenMax and ScrollMagic outside of the requirejs loop.

Instead, I asked that question on StackOverflow and answered myself:
http://stackoverflow.com/questions/25867893/using-scrollmagic-js-as-amd-module

I forked the repo and hope to send you a pull request with full support for AMD modules soon (including module.exports for node hopefully).

Thanks again for the reply and that wonderful plugin!

@janpaepke
Copy link
Owner

All right, I'll leave this open for now. :)
Thanks for investigating this!

@krnlde
Copy link

krnlde commented Sep 23, 2014

Here is my scrollmagic require config:

;(function (window) {
  "use strict";
  require.config({
    waitSeconds: 360,
    baseUrl: '/tour/js/',
    paths: {
      when: 'lib/vendor/cujojs/when',
      TweenMax: 'lib/vendor/TweenMax.min'
    },
    shim: {
      IScroll: {
        exports: 'IScroll'
      },
      ScrollMagic: {
        deps: ['lib/vendor/jquery.scrollmagic.min', 'lib/vendor/animationFrame'],
        exports: 'ScrollMagic',
        init: function() {
          var instance;
          return {
            ScrollMagic: ScrollMagic,
            ScrollScene: ScrollScene,
            controller: function () {
              return instance || (instance = new ScrollMagic());
            }
          };
        }
      }
    }
  });
  require(['app']);
}(window));

Require ScrollMagic in your module like so:

require(['ScrollMagic', 'TweenMax', 'IScroll'], function (S, TweenMax, IScroll) {
  var controller = new ScrollMagic();
  // you can call "new ScrollMagic();" because it's a global variable.
});

There might be some improvement involved with this, since ScrollMagic is a global variable. Preferably extend it with the UMD pattern: https://github.com/umdjs/umd . Any thoughts Jan?

@janpaepke
Copy link
Owner

I will have to look into this some more.
So far I haven't really used require.js or the like.
Although I do understand the advantages...
I'll look into it...

janpaepke added a commit that referenced this issue Oct 14, 2014
Defined both modules using UMD.
They are now defined as browser globals as well as using the AMD
pattern.
See here for more info:
#160
@janpaepke
Copy link
Owner

ScrollMagic now uses the UMD pattern. It can be used as a browser global or defined with the AMD pattern.
Here's the code I used to get requirejs to load it:

require.config({
    baseUrl: '../ScrollMagic/js',
    paths: {
        TweenMax: '_dependent/greensock/TweenMax.min',
        TimelineMax: '_dependent/greensock/TweenMax.min',
        ScrollMagic: 'jquery.scrollmagic',
        ScrollScene: 'jquery.scrollmagic',
        "ScrollMagic.debug": 'jquery.scrollmagic.debug',
        jquery: '_dependent/jquery.min'
    }
});

require(['jquery', 'ScrollMagic', 'ScrollScene', 'ScrollMagic.debug'], function( $, ScrollMagic, ScrollScene, debug) {
    // do stuff
});

Have fun! :)

@krnlde
Copy link

krnlde commented Oct 14, 2014

Dear good Sir. You. Are. Awesome.

@janpaepke
Copy link
Owner

Haha - you're the one that made me learn about it.
I didn't have a clue about UMD and AMD, now I do and I understand them and see their value.

So thank you for that. :)

If you have tested it out I'd love some feedback that it works for you as well.
Just to make sure...

@krnlde
Copy link

krnlde commented Oct 14, 2014

Seems to work great at a first glance. I only find it a bit annoying that ScrollMagic is now begging for jQuery as a require-module, which is (together with require.js itself) the only module I load synchronously.
But I know there is already a TODO which will remove these kinda dependencies so no offense!

In the meantime my solution will be the following, suggested by this saviour:

define('jquery', function() {
    return jQuery;
});

@janpaepke
Copy link
Owner

Actually there's also an even bigger TODO on my list which is to remove the jQuery dependency all together.
It's actually only in there for convenience reasons but not out of necessity.
So stay tuned for a module version of ScrollMagic, where both jQuery and possibly TweenMax are optional additional AddOns to the core functionality.

@krnlde
Copy link

krnlde commented Nov 26, 2014

As of ScrollMagic v1.3.0 the behavior for require.js has changed a bit. You only need to load ScrollMagic as a single module which'll itself provide the ScrollMagic Controller and Scene Constructors.

Here's an example

require.config({
    baseUrl: '../ScrollMagic/js',
    paths: {
        TweenMax: '_dependent/greensock/TweenMax.min',
        TimelineMax: '_dependent/greensock/TweenMax.min',
        ScrollMagic: 'jquery.scrollmagic',
        jquery: '_dependent/jquery.min'
    }
});

require(['ScrollMagic'], function (ScrollMagic) {
    var controller = new ScrollMagic.Controller(/*...*/);
    var scene = new ScrollMagic.Scene(/*...*/);
});

Further information are described here: https://github.com/janpaepke/ScrollMagic/wiki/Getting-Started-:-Using-AMD

@colinory
Copy link

I'm trying to use ScrollMagic 1.3.0 with RequireJS. I've followed the getting started wiki. Still not working..

I get this error in the console:
Uncaught TypeError: Cannot read property 'Controller' of undefined

This is my requirejs config:

requirejs.config({
    "baseUrl": wp_path,
    "paths": {
      "app": "../app",
      "jquery": "//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min",
        "TweenMax": "//cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min",
        "TimelineMax": "//cdnjs.cloudflare.com/ajax/libs/gsap/latest/TimelineMax.min",
        "TweenLite": "//cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenLite.min",
        "cssplugin": "//cdnjs.cloudflare.com/ajax/libs/gsap/latest/plugins/CSSPlugin.min",
        "jqueryui": "//code.jquery.com/ui/1.11.1/jquery-ui.min",
        "ScrollMagic": "jquery.scrollmagic.min",
        "intense": "intense",
        "videobg": "jquery.videoBG",
        "placeholders": "placeholders",
        "viewportbuggyfill": "viewport-units-buggyfill"
    }
});

This is how I define them:

define(["jquery","jqueryui","intense","videobg","placeholders","viewportbuggyfill","TweenMax","TimelineMax","cssplugin","ScrollMagic"], function($, ScrollMagic) {

This is how I init the controller

        // init the controller
        var controller = new ScrollMagic.Controller({
            globalSceneOptions: {
                triggerHook: "onEnter"
            }, loglevel: 0

        });
        var intro_icon = new TimelineMax();
        intro_icon.add([
            TweenMax.to(".intro .icons", 2, { bottom:0, autoAlpha: 1, ease: Back.easeInOut, force3D: true})
        ]);
        var scene1 = new ScrollMagic.Scene({
            triggerElement: ".columns_container"
        })
            .setTween(intro_icon)
            .addTo(controller);

Am I doing something wrong?

@krnlde
Copy link

krnlde commented Nov 27, 2014

You have to fill every required module into the params of the callback like so:

define(["jquery","jqueryui","intense","videobg","placeholders","viewportbuggyfill","TweenMax","TimelineMax","cssplugin","ScrollMagic"], function($, jqueryui, intense, videobg, placeholders, viewportbuggyfill, TweenMax, TimelineMax, cssplugin, ScrollMagic) {
  // ...
});

The parameters of the callback have to match the length of the dependency array, since these values are linked/mapped to each other.

If there are libs you don't need as a param, just require them at the end and leave the param out, in your case for example jquery ui:

define(['jquery', 'jqueryui'], function ($) {
  // ...
});

@colinory
Copy link

Thanks! It's working. A bit off topic. I'm also using this line:

window.viewportUnitsBuggyfill.init();

Do I need to add window as well as a parameter? Because I'm getting this error :

Uncaught TypeError: Cannot read property 'init' of undefined

@krnlde
Copy link

krnlde commented Nov 27, 2014

Leave out the window. part when using requirejs, and write the variable the same way you wrote the function parameter.

@colinory
Copy link

It's working! Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants