(function($, anim) { 'use strict'; let _defaults = { indicators: true, height: 400, duration: 500, interval: 6000 }; /** * @class * */ class Slider extends Component { /** * Construct Slider instance and set up overlay * @constructor * @param {Element} el * @param {Object} options */ constructor(el, options) { super(Slider, el, options); this.el.M_Slider = this; /** * Options for the modal * @member Slider#options * @prop {Boolean} [indicators=true] - Show indicators * @prop {Number} [height=400] - height of slider * @prop {Number} [duration=500] - Length in ms of slide transition * @prop {Number} [interval=6000] - Length in ms of slide interval */ this.options = $.extend({}, Slider.defaults, options); // setup this.$slider = this.$el.find('.slides'); this.$slides = this.$slider.children('li'); this.activeIndex = this.$slides .filter(function(item) { return $(item).hasClass('active'); }) .first() .index(); if (this.activeIndex != -1) { this.$active = this.$slides.eq(this.activeIndex); } this._setSliderHeight(); // Set initial positions of captions this.$slides.find('.caption').each((el) => { this._animateCaptionIn(el, 0); }); // Move img src into background-image this.$slides.find('img').each((el) => { let placeholderBase64 = 'data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='; if ($(el).attr('src') !== placeholderBase64) { $(el).css('background-image', 'url("' + $(el).attr('src') + '")'); $(el).attr('src', placeholderBase64); } }); this._setupIndicators(); // Show active slide if (this.$active) { this.$active.css('display', 'block'); } else { this.$slides.first().addClass('active'); anim({ targets: this.$slides.first()[0], opacity: 1, duration: this.options.duration, easing: 'easeOutQuad' }); this.activeIndex = 0; this.$active = this.$slides.eq(this.activeIndex); // Update indicators if (this.options.indicators) { this.$indicators.eq(this.activeIndex).addClass('active'); } } // Adjust height to current slide this.$active.find('img').each((el) => { anim({ targets: this.$active.find('.caption')[0], opacity: 1, translateX: 0, translateY: 0, duration: this.options.duration, easing: 'easeOutQuad' }); }); this._setupEventHandlers(); // auto scroll this.start(); } 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_Slider; } /** * Teardown component */ destroy() { this.pause(); this._removeIndicators(); this._removeEventHandlers(); this.el.M_Slider = undefined; } /** * Setup Event Handlers */ _setupEventHandlers() { this._handleIntervalBound = this._handleInterval.bind(this); this._handleIndicatorClickBound = this._handleIndicatorClick.bind(this); if (this.options.indicators) { this.$indicators.each((el) => { el.addEventListener('click', this._handleIndicatorClickBound); }); } } /** * Remove Event Handlers */ _removeEventHandlers() { if (this.options.indicators) { this.$indicators.each((el) => { el.removeEventListener('click', this._handleIndicatorClickBound); }); } } /** * Handle indicator click * @param {Event} e */ _handleIndicatorClick(e) { let currIndex = $(e.target).index(); this.set(currIndex); } /** * Handle Interval */ _handleInterval() { let newActiveIndex = this.$slider.find('.active').index(); if (this.$slides.length === newActiveIndex + 1) newActiveIndex = 0; // loop to start else newActiveIndex += 1; this.set(newActiveIndex); } /** * Animate in caption * @param {Element} caption * @param {Number} duration */ _animateCaptionIn(caption, duration) { let animOptions = { targets: caption, opacity: 0, duration: duration, easing: 'easeOutQuad' }; if ($(caption).hasClass('center-align')) { animOptions.translateY = -100; } else if ($(caption).hasClass('right-align')) { animOptions.translateX = 100; } else if ($(caption).hasClass('left-align')) { animOptions.translateX = -100; } anim(animOptions); } /** * Set height of slider */ _setSliderHeight() { // If fullscreen, do nothing if (!this.$el.hasClass('fullscreen')) { if (this.options.indicators) { // Add height if indicators are present this.$el.css('height', this.options.height + 40 + 'px'); } else { this.$el.css('height', this.options.height + 'px'); } this.$slider.css('height', this.options.height + 'px'); } } /** * Setup indicators */ _setupIndicators() { if (this.options.indicators) { this.$indicators = $('