dark-overlay-sliding-menu-animator
Version:
Sliding menu animator for OnsenUI with a dark overlay.
252 lines (213 loc) • 7.13 kB
JavaScript
/**
* Dark Overlay Sliding Menu Animator.
*
* A modified version of the default sliding menu overlay animation
* for the OnsenUI framework. This version uses a darker overlay.
*
* OverlaySlidingMenuAnimator:
* https://github.com/OnsenUI/OnsenUI/blob/master/framework/views/overlaySlidingMenuAnimator.js
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
(function() {
'use strict';
var module = angular.module('onsen');
module.factory('DarkOverlaySlidingMenuAnimator', ['SlidingMenuAnimator', function(SlidingMenuAnimator) {
var DarkOverlaySlidingMenuAnimator = SlidingMenuAnimator.extend({
_blackMask: undefined,
_opacityModifier: 0.6,
_isRight: false,
_element: false,
_menuPage: false,
_mainPage: false,
_width: false,
_duration: false,
/**
* @param {jqLite} element "ons-sliding-menu" or "ons-split-view" element
* @param {jqLite} mainPage
* @param {jqLite} menuPage
* @param {Object} options
* @param {String} options.width "width" style value
* @param {Boolean} options.isRight
*/
setup: function(element, mainPage, menuPage, options) {
options = options || {};
this._width = options.width || '90%';
this._isRight = !!options.isRight;
this._element = element;
this._mainPage = mainPage;
this._menuPage = menuPage;
this._duration = 0.3;
menuPage.css({
width: options.width,
display: 'none',
zIndex: 2
});
mainPage.css({zIndex: 1});
if (this._isRight) {
menuPage.css({
right: '-' + options.width,
left: 'auto'
});
} else {
menuPage.css({
right: 'auto',
left: '-' + options.width
});
}
this._blackMask = angular.element('<div></div>').css({
backgroundColor: 'black',
top: '0px',
left: '0px',
right: '0px',
bottom: '0px',
position: 'absolute',
display: 'none',
zIndex: 0
});
element.prepend(this._blackMask);
},
/**
* @param {Object} options
* @param {String} options.width
*/
onResized: function(options) {
this._menuPage.css('width', options.width);
if (this._isRight) {
this._menuPage.css({
right: '-' + options.width,
left: 'auto'
});
} else {
this._menuPage.css({
right: 'auto',
left: '-' + options.width
});
}
if (options.isOpened) {
var max = this._menuPage[0].clientWidth;
var menuStyle = this._generateMenuPageStyle(max);
animit(this._menuPage[0]).queue(menuStyle).play();
}
},
/**
*/
destroy: function() {
if (this._blackMask) {
this._blackMask.remove();
this._blackMask = null;
}
this._mainPage.removeAttr('style');
this._menuPage.removeAttr('style');
this._element = this._mainPage = this._menuPage = null;
},
/**
* @param {Function} callback
* @param {Boolean} instant
*/
openMenu: function(callback, instant) {
var duration = instant === true ? 0.0 : this._duration;
this._menuPage.css('display', 'block');
this._blackMask.css('display', 'block');
var max = this._menuPage[0].clientWidth;
var menuStyle = this._generateMenuPageStyle(max);
var mainPageStyle = this._generateMainPageStyle(max);
setTimeout(function() {
animit(this._mainPage[0])
.queue(mainPageStyle, {
duration: duration,
timing: 'cubic-bezier(.1, .7, .1, 1)'
})
.queue(function(done) {
callback();
done();
})
.play();
animit(this._menuPage[0])
.queue(menuStyle, {
duration: duration,
timing: 'cubic-bezier(.1, .7, .1, 1)'
})
.play();
}.bind(this), 1000 / 60);
},
/**
* @param {Function} callback
* @param {Boolean} instant
*/
closeMenu: function(callback, instant) {
var duration = instant === true ? 0.0 : this._duration;
this._blackMask.css({display: 'block'});
var menuPageStyle = this._generateMenuPageStyle(0);
var mainPageStyle = this._generateMainPageStyle(0);
setTimeout(function() {
animit(this._mainPage[0])
.queue(mainPageStyle, {
duration: duration,
timing: 'cubic-bezier(.1, .7, .1, 1)'
})
.queue(function(done) {
this._menuPage.css('display', 'none');
callback();
done();
}.bind(this))
.play();
animit(this._menuPage[0])
.queue(menuPageStyle, {
duration: duration,
timing: 'cubic-bezier(.1, .7, .1, 1)'
})
.play();
}.bind(this), 1000 / 60);
},
/**
* @param {Object} options
* @param {Number} options.distance
* @param {Number} options.maxDistance
*/
translateMenu: function(options) {
this._menuPage.css('display', 'block');
this._blackMask.css({display: 'block'});
var menuPageStyle = this._generateMenuPageStyle(Math.min(options.maxDistance, options.distance));
var mainPageStyle = this._generateMainPageStyle(Math.min(options.maxDistance, options.distance));
delete mainPageStyle.opacity;
animit(this._menuPage[0])
.queue(menuPageStyle)
.play();
if (Object.keys(mainPageStyle).length > 0) {
animit(this._mainPage[0])
.queue(mainPageStyle)
.play();
}
},
_generateMenuPageStyle: function(distance) {
var x = this._isRight ? -distance : distance;
var transform = 'translate3d(' + x + 'px, 0, 0)';
return {
transform: transform
};
},
_generateMainPageStyle: function(distance) {
var max = this._menuPage[0].clientWidth;
var opacity = 1 - (this._opacityModifier * distance / max);
return {
opacity: opacity
};
},
copy: function() {
return new DarkOverlaySlidingMenuAnimator();
}
});
return DarkOverlaySlidingMenuAnimator;
}]);
})();