diff options
Diffstat (limited to 'node_modules/materialize-css/js/parallax.js')
-rw-r--r-- | node_modules/materialize-css/js/parallax.js | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/node_modules/materialize-css/js/parallax.js b/node_modules/materialize-css/js/parallax.js new file mode 100644 index 0000000000..998229739c --- /dev/null +++ b/node_modules/materialize-css/js/parallax.js @@ -0,0 +1,138 @@ +(function($) { + 'use strict'; + + let _defaults = { + responsiveThreshold: 0 // breakpoint for swipeable + }; + + class Parallax extends Component { + constructor(el, options) { + super(Parallax, el, options); + + this.el.M_Parallax = this; + + /** + * Options for the Parallax + * @member Parallax#options + * @prop {Number} responsiveThreshold + */ + this.options = $.extend({}, Parallax.defaults, options); + this._enabled = window.innerWidth > this.options.responsiveThreshold; + + this.$img = this.$el.find('img').first(); + this.$img.each(function() { + let el = this; + if (el.complete) $(el).trigger('load'); + }); + + this._updateParallax(); + this._setupEventHandlers(); + this._setupStyles(); + + Parallax._parallaxes.push(this); + } + + static get defaults() { + return _defaults; + } + + static init(els, options) { + return super.init(this, els, options); + } + + /** + * Get Instance + */ + static getInstance(el) { + let domElem = !!el.jquery ? el[0] : el; + return domElem.M_Parallax; + } + + /** + * Teardown component + */ + destroy() { + Parallax._parallaxes.splice(Parallax._parallaxes.indexOf(this), 1); + this.$img[0].style.transform = ''; + this._removeEventHandlers(); + + this.$el[0].M_Parallax = undefined; + } + + static _handleScroll() { + for (let i = 0; i < Parallax._parallaxes.length; i++) { + let parallaxInstance = Parallax._parallaxes[i]; + parallaxInstance._updateParallax.call(parallaxInstance); + } + } + + static _handleWindowResize() { + for (let i = 0; i < Parallax._parallaxes.length; i++) { + let parallaxInstance = Parallax._parallaxes[i]; + parallaxInstance._enabled = + window.innerWidth > parallaxInstance.options.responsiveThreshold; + } + } + + _setupEventHandlers() { + this._handleImageLoadBound = this._handleImageLoad.bind(this); + this.$img[0].addEventListener('load', this._handleImageLoadBound); + + if (Parallax._parallaxes.length === 0) { + Parallax._handleScrollThrottled = M.throttle(Parallax._handleScroll, 5); + window.addEventListener('scroll', Parallax._handleScrollThrottled); + + Parallax._handleWindowResizeThrottled = M.throttle(Parallax._handleWindowResize, 5); + window.addEventListener('resize', Parallax._handleWindowResizeThrottled); + } + } + + _removeEventHandlers() { + this.$img[0].removeEventListener('load', this._handleImageLoadBound); + + if (Parallax._parallaxes.length === 0) { + window.removeEventListener('scroll', Parallax._handleScrollThrottled); + window.removeEventListener('resize', Parallax._handleWindowResizeThrottled); + } + } + + _setupStyles() { + this.$img[0].style.opacity = 1; + } + + _handleImageLoad() { + this._updateParallax(); + } + + _updateParallax() { + let containerHeight = this.$el.height() > 0 ? this.el.parentNode.offsetHeight : 500; + let imgHeight = this.$img[0].offsetHeight; + let parallaxDist = imgHeight - containerHeight; + let bottom = this.$el.offset().top + containerHeight; + let top = this.$el.offset().top; + let scrollTop = M.getDocumentScrollTop(); + let windowHeight = window.innerHeight; + let windowBottom = scrollTop + windowHeight; + let percentScrolled = (windowBottom - top) / (containerHeight + windowHeight); + let parallax = parallaxDist * percentScrolled; + + if (!this._enabled) { + this.$img[0].style.transform = ''; + } else if (bottom > scrollTop && top < scrollTop + windowHeight) { + this.$img[0].style.transform = `translate3D(-50%, ${parallax}px, 0)`; + } + } + } + + /** + * @static + * @memberof Parallax + */ + Parallax._parallaxes = []; + + M.Parallax = Parallax; + + if (M.jQueryLoaded) { + M.initializeJqueryWrapper(Parallax, 'parallax', 'M_Parallax'); + } +})(cash); |