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; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } (function ($, anim) { 'use strict'; var _defaults = { direction: 'top', hoverEnabled: true, toolbarEnabled: false }; $.fn.reverse = [].reverse; /** * @class * */ var FloatingActionButton = function () { /** * Construct FloatingActionButton instance * @constructor * @param {Element} el * @param {Object} options */ function FloatingActionButton(el, options) { _classCallCheck(this, FloatingActionButton); // If exists, destroy and reinitialize if (!!el.M_FloatingActionButton) { el.M_FloatingActionButton.destroy(); } this.el = el; this.$el = $(el); this.el.M_FloatingActionButton = this; /** * Options for the fab * @member FloatingActionButton#options * @prop {Boolean} [direction] - Direction fab menu opens * @prop {Boolean} [hoverEnabled=true] - Enable hover vs click * @prop {Boolean} [toolbarEnabled=false] - Enable toolbar transition */ this.options = $.extend({}, FloatingActionButton.defaults, options); this.isOpen = false; this.$anchor = this.$el.children('a').first(); this.$menu = this.$el.children('ul').first(); this.$floatingBtns = this.$el.find('ul .btn-floating'); this.$floatingBtnsReverse = this.$el.find('ul .btn-floating').reverse(); this.offsetY = 0; this.offsetX = 0; if (this.options.direction === 'top') { this.$el.addClass('direction-top'); this.offsetY = 40; } else if (this.options.direction === 'right') { this.$el.addClass('direction-right'); this.offsetX = -40; } else if (this.options.direction === 'bottom') { this.$el.addClass('direction-bottom'); this.offsetY = -40; } else { this.$el.addClass('direction-left'); this.offsetX = 40; } this._setupEventHandlers(); } _createClass(FloatingActionButton, [{ key: 'destroy', /** * Teardown component */ value: function destroy() { this._removeEventHandlers(); this.el.M_FloatingActionButton = undefined; } /** * Setup Event Handlers */ }, { key: '_setupEventHandlers', value: function _setupEventHandlers() { this._handleFABClickBound = this._handleFABClick.bind(this); this._handleOpenBound = this.open.bind(this); this._handleCloseBound = this.close.bind(this); if (this.options.hoverEnabled && !this.options.toolbarEnabled) { this.el.addEventListener('mouseenter', this._handleOpenBound); this.el.addEventListener('mouseleave', this._handleCloseBound); } else { this.el.addEventListener('click', this._handleFABClickBound); } } /** * Remove Event Handlers */ }, { key: '_removeEventHandlers', value: function _removeEventHandlers() { if (this.options.hoverEnabled && !this.options.toolbarEnabled) { this.el.removeEventListener('mouseenter', this._handleOpenBound); this.el.removeEventListener('mouseleave', this._handleCloseBound); } else { this.el.removeEventListener('click', this._handleFABClickBound); } } /** * Handle FAB Click */ }, { key: '_handleFABClick', value: function _handleFABClick() { if (this.isOpen) { this.close(); } else { this.open(); } } /** * Handle Document Click * @param {Event} e */ }, { key: '_handleDocumentClick', value: function _handleDocumentClick(e) { if (!$(e.target).closest(this.$menu).length) { this.close(); } } /** * Open FAB */ }, { key: 'open', value: function open() { if (this.isOpen) { return; } if (this.options.toolbarEnabled) { this._animateInToolbar(); } else { this._animateInFAB(); } this.isOpen = true; } /** * Close FAB */ }, { key: 'close', value: function close() { if (!this.isOpen) { return; } if (this.options.toolbarEnabled) { window.removeEventListener('scroll', this._handleCloseBound, true); document.body.removeEventListener('click', this._handleDocumentClickBound, true); this._animateOutToolbar(); } else { this._animateOutFAB(); } this.isOpen = false; } /** * Classic FAB Menu open */ }, { key: '_animateInFAB', value: function _animateInFAB() { var _this = this; this.$el.addClass('active'); var time = 0; this.$floatingBtnsReverse.each(function (el) { anim({ targets: el, opacity: 1, scale: [.4, 1], translateY: [_this.offsetY, 0], translateX: [_this.offsetX, 0], duration: 275, delay: time, easing: 'easeInOutQuad' }); time += 40; }); } /** * Classic FAB Menu close */ }, { key: '_animateOutFAB', value: function _animateOutFAB() { var _this2 = this; this.$floatingBtnsReverse.each(function (el) { anim.remove(el); anim({ targets: el, opacity: 0, scale: .4, translateY: _this2.offsetY, translateX: _this2.offsetX, duration: 175, easing: 'easeOutQuad', complete: function () { _this2.$el.removeClass('active'); } }); }); } /** * Toolbar transition Menu open */ }, { key: '_animateInToolbar', value: function _animateInToolbar() { var _this3 = this; var scaleFactor = void 0; var windowWidth = window.innerWidth; var windowHeight = window.innerHeight; var btnRect = this.el.getBoundingClientRect(); var backdrop = $('
'); var fabColor = this.$anchor.css('background-color'); this.$anchor.append(backdrop); this.offsetX = btnRect.left - windowWidth / 2 + btnRect.width / 2; this.offsetY = windowHeight - btnRect.bottom; scaleFactor = windowWidth / backdrop[0].clientWidth; this.btnBottom = btnRect.bottom; this.btnLeft = btnRect.left; this.btnWidth = btnRect.width; // Set initial state this.$el.addClass('active'); this.$el.css({ 'text-align': 'center', width: '100%', bottom: 0, left: 0, transform: 'translateX(' + this.offsetX + 'px)', transition: 'none' }); this.$anchor.css({ transform: 'translateY(' + -this.offsetY + 'px)', transition: 'none' }); backdrop.css({ 'background-color': fabColor }); setTimeout(function () { _this3.$el.css({ transform: '', transition: 'transform .2s cubic-bezier(0.550, 0.085, 0.680, 0.530), background-color 0s linear .2s' }); _this3.$anchor.css({ overflow: 'visible', transform: '', transition: 'transform .2s' }); setTimeout(function () { _this3.$el.css({ overflow: 'hidden', 'background-color': fabColor }); backdrop.css({ transform: 'scale(' + scaleFactor + ')', transition: 'transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)' }); _this3.$menu.children('li').children('a').css({ opacity: 1 }); // Scroll to close. _this3._handleDocumentClickBound = _this3._handleDocumentClick.bind(_this3); window.addEventListener('scroll', _this3._handleCloseBound, true); document.body.addEventListener('click', _this3._handleDocumentClickBound, true); }, 100); }, 0); } /** * Toolbar transition Menu close */ }, { key: '_animateOutToolbar', value: function _animateOutToolbar() { var _this4 = this; var windowWidth = window.innerWidth; var windowHeight = window.innerHeight; var backdrop = this.$el.find('.fab-backdrop'); var fabColor = anchor.css('background-color'); this.offsetX = this.btnLeft - windowWidth / 2 + this.btnWidth / 2; this.offsetY = windowHeight - this.btnBottom; // Hide backdrop this.$el.removeClass('active'); this.$el.css({ 'background-color': 'transparent', transition: 'none' }); this.$anchor.css({ transition: 'none' }); backdrop.css({ transform: 'scale(0)', 'background-color': fabColor }); this.$menu.children('li').children('a').css({ opacity: '' }); setTimeout(function () { backdrop.remove(); // Set initial state. _this4.$el.css({ 'text-align': '', width: '', bottom: '', left: '', overflow: '', 'background-color': '', transform: 'translate3d(' + -_this4.offsetX + 'px,0,0)' }); _this4.$anchor.css({ overflow: '', transform: 'translate3d(0,' + _this4.offsetY + 'px,0)' }); setTimeout(function () { _this4.$el.css({ transform: 'translate3d(0,0,0)', transition: 'transform .2s' }); _this4.$anchor.css({ transform: 'translate3d(0,0,0)', transition: 'transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)' }); }, 20); }, 200); } }], [{ key: 'init', value: function init($els, options) { var arr = []; $els.each(function () { arr.push(new FloatingActionButton(this, options)); }); return arr; } /** * Get Instance */ }, { key: 'getInstance', value: function getInstance(el) { var domElem = !!el.jquery ? el[0] : el; return domElem.M_FloatingActionButton; } }, { key: 'defaults', get: function () { return _defaults; } }]); return FloatingActionButton; }(); M.FloatingActionButton = FloatingActionButton; if (M.jQueryLoaded) { M.initializeJqueryWrapper(FloatingActionButton, 'floatingActionButton', 'M_FloatingActionButton'); } })(cash, M.anime);