Skip to content

Instantly share code, notes, and snippets.

@jstott
Forked from evanlarsen/transitionHelper.js
Last active December 3, 2018 16:13
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jstott/6326038 to your computer and use it in GitHub Desktop.
Save jstott/6326038 to your computer and use it in GitHub Desktop.
define(['durandal/system', './transitionHelper'], function(system, helper) {
var settings = {
inAnimation: 'fadeInLeftBig',
outAnimation: 'fadeOutRight'
},
fadeIn = function(context) {
system.extend(context, settings);
return helper.create(context);
};
return fadeIn;
});
define(['durandal/system', 'jquery'], function (system, $) {
var animationTypes = [
'bounce',
'bounceIn',
'bounceInDown',
'bounceInLeft',
'bounceInRight',
'bounceInUp',
'bounceOut',
'bounceOutDown',
'bounceOutLeft',
'bounceOutRight',
'bounceOutUp',
'fadeIn',
'fadeInDown',
'fadeInDownBig',
'fadeInLeft',
'fadeInLeftBig',
'fadeInRight',
'fadeInRightBig',
'fadeInUp',
'fadeInUpBig',
'fadeOut',
'fadeOutDown',
'fadeOutDownBig',
'fadeOutLeft',
'fadeOutLeftBig',
'fadeOutRight',
'fadeOutRightBig',
'fadeOutUp',
'fadeOutUpBig',
'flash',
'flip',
'flipInX',
'flipInY',
'flipOutX',
'flipOutY',
'hinge',
'lightSpeedIn',
'lightSpeedOut',
'pulse',
'rollIn',
'rollOut',
'rotateIn',
'rotateInDownLeft',
'rotateInDownRight',
'rotateInUpLeft',
'rotateInUpRight',
'rotateOut',
'rotateOutDownLeft',
'rotateOutDownRight',
'rotateOutUpLeft',
'roateOutUpRight',
'shake',
'swing',
'tada',
'wiggle',
'wobble'
];
return App = {
duration: 1000 * .35, // seconds
create: function (settings) {
settings = ensureSettings(settings);
return doTrans(settings);
}
};
function animValue(type) {
return Object.prototype.toString.call(type) == '[object String]' ? type : animationTypes[type];
}
function ensureSettings(settings) {
settings.inAnimation = settings.inAnimation || 'fadeInRight';
settings.outAnimation = settings.outAnimation || 'fadeOut';
return settings;
}
function doTrans(settings) {
var activeView = settings.activeView,
newChild = settings.child,
outAn = animValue(settings.outAnimation),
inAn = animValue(settings.inAnimation),
$previousView,
$newView = $(newChild).removeClass([outAn, inAn]).addClass('animated');
return system.defer(function (dfd) {
if (newChild) {
startTransition();
} else {
endTransistion();
}
function startTransition() {
if (settings.activeView) {
outTransition(inTransition);
} else {
inTransition();
}
}
function outTransition(callback) {
$previousView = $(activeView);
$previousView.addClass('animated');
$previousView.addClass(outAn);
setTimeout(function () {
if (callback) {
callback();
endTransistion();
}
}, App.duration);
}
function inTransition() {
settings.triggerAttach();
$newView.css('display', '');
$newView.addClass(inAn);
setTimeout(function () {
$newView.removeClass(inAn + ' ' + outAn + ' animated');
endTransistion();
}, App.duration);
}
function endTransistion() {
dfd.resolve();
}
}).promise();
}
});
@jstott
Copy link
Author

jstott commented Aug 24, 2013

This was updated from evanlarsen gist sample, for Durandjs v2.0

The setup is the same, place the transitionHelper.js and fadeIn.js in the durandal/transitions folder (depending on your config, the folder might be in durandal/js/transitions - check your main.js paths configuration).

The transition would go something like this: <div class="container-fluid page-host" data-bind="router: { transition:'fadeIn', cacheViews:true }"></div>

As before - use the pattern above in the fadeIn.js file for any other animations you wish to use. Don't forget to include the animation.css

I'm still testing this - and will be back to update & clean up the gist.

@sheepsteak
Copy link

EDIT: Actually this still doesn't work properly for me.

This didn't work for me. I finally got it working using the below. It seems new views have their display style set to 'none' which tripped me up. I noticed the 'entrance' transition sets this to 'block' and then clears it at the end. So that it doesn't interfere with the CSS3 animations I clear it at the beginning.

I also stripped out the JS fallback stuff as I don't need that.

The below isn't perfect and I've altered my duration; you'll probably need to tweak it

define(['durandal/system', 'jquery'], function(system, $) {

  return App = {
    duration: 1000 * .35, // seconds
    create: function(settings) {
      settings = ensureSettings(settings);
      return doTrans(settings);
    }
  };

  function animValue(type) {
    if (Object.prototype.toString.call(type) == '[object String]') {
      return type;
    } else {
      return animationTypes[type];
    }
  }

  function ensureSettings(settings) {
    settings.inAnimation = settings.inAnimation || 'fadeInRight';
    settings.outAnimation = settings.outAnimation || 'fadeOut';
    return settings;
  }

  function doTrans(settings) {
    var parent = settings.parent,
      activeView = settings.activeView,
      newChild = settings.child,
      outAn = animValue(settings.outAnimation),
      inAn = animValue(settings.inAnimation),
      $previousView,
      $newView = $(newChild).removeClass([outAn, inAn]).addClass('animated');

    return system.defer(function(dfd) {
      if (newChild) {

        $newView = $(newChild);
        if (settings.activeView) {
          outTransition(inTransition);
        } else {
          inTransition();
        }
      }

      function outTransition(callback) {
        $previousView = $(activeView);
        $previousView.addClass('animated')
        $previousView.addClass(outAn);
        setTimeout(function() {
          //$previousView.hide();
          //$previousView.removeClass(outAn + ' animated');
          if (callback) {
            callback();
          }
        }, App.duration);
      }

      function inTransition() {
        settings.triggerAttach();
        $newView.css('display', '');
        $newView.addClass(inAn);

        setTimeout(function() {
          $newView.removeClass(inAn + ' ' + outAn + ' animated');
          dfd.resolve(true);
        }, App.duration);
      }

    }).promise();
  }
});

@jstott
Copy link
Author

jstott commented Sep 13, 2013

Thanks for the feedback Sheepsteak, I updated with your changes plus a little a little more re-factoring I had done.

@LayZeeDK
Copy link

This works in Durandal 2.0.1 except when using cacheViews: true, which will make views stick around if you navigate too fast (before the animation's finished, I think).

@jiggle
Copy link

jiggle commented Jan 24, 2014

I still couldn't get it to work either LayzeeDK with cacheViews:true, but I think I have figured it out now: (version 2.0.1), animate taken from http://daneden.me/animate today, and animation settings in animate.css changed to:

.animated {
  -webkit-animation-duration:0.35s;
  animation-duration: 0.35s;
  -webkit-animation-fill-mode: both;
  animation-fill-mode: both;
}
    define(['durandal/system', 'jquery'], function (system, $) {

    return App = {
        duration: 1000 * .35, // seconds
        create: function (settings) {
            settings = ensureSettings(settings);
            return doTrans(settings);
        }
    };

    function animValue(type) {
        if (Object.prototype.toString.call(type) == '[object String]') {
            return type;
        } else {
            return animationTypes[type];
        }
    }

    function ensureSettings(settings) {
        settings.inAnimation = settings.inAnimation || 'fadeInRight';
        settings.outAnimation = settings.outAnimation || 'fadeOut';
        return settings;
    }

    function doTrans(settings) {
        var parent = settings.parent,
          activeView = settings.activeView,
          newChild = settings.child,
          outAn = animValue(settings.outAnimation),
          inAn = animValue(settings.inAnimation),
          $previousView,
          $newView = $(newChild).removeClass(outAn); // just need to remove outAn here, keeping the animated class so we don't get a "flash"

        return system.defer(function (dfd) {
            if (newChild) {

                $newView = $(newChild);
                if (settings.activeView) {
                    outTransition(inTransition);
                } else {
                    inTransition();
                }
            }

            function outTransition(callback) {
                $previousView = $(activeView);
                $previousView.addClass('animated')
                $previousView.addClass(outAn);
                setTimeout(function () {
                    if (callback) {
                        callback();
                    }
                }, App.duration);
            }

            function inTransition() {
                if ($previousView) {
                    $previousView.css('display', 'none');
                }
                settings.triggerAttach();

                $newView.addClass('animated');  //moved the adding of the animated class here so it keeps it together
                $newView.addClass(inAn);
                $newView.css('display', '');

                setTimeout(function () {
                    $newView.removeClass(inAn + ' animated'); // just need to remove inAn here, that's all we'll have
                    dfd.resolve(true);
                }, App.duration);
            }

        }).promise();
    }
});

Thanks very much for the transition helper evanlarsen and jstott, it's great!!

@bestguy
Copy link

bestguy commented Jun 2, 2014

@jiggle - Thanks for this, works great! Thanks all for the samples here.

@sreerajeferns
Copy link

How do I apply a transition to a particular element rather than the whole document ?

@ShamanSC
Copy link

ShamanSC commented Apr 5, 2016

This is great thanks!!!

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