barbajs / barba

Create badass, fluid and smooth transitions between your website’s pages
https://barba.js.org/
MIT License
11.59k stars 477 forks source link

Help with Transition #161

Closed davidelanfranchi closed 7 years ago

davidelanfranchi commented 7 years ago

Hello @luruke and hello everyone,

I can't manage to make the functions of my the promise queue follow the right order. Obviously, I'm not understanding something related to the deferred utility :). Do you have any advice?

This is my code:

  var PagesFooterTransition = Barba.BaseTransition.extend({
    start: function() {

      Promise
        .all([this.newContainerLoading, this.scrollToEnd()])
        .then(this.enlargeOverlay())
        .then(this.fadeOut())
        .then(this.fadeIn.bind(this));

    },

    scrollToEnd: function() {

      var deferred = Barba.Utils.deferred();

      console.log('scrollToEnd')

      var scrollInstance = Scroll.getInstance();

      if (scrollInstance.offset.x == scrollInstance.limit.x && scrollInstance.offset.y == scrollInstance.limit.y ) {
        console.log('scrollToEnd resolve')
        deferred.resolve();
      }else{
        scrollInstance.scrollTo(scrollInstance.limit.x, scrollInstance.limit.y, 1000, function () {
          console.log('scrollToEnd resolve')
         deferred.resolve();
        });
      }

      return deferred.promise;

    },

    enlargeOverlay: function(){

      var deferred = Barba.Utils.deferred();

      console.log('enlargeOverlay')

      var scrollLayout = Scroll.getScrollLayout();

      var $overlay = $(lastElementClicked).closest('.pages-footer').find('.pages-footer__overlay');

      if (scrollLayout == 'horizontal') {

        TweenLite.to($overlay, 1, {
          width: $(window).width(),
          onComplete: function() {
              console.log('enlargeOverlay resolve')
              deferred.resolve();
          } 
        });

      }else if (scrollLayout == 'vertical') {

        TweenLite.to($overlay, 1, {
          height: $(window).height(),
          onComplete: function() {
            console.log('enlargeOverlay resolve')
              deferred.resolve();
          } 
        });

      }

      return deferred.promise;

    },

    fadeOut: function() {

      var deferred = Barba.Utils.deferred();

      console.log('fadeOut')

      TweenLite.to(this.oldContainer, 1, {
        opacity: 0,
        onComplete: function() {
          console.log('fadeOut resolve')
            deferred.resolve();
        } 
      });

      return deferred.promise;

    },

    fadeIn: function() {

      console.log('fadeIn')

      var _this = this;
      var $el = $(this.newContainer);

      Scroll.update($el);
      Scroll.getInstance().setPosition(0,0);

      $(this.oldContainer).hide();

      $el.css({
        visibility : 'visible',
        opacity : 0
      });

      TweenLite.to($el, 1, {
        opacity: 1,
        onComplete: function() {
          console.log('fadeIn complete')
          _this.done();
        } 
      });

    },

  });

This is the log:

scrollToEnd
enlargeOverlay
fadeOut
enlargeOverlay resolve
fadeOut resolve
scrollToEnd resolve
fadeIn
fadeIn complete

The problem is that all the functions, with the exception of the last one, fire immediately and the transitions happen together.

The whole queue is fired together and it seems that the first 'deferred.resolve()' call fires the last function ('this.fadeIn.bind(this)'). I say this because in the 'scrollToEnd' function I check if the page is at the end. If the page is at the end the deferred.resolve() function fires immediately and the last function is called.

What I'm not seeing? :) Thanks for your help (and for your library ;))!

davidelanfranchi commented 7 years ago

Hello @luruke, you narrowed down my problem. The correct way to concatenate the promises:

Promise
        .all([this.newContainerLoading, this.scrollToEnd()])
        .then(this.enlargeOverlay)
        .then(this.fadeOut.bind(this))
        .then(this.fadeIn.bind(this));

Thanks again and have a good day!