(function ($) { $(document).ready(function() { // jQuery reverse $.fn.reverse = [].reverse; // Hover behaviour: make sure this doesn't work on .click-to-toggle FABs! $(document).on('mouseenter.fixedActionBtn', '.fixed-action-btn:not(.click-to-toggle):not(.toolbar)', function(e) { var $this = $(this); openFABMenu($this); }); $(document).on('mouseleave.fixedActionBtn', '.fixed-action-btn:not(.click-to-toggle):not(.toolbar)', function(e) { var $this = $(this); closeFABMenu($this); }); // Toggle-on-click behaviour. $(document).on('click.fabClickToggle', '.fixed-action-btn.click-to-toggle > a', function(e) { var $this = $(this); var $menu = $this.parent(); if ($menu.hasClass('active')) { closeFABMenu($menu); } else { openFABMenu($menu); } }); // Toolbar transition behaviour. $(document).on('click.fabToolbar', '.fixed-action-btn.toolbar > a', function(e) { var $this = $(this); var $menu = $this.parent(); FABtoToolbar($menu); }); }); $.fn.extend({ openFAB: function() { openFABMenu($(this)); }, closeFAB: function() { closeFABMenu($(this)); }, openToolbar: function() { FABtoToolbar($(this)); }, closeToolbar: function() { toolbarToFAB($(this)); } }); var openFABMenu = function (btn) { var $this = btn; if ($this.hasClass('active') === false) { // Get direction option var horizontal = $this.hasClass('horizontal'); var offsetY, offsetX; if (horizontal === true) { offsetX = 40; } else { offsetY = 40; } $this.addClass('active'); $this.find('ul .btn-floating').velocity( { scaleY: ".4", scaleX: ".4", translateY: offsetY + 'px', translateX: offsetX + 'px'}, { duration: 0 }); var time = 0; $this.find('ul .btn-floating').reverse().each( function () { $(this).velocity( { opacity: "1", scaleX: "1", scaleY: "1", translateY: "0", translateX: '0'}, { duration: 80, delay: time }); time += 40; }); } }; var closeFABMenu = function (btn) { var $this = btn; // Get direction option var horizontal = $this.hasClass('horizontal'); var offsetY, offsetX; if (horizontal === true) { offsetX = 40; } else { offsetY = 40; } $this.removeClass('active'); var time = 0; $this.find('ul .btn-floating').velocity("stop", true); $this.find('ul .btn-floating').velocity( { opacity: "0", scaleX: ".4", scaleY: ".4", translateY: offsetY + 'px', translateX: offsetX + 'px'}, { duration: 80 } ); }; /** * Transform FAB into toolbar * @param {Object} object jQuery object */ var FABtoToolbar = function(btn) { if (btn.attr('data-open') === "true") { return; } var offsetX, offsetY, scaleFactor; var windowWidth = window.innerWidth; var windowHeight = window.innerHeight; var btnRect = btn[0].getBoundingClientRect(); var anchor = btn.find('> a').first(); var menu = btn.find('> ul').first(); var backdrop = $('
'); var fabColor = anchor.css('background-color'); anchor.append(backdrop); offsetX = btnRect.left - (windowWidth / 2) + (btnRect.width / 2); offsetY = windowHeight - btnRect.bottom; scaleFactor = windowWidth / backdrop.width(); btn.attr('data-origin-bottom', btnRect.bottom); btn.attr('data-origin-left', btnRect.left); btn.attr('data-origin-width', btnRect.width); // Set initial state btn.addClass('active'); btn.attr('data-open', true); btn.css({ 'text-align': 'center', width: '100%', bottom: 0, left: 0, transform: 'translateX(' + offsetX + 'px)', transition: 'none' }); anchor.css({ transform: 'translateY(' + -offsetY + 'px)', transition: 'none' }); backdrop.css({ 'background-color': fabColor }); setTimeout(function() { btn.css({ transform: '', transition: 'transform .2s cubic-bezier(0.550, 0.085, 0.680, 0.530), background-color 0s linear .2s' }); anchor.css({ overflow: 'visible', transform: '', transition: 'transform .2s' }); setTimeout(function() { btn.css({ overflow: 'hidden', 'background-color': fabColor }); backdrop.css({ transform: 'scale(' + scaleFactor + ')', transition: 'transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)' }); menu.find('> li > a').css({ opacity: 1 }); // Scroll to close. $(window).on('scroll.fabToolbarClose', function() { toolbarToFAB(btn); $(window).off('scroll.fabToolbarClose'); $(document).off('click.fabToolbarClose'); }); $(document).on('click.fabToolbarClose', function(e) { if (!$(e.target).closest(menu).length) { toolbarToFAB(btn); $(window).off('scroll.fabToolbarClose'); $(document).off('click.fabToolbarClose'); } }); }, 100); }, 0); }; /** * Transform toolbar back into FAB * @param {Object} object jQuery object */ var toolbarToFAB = function(btn) { if (btn.attr('data-open') !== "true") { return; } var offsetX, offsetY, scaleFactor; var windowWidth = window.innerWidth; var windowHeight = window.innerHeight; var btnWidth = btn.attr('data-origin-width'); var btnBottom = btn.attr('data-origin-bottom'); var btnLeft = btn.attr('data-origin-left'); var anchor = btn.find('> .btn-floating').first(); var menu = btn.find('> ul').first(); var backdrop = btn.find('.fab-backdrop'); var fabColor = anchor.css('background-color'); offsetX = btnLeft - (windowWidth / 2) + (btnWidth / 2); offsetY = windowHeight - btnBottom; scaleFactor = windowWidth / backdrop.width(); // Hide backdrop btn.removeClass('active'); btn.attr('data-open', false); btn.css({ 'background-color': 'transparent', transition: 'none' }); anchor.css({ transition: 'none' }); backdrop.css({ transform: 'scale(0)', 'background-color': fabColor }); menu.find('> li > a').css({ opacity: '' }); setTimeout(function() { backdrop.remove(); // Set initial state. btn.css({ 'text-align': '', width: '', bottom: '', left: '', overflow: '', 'background-color': '', transform: 'translate3d(' + -offsetX + 'px,0,0)' }); anchor.css({ overflow: '', transform: 'translate3d(0,' + offsetY + 'px,0)' }); setTimeout(function() { btn.css({ transform: 'translate3d(0,0,0)', transition: 'transform .2s' }); anchor.css({ transform: 'translate3d(0,0,0)', transition: 'transform .2s cubic-bezier(0.550, 0.055, 0.675, 0.190)' }); }, 20); }, 200); }; }( jQuery ));