166 lines
7.0 KiB
JavaScript
Executable File
166 lines
7.0 KiB
JavaScript
Executable File
|
|
/* ===================================================
|
|
* jqueryParallax.js v1.0.0
|
|
* ===================================================
|
|
* (c) 2016 Nicolas Guillaume - Rocco Aliberti, Nice, France
|
|
* CenterImages plugin may be freely distributed under the terms of the GNU GPL v2.0 or later license.
|
|
*
|
|
* License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
|
*
|
|
*
|
|
*
|
|
* =================================================== */
|
|
(function ( $, window, _ ) {
|
|
//defaults
|
|
var pluginName = 'czrParallax',
|
|
defaults = {
|
|
parallaxRatio : 0.5,
|
|
parallaxDirection : 1,
|
|
parallaxOverflowHidden : true,
|
|
oncustom : [],//list of event here
|
|
backgroundClass : 'image',
|
|
matchMedia : 'only screen and (max-width: 768px)'
|
|
};
|
|
|
|
function Plugin( element, options ) {
|
|
this.element = $(element);
|
|
this.element_wrapper = this.element.closest( '.parallax-wrapper' );
|
|
this.options = $.extend( {}, defaults, options, this.parseElementDataOptions() ) ;
|
|
this._defaults = defaults;
|
|
this._name = pluginName;
|
|
this.init();
|
|
}
|
|
|
|
Plugin.prototype.parseElementDataOptions = function () {
|
|
return this.element.data();
|
|
};
|
|
|
|
//can access this.element and this.option
|
|
//@return void
|
|
Plugin.prototype.init = function () {
|
|
//cache some element
|
|
this.$_document = $(document);
|
|
this.$_window = czrapp ? czrapp.$_window : $(window);
|
|
this.doingAnimation = false;
|
|
|
|
this.initWaypoints();
|
|
this.stageParallaxElements();
|
|
this._bind_evt();
|
|
};
|
|
|
|
//@return void
|
|
//map custom events if any
|
|
Plugin.prototype._bind_evt = function() {
|
|
//var _customEvt = _.isArray(this.options.oncustom) ? this.options.oncustom : this.options.oncustom.split(' ');
|
|
|
|
_.bindAll( this, 'maybeParallaxMe', 'parallaxMe' );
|
|
/* TODO: custom events? */
|
|
};
|
|
|
|
Plugin.prototype.stageParallaxElements = function() {
|
|
|
|
this.element.css({
|
|
'position': this.element.hasClass( this.options.backgroundClass ) ? 'absolute' : 'relative',
|
|
'will-change': 'transform'
|
|
});
|
|
|
|
if ( this.options.parallaxOverflowHidden ){
|
|
var $_wrapper = this.element_wrapper;
|
|
if ( $_wrapper.length )
|
|
$_wrapper.css( 'overflow', 'hidden' );
|
|
}
|
|
};
|
|
|
|
Plugin.prototype.initWaypoints = function() {
|
|
var self = this;
|
|
|
|
this.way_start = new Waypoint({
|
|
element: self.element_wrapper.length ? self.element_wrapper : self.element,
|
|
handler: function() {
|
|
self.maybeParallaxMe();
|
|
if ( ! self.element.hasClass('parallaxing') ){
|
|
self.$_window.on('scroll', self.maybeParallaxMe );
|
|
self.element.addClass('parallaxing');
|
|
} else{
|
|
self.element.removeClass('parallaxing');
|
|
self.$_window.off('scroll', self.maybeParallaxMe );
|
|
self.doingAnimation = false;
|
|
self.element.css('top', 0 );
|
|
}
|
|
}
|
|
});
|
|
|
|
this.way_stop = new Waypoint({
|
|
element: self.element_wrapper.length ? self.element_wrapper : self.element,
|
|
handler: function() {
|
|
self.maybeParallaxMe();
|
|
if ( ! self.element.hasClass('parallaxing') ) {
|
|
self.$_window.on('scroll', self.maybeParallaxMe );
|
|
self.element.addClass('parallaxing');
|
|
}else {
|
|
self.element.removeClass('parallaxing');
|
|
self.$_window.off('scroll', self.maybeParallaxMe );
|
|
self.doingAnimation = false;
|
|
}
|
|
},
|
|
offset: function(){
|
|
//offset = this.context.innerHeight() - this.adapter.outerHeight();
|
|
//return - ( offset > 20 /* possible wrong h scrollbar */ ? offset : this.context.innerHeight() );
|
|
return - this.adapter.outerHeight();
|
|
}
|
|
});
|
|
};
|
|
|
|
/*
|
|
* In order to handle a smooth scroll
|
|
*/
|
|
Plugin.prototype.maybeParallaxMe = function() {
|
|
var self = this;
|
|
//options.matchMedia is set to 'only screen and (max-width: 768px)' by default
|
|
//if a match is found, then reset the top position
|
|
if ( _.isFunction( window.matchMedia ) && matchMedia( self.options.matchMedia ).matches )
|
|
return this.setTopPosition();
|
|
|
|
if ( ! this.doingAnimation ) {
|
|
this.doingAnimation = true;
|
|
window.requestAnimationFrame(function() {
|
|
self.parallaxMe();
|
|
self.doingAnimation = false;
|
|
});
|
|
}
|
|
};
|
|
|
|
//@see https://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/
|
|
Plugin.prototype.setTopPosition = function( _top_ ) {
|
|
_top_ = _top_ || 0;
|
|
this.element.css({
|
|
'transform' : 'translate3d(0px, ' + _top_ + 'px, .01px)',
|
|
'-webkit-transform' : 'translate3d(0px, ' + _top_ + 'px, .01px)'
|
|
//top: _top_
|
|
});
|
|
};
|
|
|
|
Plugin.prototype.parallaxMe = function() {
|
|
//parallax only the current slide if in slider context?
|
|
/*
|
|
if ( ! ( this.element.hasClass( 'is-selected' ) || this.element.parent( '.is-selected' ).length ) )
|
|
return;
|
|
*/
|
|
|
|
var ratio = this.options.parallaxRatio,
|
|
parallaxDirection = this.options.parallaxDirection,
|
|
value = ratio * parallaxDirection * ( this.$_document.scrollTop() - this.way_start.triggerPoint );
|
|
this.setTopPosition( parallaxDirection * value < 0 ? 0 : value );
|
|
};
|
|
|
|
|
|
// prevents against multiple instantiations
|
|
$.fn[pluginName] = function ( options ) {
|
|
return this.each(function () {
|
|
if (!$.data(this, 'plugin_' + pluginName)) {
|
|
$.data(this, 'plugin_' + pluginName,
|
|
new Plugin( this, options ));
|
|
}
|
|
});
|
|
};
|
|
})( jQuery, window, _ ); |