var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } }; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } (function ($, anim) { 'use strict'; var _defaults = { inDuration: 275, outDuration: 200, onOpenStart: null, onOpenEnd: null, onCloseStart: null, onCloseEnd: null }; /** * @class * */ var Materialbox = function (_Component) { _inherits(Materialbox, _Component); /** * Construct Materialbox instance * @constructor * @param {Element} el * @param {Object} options */ function Materialbox(el, options) { _classCallCheck(this, Materialbox); var _this = _possibleConstructorReturn(this, (Materialbox.__proto__ || Object.getPrototypeOf(Materialbox)).call(this, Materialbox, el, options)); _this.el.M_Materialbox = _this; /** * Options for the modal * @member Materialbox#options * @prop {Number} [inDuration=275] - Length in ms of enter transition * @prop {Number} [outDuration=200] - Length in ms of exit transition * @prop {Function} onOpenStart - Callback function called before materialbox is opened * @prop {Function} onOpenEnd - Callback function called after materialbox is opened * @prop {Function} onCloseStart - Callback function called before materialbox is closed * @prop {Function} onCloseEnd - Callback function called after materialbox is closed */ _this.options = $.extend({}, Materialbox.defaults, options); _this.overlayActive = false; _this.doneAnimating = true; _this.placeholder = $('
').addClass('material-placeholder'); _this.originalWidth = 0; _this.originalHeight = 0; _this.originInlineStyles = _this.$el.attr('style'); _this.caption = _this.el.getAttribute('data-caption') || ""; // Wrap _this.$el.before(_this.placeholder); _this.placeholder.append(_this.$el); _this._setupEventHandlers(); return _this; } _createClass(Materialbox, [{ key: 'destroy', /** * Teardown component */ value: function destroy() { this._removeEventHandlers(); this.el.M_Materialbox = undefined; } /** * Setup Event Handlers */ }, { key: '_setupEventHandlers', value: function _setupEventHandlers() { this._handleMaterialboxClickBound = this._handleMaterialboxClick.bind(this); this.el.addEventListener('click', this._handleMaterialboxClickBound); } /** * Remove Event Handlers */ }, { key: 'removeEventHandlers', value: function removeEventHandlers() { this.el.removeEventListener('click', this._handleMaterialboxClickBound); } /** * Handle Materialbox Click * @param {Event} e */ }, { key: '_handleMaterialboxClick', value: function _handleMaterialboxClick(e) { // If already modal, return to original if (this.doneAnimating === false || this.overlayActive && this.doneAnimating) { this.close(); } else { this.open(); } } /** * Handle Window Scroll */ }, { key: '_handleWindowScroll', value: function _handleWindowScroll() { if (this.overlayActive) { this.close(); } } /** * Handle Window Resize */ }, { key: '_handleWindowResize', value: function _handleWindowResize() { if (this.overlayActive) { this.close(); } } /** * Handle Window Resize * @param {Event} e */ }, { key: '_handleWindowEscape', value: function _handleWindowEscape(e) { // ESC key if (e.keyCode === 27 && this.doneAnimating && this.overlayActive) { this.close(); } } /** * Find ancestors with overflow: hidden; and make visible */ }, { key: '_makeAncestorsOverflowVisible', value: function _makeAncestorsOverflowVisible() { this.ancestorsChanged = $(); var ancestor = this.placeholder[0].parentNode; while (ancestor !== null && !$(ancestor).is(document)) { var curr = $(ancestor); if (curr.css('overflow') !== 'visible') { curr.css('overflow', 'visible'); if (this.ancestorsChanged === undefined) { this.ancestorsChanged = curr; } else { this.ancestorsChanged = this.ancestorsChanged.add(curr); } } ancestor = ancestor.parentNode; } } /** * Animate image in */ }, { key: '_animateImageIn', value: function _animateImageIn() { var _this2 = this; var animOptions = { targets: this.el, height: this.newHeight, width: this.newWidth, left: M.getDocumentScrollLeft() + this.windowWidth / 2 - this.placeholder.offset().left - this.newWidth / 2, top: M.getDocumentScrollTop() + this.windowHeight / 2 - this.placeholder.offset().top - this.newHeight / 2, duration: this.options.inDuration, easing: 'easeOutQuad', complete: function () { _this2.doneAnimating = true; // onOpenEnd callback if (typeof _this2.options.onOpenEnd === 'function') { _this2.options.onOpenEnd.call(_this2, _this2.el); } } }; if (this.$el.hasClass('responsive-img')) { animOptions.maxWidth = this.newWidth; animOptions.width = [this.originalWidth, animOptions.width]; } else { animOptions.left = [animOptions.left, 0]; animOptions.top = [animOptions.top, 0]; } anim(animOptions); } /** * Animate image out */ }, { key: '_animateImageOut', value: function _animateImageOut() { var _this3 = this; var animOptions = { targets: this.el, width: this.originalWidth, height: this.originalHeight, left: 0, top: 0, duration: this.options.outDuration, easing: 'easeOutQuad', complete: function () { _this3.placeholder.css({ height: '', width: '', position: '', top: '', left: '' }); _this3.$el.removeAttr('style'); _this3.$el.attr('style', _this3.originInlineStyles); // Remove class _this3.$el.removeClass('active'); _this3.doneAnimating = true; // Remove overflow overrides on ancestors if (_this3.ancestorsChanged.length) { _this3.ancestorsChanged.css('overflow', ''); } // onCloseEnd callback if (typeof _this3.options.onCloseEnd === 'function') { _this3.options.onCloseEnd.call(_this3, _this3.el); } } }; anim(animOptions); } /** * Update open and close vars */ }, { key: '_updateVars', value: function _updateVars() { this.windowWidth = window.innerWidth; this.windowHeight = window.innerHeight; this.caption = this.el.getAttribute('data-caption') || ""; } /** * Open Materialbox */ }, { key: 'open', value: function open() { var _this4 = this; this._updateVars(); this.originalWidth = this.el.getBoundingClientRect().width; this.originalHeight = this.el.getBoundingClientRect().height; // Set states this.doneAnimating = false; this.$el.addClass('active'); this.overlayActive = true; // onOpenStart callback if (typeof this.options.onOpenStart === 'function') { this.options.onOpenStart.call(this, this.el); } // Set positioning for placeholder this.placeholder.css({ width: this.placeholder[0].getBoundingClientRect().width + 'px', height: this.placeholder[0].getBoundingClientRect().height + 'px', position: 'relative', top: 0, left: 0 }); this._makeAncestorsOverflowVisible(); // Set css on origin this.$el.css({ position: 'absolute', 'z-index': 1000, 'will-change': 'left, top, width, height' }); // Add overlay this.$overlay = $('').css({ opacity: 0 }).one('click', function () { if (_this4.doneAnimating) { _this4.close(); } }); // Put before in origin image to preserve z-index layering. this.$el.before(this.$overlay); // Set dimensions if needed var overlayOffset = this.$overlay[0].getBoundingClientRect(); this.$overlay.css({ width: this.windowWidth + 'px', height: this.windowHeight + 'px', left: -1 * overlayOffset.left + 'px', top: -1 * overlayOffset.top + 'px' }); anim.remove(this.el); anim.remove(this.$overlay[0]); if (this.caption !== "") { anim.remove(this.$photoCaption[0]); } // Animate Overlay anim({ targets: this.$overlay[0], opacity: 1, duration: this.options.inDuration, easing: 'easeOutQuad' }); // Add and animate caption if it exists if (this.caption !== "") { this.$photoCaption = $(''); this.$photoCaption.text(this.caption); $('body').append(this.$photoCaption); this.$photoCaption.css({ "display": "inline" }); anim({ targets: this.$photoCaption[0], opacity: 1, duration: this.options.inDuration, easing: 'easeOutQuad' }); } // Resize Image var ratio = 0; var widthPercent = this.originalWidth / this.windowWidth; var heightPercent = this.originalHeight / this.windowHeight; this.newWidth = 0; this.newHeight = 0; if (widthPercent > heightPercent) { ratio = this.originalHeight / this.originalWidth; this.newWidth = this.windowWidth * 0.9; this.newHeight = this.windowWidth * 0.9 * ratio; } else { ratio = this.originalWidth / this.originalHeight; this.newWidth = this.windowHeight * 0.9 * ratio; this.newHeight = this.windowHeight * 0.9; } this._animateImageIn(); // Handle Exit triggers this._handleWindowScrollBound = this._handleWindowScroll.bind(this); this._handleWindowResizeBound = this._handleWindowResize.bind(this); this._handleWindowEscapeBound = this._handleWindowEscape.bind(this); window.addEventListener('scroll', this._handleWindowScrollBound); window.addEventListener('resize', this._handleWindowResizeBound); window.addEventListener('keyup', this._handleWindowEscapeBound); } /** * Close Materialbox */ }, { key: 'close', value: function close() { var _this5 = this; this._updateVars(); this.doneAnimating = false; // onCloseStart callback if (typeof this.options.onCloseStart === 'function') { this.options.onCloseStart.call(this, this.el); } anim.remove(this.el); anim.remove(this.$overlay[0]); if (this.caption !== "") { anim.remove(this.$photoCaption[0]); } // disable exit handlers window.removeEventListener('scroll', this._handleWindowScrollBound); window.removeEventListener('resize', this._handleWindowResizeBound); window.removeEventListener('keyup', this._handleWindowEscapeBound); anim({ targets: this.$overlay[0], opacity: 0, duration: this.options.outDuration, easing: 'easeOutQuad', complete: function () { _this5.overlayActive = false; _this5.$overlay.remove(); } }); this._animateImageOut(); // Remove Caption + reset css settings on image if (this.caption !== "") { anim({ targets: this.$photoCaption[0], opacity: 0, duration: this.options.outDuration, easing: 'easeOutQuad', complete: function () { _this5.$photoCaption.remove(); } }); } } }], [{ key: 'init', value: function init(els, options) { return _get(Materialbox.__proto__ || Object.getPrototypeOf(Materialbox), 'init', this).call(this, this, els, options); } /** * Get Instance */ }, { key: 'getInstance', value: function getInstance(el) { var domElem = !!el.jquery ? el[0] : el; return domElem.M_Materialbox; } }, { key: 'defaults', get: function () { return _defaults; } }]); return Materialbox; }(Component); M.Materialbox = Materialbox; if (M.jQueryLoaded) { M.initializeJqueryWrapper(Materialbox, 'materialbox', 'M_Materialbox'); } })(cash, M.anime);