first commit
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
// global sekFrontLocalized, nimbleListenTo
|
||||
/* ===================================================
|
||||
* jquery.fn.parallaxBg v1.0.0
|
||||
* Created in October 2018.
|
||||
* Inspired from https://github.com/presscustomizr/front-jquery-plugins/blob/master/jqueryParallax.js
|
||||
* ===================================================
|
||||
*/
|
||||
(function(w, d){
|
||||
var callbackFunc = function() {
|
||||
(function ( $, window ) {
|
||||
//defaults
|
||||
var pluginName = 'parallaxBg',
|
||||
defaults = {
|
||||
parallaxForce : 40,
|
||||
oncustom : [],//list of event here
|
||||
matchMedia : 'only screen and (max-width: 800px)'
|
||||
};
|
||||
|
||||
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 () {
|
||||
var self = this;
|
||||
//cache some element
|
||||
this.$_window = nb_.cachedElements.$window;
|
||||
this.doingAnimation = false;
|
||||
this.isVisible = false;
|
||||
this.isBefore = false;//the element is before the scroll point
|
||||
this.isAfter = true;// the element is after the scroll point
|
||||
|
||||
// normalize the parallax ratio
|
||||
// must be a number 0 > ratio > 100
|
||||
if ( 'number' !== typeof( self.options.parallaxForce ) || self.options.parallaxForce < 0 ) {
|
||||
if ( sekFrontLocalized.isDevMode ) {
|
||||
console.log('parallaxBg => the provided parallaxForce is invalid => ' + self.options.parallaxForce );
|
||||
}
|
||||
self.options.parallaxForce = this._defaults.parallaxForce;
|
||||
}
|
||||
if ( self.options.parallaxForce > 100 ) {
|
||||
self.options.parallaxForce = 100;
|
||||
}
|
||||
|
||||
//the scroll event gets throttled with the requestAnimationFrame
|
||||
this.$_window.on( 'scroll', function(_evt) { self.maybeParallaxMe(_evt); } );
|
||||
//debounced resize event
|
||||
this.$_window.on( 'resize', nb_.debounce( function(_evt) {
|
||||
self.maybeParallaxMe(_evt);
|
||||
}, 100 ) );
|
||||
|
||||
//on load
|
||||
this.checkIfIsVisibleAndCacheProperties();
|
||||
this.setTopPositionAndBackgroundSize();
|
||||
};
|
||||
|
||||
//@see https://www.paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/
|
||||
Plugin.prototype.setTopPositionAndBackgroundSize = 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 ( nb_.isFunction( window.matchMedia ) && matchMedia( self.options.matchMedia ).matches ) {
|
||||
this.element.css({'background-position-y' : '', 'background-attachment' : '' });
|
||||
return;
|
||||
}
|
||||
|
||||
var $element = this.element,
|
||||
elemHeight = $element.outerHeight(),
|
||||
winHeight = this.$_window.height(),
|
||||
offsetTop = $element.offset().top,
|
||||
scrollTop = this.$_window.scrollTop(),
|
||||
percentOfPage = 100;
|
||||
|
||||
// the percentOfPage can vary from -1 to 1
|
||||
if ( this.isVisible ) {
|
||||
//percentOfPage = currentDistanceToMiddleScreen / maxDistanceToMiddleScreen;
|
||||
percentOfPage = ( offsetTop - scrollTop ) / winHeight;
|
||||
} else if ( this.isBefore ) {
|
||||
percentOfPage = 1;
|
||||
} else if ( this.isAfter ) {
|
||||
percentOfPage = - 1;
|
||||
}
|
||||
|
||||
var maxBGYMove = this.options.parallaxForce > 0 ? winHeight * ( 100 - this.options.parallaxForce ) / 100 : winHeight,
|
||||
bgPositionY = Math.round( percentOfPage * maxBGYMove );
|
||||
|
||||
this.element.css({
|
||||
'background-position-y' : [
|
||||
'calc(50% ',
|
||||
bgPositionY > 0 ? '+ ' : '- ',
|
||||
Math.abs( bgPositionY ) + 'px)'
|
||||
].join('')
|
||||
});
|
||||
};
|
||||
|
||||
// When does the image enter the viewport ?
|
||||
Plugin.prototype.checkIfIsVisibleAndCacheProperties = function( _evt ) {
|
||||
var $element = this.element;
|
||||
// bail if the level is display:none;
|
||||
// because $.offset() won't work
|
||||
// see because of https://github.com/presscustomizr/nimble-builder/issues/363
|
||||
if ( ! $element.is(':visible') )
|
||||
return false;
|
||||
|
||||
var scrollTop = this.$_window.scrollTop(),
|
||||
wb = scrollTop + this.$_window.height(),
|
||||
offsetTop = $element.offset().top,
|
||||
ib = offsetTop + $element.outerHeight();
|
||||
|
||||
// Cache now
|
||||
this.isVisible = ib >= scrollTop && offsetTop <= wb;
|
||||
this.isBefore = offsetTop > wb ;//the element is before the scroll point
|
||||
this.isAfter = ib < scrollTop;// the element is after the scroll point
|
||||
return this.isVisible;
|
||||
};
|
||||
|
||||
// a throttle is implemented with window.requestAnimationFrame
|
||||
Plugin.prototype.maybeParallaxMe = function(evt) {
|
||||
var self = this;
|
||||
if ( ! this.checkIfIsVisibleAndCacheProperties() )
|
||||
return;
|
||||
|
||||
if ( ! this.doingAnimation ) {
|
||||
this.doingAnimation = true;
|
||||
window.requestAnimationFrame(function() {
|
||||
self.setTopPositionAndBackgroundSize();
|
||||
self.doingAnimation = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 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 );
|
||||
};/////////////// callbackFunc
|
||||
|
||||
// on 'nb-app-ready', jQuery is loaded
|
||||
nb_.listenTo('nb-app-ready', function(){
|
||||
callbackFunc();
|
||||
nb_.emit('nb-parallax-parsed');
|
||||
});
|
||||
}(window, document));
|
||||
Reference in New Issue
Block a user