Add transitions for content block addition and removal

This commit is contained in:
Tautvidas Sipavičius
2015-12-02 17:54:06 +02:00
parent 916fe76795
commit 97d1e95037
7 changed files with 155 additions and 10 deletions

View File

@ -30,3 +30,8 @@ $block-hover-highlight-color = $primary-active-color
.mailpoet_content .mailpoet_content
position: relative position: relative
.mailpoet_block_transition_in
animation-fade-in-and-scale-up()
.mailpoet_block_transition_out
animation-fade-out-and-scale-down()

View File

@ -79,3 +79,4 @@ $three-column-width = ($newsletter-width / 3) - (2 * $column-margin)
box-shadow(inset 1px 2px 1px $primary-inactive-color) box-shadow(inset 1px 2px 1px $primary-inactive-color)
color: #656565 color: #656565
border-radius(3px) border-radius(3px)
animation-background-color()

View File

@ -7,3 +7,45 @@ animation-slide-open-downwards()
max-height: 0 max-height: 0
opacity: 0 opacity: 0
overflow-y: hidden overflow-y: hidden
animation-background-color()
transition: background 300ms cubic-bezier(0.420, 0.000, 0.580, 1.000) /* ease-in-out */
animation-fade-in-and-scale-up()
animation-name: fadeInAndScaleUp
animation-duration: 500ms
animation-fill-mode: forwards
animation-fade-out-and-scale-down()
animation-name: fadeOutAndScaleDown
animation-duration: 500ms
animation-fill-mode: forwards
@keyframes fadeInAndScaleUp {
0% {
opacity: 0.3
max-height: 0
overflow: hidden
}
100% {
opacity: 1
max-height: 5000px
overflow: hidden
}
}
@keyframes fadeOutAndScaleDown {
0% {
opacity: 1
max-height: 5000px
overflow: hidden
}
100% {
opacity: 0.3
max-height: 0
overflow: hidden
}
}

View File

@ -48,6 +48,7 @@ define([
}, },
modelEvents: { modelEvents: {
'change': 'render', 'change': 'render',
'delete': 'deleteBlock',
}, },
events: { events: {
"mouseenter": "showTools", "mouseenter": "showTools",
@ -88,7 +89,9 @@ define([
this.$el.addClass('mailpoet_editor_view_' + this.cid); this.$el.addClass('mailpoet_editor_view_' + this.cid);
}, },
initialize: function() { initialize: function() {
this.on('showSettings', this.showSettings); this.on('showSettings', this.showSettings, this);
this.on('dom:refresh', this.showBlock, this);
this._isFirstRender = true;
}, },
showTools: function(_event) { showTools: function(_event) {
if (!this.showingToolsDisabled) { if (!this.showingToolsDisabled) {
@ -121,6 +124,36 @@ define([
return newModel; return newModel;
}; };
}, },
showBlock: function() {
console.log('Show block', arguments, this);
if (this._isFirstRender) {
this.transitionIn();
this._isFirstRender = false;
}
},
deleteBlock: function() {
this.transitionOut().done(function() {
this.model.destroy();
}.bind(this));
},
transitionIn: function() {
return this._transition('mailpoet_block_transition_in');
},
transitionOut: function() {
return this._transition('mailpoet_block_transition_out');
},
_transition: function(className) {
var that = this,
promise = jQuery.Deferred();
this.$el.addClass(className);
this.$el.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd animationend', function() {
that.$el.removeClass('mailpoet_block_transition_out');
promise.resolve();
console.log('Transition fired', arguments, this);
});
return promise;
},
}); });
Module.BlockToolsView = AugmentedView.extend({ Module.BlockToolsView = AugmentedView.extend({
@ -168,9 +201,9 @@ define([
}, },
deleteBlock: function(event) { deleteBlock: function(event) {
event.preventDefault(); event.preventDefault();
this.model.destroy(); this.model.trigger('delete');
return false; return false;
} },
}); });
Module.BlockSettingsView = Marionette.LayoutView.extend({ Module.BlockSettingsView = Marionette.LayoutView.extend({

View File

@ -42,16 +42,12 @@ define([
Module.ButtonBlockView = base.BlockView.extend({ Module.ButtonBlockView = base.BlockView.extend({
className: "mailpoet_block mailpoet_button_block mailpoet_droppable_block", className: "mailpoet_block mailpoet_button_block mailpoet_droppable_block",
getTemplate: function() { return templates.buttonBlock; }, getTemplate: function() { return templates.buttonBlock; },
modelEvents: {
'change': 'render',
},
onDragSubstituteBy: function() { return Module.ButtonWidgetView; }, onDragSubstituteBy: function() { return Module.ButtonWidgetView; },
initialize: function() { initialize: function() {
base.BlockView.prototype.initialize.apply(this, arguments); base.BlockView.prototype.initialize.apply(this, arguments);
var that = this;
// Listen for attempts to change all dividers in one go // Listen for attempts to change all dividers in one go
this._replaceButtonStylesHandler = function(data) { that.model.set(data); }; this._replaceButtonStylesHandler = function(data) { this.model.set(data); }.bind(this);
App.getChannel().on('replaceAllButtonStyles', this._replaceButtonStylesHandler); App.getChannel().on('replaceAllButtonStyles', this._replaceButtonStylesHandler);
}, },
onRender: function() { onRender: function() {

View File

@ -75,7 +75,8 @@ define([
getEmptyView: function() { return Module.ContainerBlockEmptyView; }, getEmptyView: function() { return Module.ContainerBlockEmptyView; },
emptyViewOptions: function() { return { renderOptions: this.renderOptions }; }, emptyViewOptions: function() { return { renderOptions: this.renderOptions }; },
modelEvents: { modelEvents: {
'change': 'render' 'change': 'render',
'delete': 'deleteBlock',
}, },
events: { events: {
"mouseenter": "showTools", "mouseenter": "showTools",
@ -136,6 +137,8 @@ define([
}, },
initialize: function(options) { initialize: function(options) {
this.renderOptions = _.defaults(options.renderOptions || {}, {}); this.renderOptions = _.defaults(options.renderOptions || {}, {});
this.on('dom:refresh', this.showBlock, this);
this._isFirstRender = true;
}, },
// Determines which view type should be used for a child // Determines which view type should be used for a child
getChildView: function(model) { getChildView: function(model) {
@ -236,6 +239,36 @@ define([
return newModel; return newModel;
}; };
}, },
showBlock: function() {
console.log('Show block', arguments, this);
if (this._isFirstRender) {
this.transitionIn();
this._isFirstRender = false;
}
},
deleteBlock: function() {
this.transitionOut().done(function() {
this.model.destroy();
}.bind(this));
},
transitionIn: function() {
return this._transition('mailpoet_block_transition_in');
},
transitionOut: function() {
return this._transition('mailpoet_block_transition_out');
},
_transition: function(className) {
var that = this,
promise = jQuery.Deferred();
this.$el.addClass(className);
this.$el.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd animationend', function() {
that.$el.removeClass('mailpoet_block_transition_out');
promise.resolve();
console.log('Transition fired', arguments, this);
});
return promise;
},
}); });
Module.ContainerBlockEmptyView = Marionette.ItemView.extend({ Module.ContainerBlockEmptyView = Marionette.ItemView.extend({

View File

@ -103,7 +103,8 @@ define([
getTemplate: function() { return templates.socialBlock; }, getTemplate: function() { return templates.socialBlock; },
childViewContainer: '.mailpoet_social', childViewContainer: '.mailpoet_social',
modelEvents: { modelEvents: {
'change': 'render' 'change': 'render',
'delete': 'deleteBlock',
}, },
events: { events: {
"mouseover": "showTools", "mouseover": "showTools",
@ -145,6 +146,10 @@ define([
arguments[0].collection = arguments[0].model.get('icons'); arguments[0].collection = arguments[0].model.get('icons');
Marionette.CompositeView.apply(this, arguments); Marionette.CompositeView.apply(this, arguments);
}, },
initialize: function() {
this.on('dom:refresh', this.showBlock, this);
this._isFirstRender = true;
},
// Determines which view type should be used for a child // Determines which view type should be used for a child
childView: SocialIconView, childView: SocialIconView,
templateHelpers: function() { templateHelpers: function() {
@ -194,6 +199,36 @@ define([
this.regionManager.destroy(); this.regionManager.destroy();
_.extend(this, this._buildRegions(this.regions)); _.extend(this, this._buildRegions(this.regions));
}, },
showBlock: function() {
console.log('Show block', arguments, this);
if (this._isFirstRender) {
this.transitionIn();
this._isFirstRender = false;
}
},
deleteBlock: function() {
this.transitionOut().done(function() {
this.model.destroy();
}.bind(this));
},
transitionIn: function() {
return this._transition('mailpoet_block_transition_in');
},
transitionOut: function() {
return this._transition('mailpoet_block_transition_out');
},
_transition: function(className) {
var that = this,
promise = jQuery.Deferred();
this.$el.addClass(className);
this.$el.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd animationend', function() {
that.$el.removeClass('mailpoet_block_transition_out');
promise.resolve();
console.log('Transition fired', arguments, this);
});
return promise;
},
}); });
Module.SocialBlockToolsView = base.BlockToolsView.extend({ Module.SocialBlockToolsView = base.BlockToolsView.extend({