Skip to content

Instantly share code, notes, and snippets.

@jasonLaster
Last active August 29, 2015 13:57
Show Gist options
  • Save jasonLaster/9794836 to your computer and use it in GitHub Desktop.
Save jasonLaster/9794836 to your computer and use it in GitHub Desktop.
var AnimationRegion = Backbone.Marionette.Region.extend({
innerRegionSelector: '.inner-page-region',
setLayout: function(layout, animationClass) {
this.regionAnimationClass = animationClass;
if (this.currentLayout) {
this.swap(layout);
} else {
this.currentLayout = layout;
this.show(layout);
}
},
swap: function(layout) {
if (this.transitioning) {
return;
}
this.newLayout = layout;
layout.render();
Backbone.Marionette.triggerMethod.call(layout, "before:show");
this.$el.append(layout.$el)
this.triggerReflow(this.$el);
this.setupTransitionEndHandler();
this.$el.toggleClass(this.regionAnimationClass);
this.$el.toggleClass('backwards');
},
setupTransitionEndHandler: function() {
this.transitioning = true;
var events = 'transitionend webkitTransitionEnd MSTransitionEnd oTransitionEnd';
var dfd = $.Deferred();
var context = this;
var shouldSwapRegion = function(e) {
return !$(e.target).is(this.innerRegionSelector);
}
var onTransitionEnd = function() {
if (!shouldSwapRegion.apply(context, arguments)) {
dfd.resolve();
}
}
dfd.always(_.bind(this.transitionEndCallback, this));
// TODO: add timeout fallback option
// transition shouldn't pend indefinitely
this.$el.on(events, onTransitionEnd);
return dfd;
},
// useful for making sure a property takes effect when setting more than once
// before any reflow happens. The implementation is not important. Just doing a read of a prop.
triggerReflow: function(el) {
window.getComputedStyle(el.get(0)).getPropertyValue('top');
},
transitionEndCallback = function() {
this.transitioning = false;
this.currentLayout.close();
this.currentLayout = this.newLayout;
this.newLayout = null;
this.$el.off(events, transitionEndCallback);
}
});
var AnimationRegion = Backbone.Marionette.Region.extend({
innerRegionSelector: '.inner-page-region',
setLayout: function(layout, animationClass) {
this.regionAnimationClass = animationClass;
if (this.currentLayout) {
this.swap(layout);
} else {
this.currentLayout = layout;
this.show(layout);
}
},
swap: function(layout) {
if (this.transitioning) {
return;
}
this.newLayout = layout;
layout.render();
Backbone.Marionette.triggerMethod.call(layout, "before:show");
this.$el.append(layout.$el)
this.triggerReflow(this.$el);
this.animateEl().always(_.bind(this.onTransitionComplete, this));
},
animateEl: function() {
this.transitioning = true;
this.$el.toggleClass(this.regionAnimationClass);
this.$el.toggleClass('backwards');
dfd = this.listenToTransitionEnd();
return dfd;
},
listenToTransitionEnd: function() {
var events = 'transitionend webkitTransitionEnd MSTransitionEnd oTransitionEnd';
var dfd = $.Deferred();
var context = this;
var shouldSwapRegion = function(e) {
return !$(e.target).is(this.innerRegionSelector);
}
var onTransitionEnd = function() {
if (!shouldSwapRegion.apply(context, arguments)) {
dfd.resolve();
}
}
this.$el.on(events, onTransitionEnd);
return dfd;
}
onTransitionComplete: function() {
this.transitioning = false;
this.currentLayout.close();
this.currentLayout = this.newLayout;
this.newLayout = null;
this.$el.off(events, transitionEndCallback);
},
// useful for making sure a property takes effect when setting more than once
// before any reflow happens. The implementation is not important. Just doing a read of a prop.
triggerReflow: function(el) {
window.getComputedStyle(el.get(0)).getPropertyValue('top');
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment