/* * raf.js * https://github.com/ngryman/raf.js * * original requestAnimationFrame polyfill by Erik Möller * inspired from paul_irish gist and post * * Copyright (c) 2013 ngryman * Licensed under the MIT license. */ (function(window) { var lastTime = 0, vendors = ['webkit', 'moz'], requestAnimationFrame = window.requestAnimationFrame, cancelAnimationFrame = window.cancelAnimationFrame, i = vendors.length; // try to un-prefix existing raf while (--i >= 0 && !requestAnimationFrame) { requestAnimationFrame = window[vendors[i] + 'RequestAnimationFrame']; cancelAnimationFrame = window[vendors[i] + 'CancelRequestAnimationFrame']; } // polyfill with setTimeout fallback // heavily inspired from @darius gist mod: https://gist.github.com/paulirish/1579671#comment-837945 if (!requestAnimationFrame || !cancelAnimationFrame) { requestAnimationFrame = function(callback) { var now = +Date.now(), nextTime = Math.max(lastTime + 16, now); return setTimeout(function() { callback(lastTime = nextTime); }, nextTime - now); }; cancelAnimationFrame = clearTimeout; } // export to window window.requestAnimationFrame = requestAnimationFrame; window.cancelAnimationFrame = cancelAnimationFrame; }(window)); /** * Generate approximated selector string for a jQuery object * @param {jQuery} obj jQuery object to be parsed * @returns {string} */ Materialize.objectSelectorString = function(obj) { var tagStr = obj.prop('tagName') || ''; var idStr = obj.attr('id') || ''; var classStr = obj.attr('class') || ''; return (tagStr + idStr + classStr).replace(/\s/g,''); }; // Unique Random ID Materialize.guid = (function() { function s4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } return function() { return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); }; })(); /** * Escapes hash from special characters * @param {string} hash String returned from this.hash * @returns {string} */ Materialize.escapeHash = function(hash) { return hash.replace( /(:|\.|\[|\]|,|=)/g, "\\$1" ); }; Materialize.elementOrParentIsFixed = function(element) { var $element = $(element); var $checkElements = $element.add($element.parents()); var isFixed = false; $checkElements.each(function(){ if ($(this).css("position") === "fixed") { isFixed = true; return false; } }); return isFixed; }; /** * Get time in ms * @license https://raw.github.com/jashkenas/underscore/master/LICENSE * @type {function} * @return {number} */ var getTime = (Date.now || function () { return new Date().getTime(); }); /** * Returns a function, that, when invoked, will only be triggered at most once * during a given window of time. Normally, the throttled function will run * as much as it can, without ever going more than once per `wait` duration; * but if you'd like to disable the execution on the leading edge, pass * `{leading: false}`. To disable execution on the trailing edge, ditto. * @license https://raw.github.com/jashkenas/underscore/master/LICENSE * @param {function} func * @param {number} wait * @param {Object=} options * @returns {Function} */ Materialize.throttle = function(func, wait, options) { var context, args, result; var timeout = null; var previous = 0; options || (options = {}); var later = function () { previous = options.leading === false ? 0 : getTime(); timeout = null; result = func.apply(context, args); context = args = null; }; return function () { var now = getTime(); if (!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); context = args = null; } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } return result; }; }; // Velocity has conflicts when loaded with jQuery, this will check for it // First, check if in noConflict mode var Vel; if (jQuery) { Vel = jQuery.Velocity; } else if ($) { Vel = $.Velocity; } else { Vel = Velocity; } ;(function ($) { $.fn.collapsible = function(options, methodParam) { var defaults = { accordion: undefined, onOpen: undefined, onClose: undefined }; var methodName = options; options = $.extend(defaults, options); return this.each(function() { var $this = $(this); var $panel_headers = $(this).find('> li > .collapsible-header'); var collapsible_type = $this.data("collapsible"); /**************** Helper Functions ****************/ // Accordion Open function accordionOpen(object) { $panel_headers = $this.find('> li > .collapsible-header'); if (object.hasClass('active')) { object.parent().addClass('active'); } else { object.parent().removeClass('active'); } if (object.parent().hasClass('active')){ object.siblings('.collapsible-body').stop(true,false).slideDown({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '');}}); } else{ object.siblings('.collapsible-body').stop(true,false).slideUp({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '');}}); } $panel_headers.not(object).removeClass('active').parent().removeClass('active'); // Close previously open accordion elements. $panel_headers.not(object).parent().children('.collapsible-body').stop(true,false).each(function() { if ($(this).is(':visible')) { $(this).slideUp({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() { $(this).css('height', ''); execCallbacks($(this).siblings('.collapsible-header')); } }); } }); } // Expandable Open function expandableOpen(object) { if (object.hasClass('active')) { object.parent().addClass('active'); } else { object.parent().removeClass('active'); } if (object.parent().hasClass('active')){ object.siblings('.collapsible-body').stop(true,false).slideDown({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '');}}); } else { object.siblings('.collapsible-body').stop(true,false).slideUp({ duration: 350, easing: "easeOutQuart", queue: false, complete: function() {$(this).css('height', '');}}); } } // Open collapsible. object: .collapsible-header function collapsibleOpen(object, noToggle) { if (!noToggle) { object.toggleClass('active'); } if (options.accordion || collapsible_type === "accordion" || collapsible_type === undefined) { // Handle Accordion accordionOpen(object); } else { // Handle Expandables expandableOpen(object); } execCallbacks(object); } // Handle callbacks function execCallbacks(object) { if (object.hasClass('active')) { if (typeof(options.onOpen) === "function") { options.onOpen.call(this, object.parent()); } } else { if (typeof(options.onClose) === "function") { options.onClose.call(this, object.parent()); } } } /** * Check if object is children of panel header * @param {Object} object Jquery object * @return {Boolean} true if it is children */ function isChildrenOfPanelHeader(object) { var panelHeader = getPanelHeader(object); return panelHeader.length > 0; } /** * Get panel header from a children element * @param {Object} object Jquery object * @return {Object} panel header object */ function getPanelHeader(object) { return object.closest('li > .collapsible-header'); } // Turn off any existing event handlers function removeEventHandlers() { $this.off('click.collapse', '> li > .collapsible-header'); } /***** End Helper Functions *****/ // Methods if (methodName === 'destroy') { removeEventHandlers(); return; } else if (methodParam >= 0 && methodParam < $panel_headers.length) { var $curr_header = $panel_headers.eq(methodParam); if ($curr_header.length && (methodName === 'open' || (methodName === 'close' && $curr_header.hasClass('active')))) { collapsibleOpen($curr_header); } return; } removeEventHandlers(); // Add click handler to only direct collapsible header children $this.on('click.collapse', '> li > .collapsible-header', function(e) { var element = $(e.target); if (isChildrenOfPanelHeader(element)) { element = getPanelHeader(element); } collapsibleOpen(element); }); // Open first active if (options.accordion || collapsible_type === "accordion" || collapsible_type === undefined) { // Handle Accordion collapsibleOpen($panel_headers.filter('.active').first(), true); } else { // Handle Expandables $panel_headers.filter('.active').each(function() { collapsibleOpen($(this), true); }); } }); }; $(document).ready(function(){ $('.collapsible').collapsible(); }); }( jQuery ));;(function ($) { // Add posibility to scroll to selected option // usefull for select for example $.fn.scrollTo = function(elem) { $(this).scrollTop($(this).scrollTop() - $(this).offset().top + $(elem).offset().top); return this; }; $.fn.dropdown = function (options) { var defaults = { inDuration: 300, outDuration: 225, constrainWidth: true, // Constrains width of dropdown to the activator hover: false, gutter: 0, // Spacing from edge belowOrigin: false, alignment: 'left', stopPropagation: false }; // Open dropdown. if (options === "open") { this.each(function() { $(this).trigger('open'); }); return false; } // Close dropdown. if (options === "close") { this.each(function() { $(this).trigger('close'); }); return false; } this.each(function(){ var origin = $(this); var curr_options = $.extend({}, defaults, options); var isFocused = false; // Dropdown menu var activates = $("#"+ origin.attr('data-activates')); function updateOptions() { if (origin.data('induration') !== undefined) curr_options.inDuration = origin.data('induration'); if (origin.data('outduration') !== undefined) curr_options.outDuration = origin.data('outduration'); if (origin.data('constrainwidth') !== undefined) curr_options.constrainWidth = origin.data('constrainwidth'); if (origin.data('hover') !== undefined) curr_options.hover = origin.data('hover'); if (origin.data('gutter') !== undefined) curr_options.gutter = origin.data('gutter'); if (origin.data('beloworigin') !== undefined) curr_options.belowOrigin = origin.data('beloworigin'); if (origin.data('alignment') !== undefined) curr_options.alignment = origin.data('alignment'); if (origin.data('stoppropagation') !== undefined) curr_options.stopPropagation = origin.data('stoppropagation'); } updateOptions(); // Attach dropdown to its activator origin.after(activates); /* Helper function to position and resize dropdown. Used in hover and click handler. */ function placeDropdown(eventType) { // Check for simultaneous focus and click events. if (eventType === 'focus') { isFocused = true; } // Check html data attributes updateOptions(); // Set Dropdown state activates.addClass('active'); origin.addClass('active'); // Constrain width if (curr_options.constrainWidth === true) { activates.css('width', origin.outerWidth()); } else { activates.css('white-space', 'nowrap'); } // Offscreen detection var windowHeight = window.innerHeight; var originHeight = origin.innerHeight(); var offsetLeft = origin.offset().left; var offsetTop = origin.offset().top - $(window).scrollTop(); var currAlignment = curr_options.alignment; var gutterSpacing = 0; var leftPosition = 0; // Below Origin var verticalOffset = 0; if (curr_options.belowOrigin === true) { verticalOffset = originHeight; } // Check for scrolling positioned container. var scrollYOffset = 0; var scrollXOffset = 0; var wrapper = origin.parent(); if (!wrapper.is('body')) { if (wrapper[0].scrollHeight > wrapper[0].clientHeight) { scrollYOffset = wrapper[0].scrollTop; } if (wrapper[0].scrollWidth > wrapper[0].clientWidth) { scrollXOffset = wrapper[0].scrollLeft; } } if (offsetLeft + activates.innerWidth() > $(window).width()) { // Dropdown goes past screen on right, force right alignment currAlignment = 'right'; } else if (offsetLeft - activates.innerWidth() + origin.innerWidth() < 0) { // Dropdown goes past screen on left, force left alignment currAlignment = 'left'; } // Vertical bottom offscreen detection if (offsetTop + activates.innerHeight() > windowHeight) { // If going upwards still goes offscreen, just crop height of dropdown. if (offsetTop + originHeight - activates.innerHeight() < 0) { var adjustedHeight = windowHeight - offsetTop - verticalOffset; activates.css('max-height', adjustedHeight); } else { // Flow upwards. if (!verticalOffset) { verticalOffset += originHeight; } verticalOffset -= activates.innerHeight(); } } // Handle edge alignment if (currAlignment === 'left') { gutterSpacing = curr_options.gutter; leftPosition = origin.position().left + gutterSpacing; } else if (currAlignment === 'right') { var offsetRight = origin.position().left + origin.outerWidth() - activates.outerWidth(); gutterSpacing = -curr_options.gutter; leftPosition = offsetRight + gutterSpacing; } // Position dropdown activates.css({ position: 'absolute', top: origin.position().top + verticalOffset + scrollYOffset, left: leftPosition + scrollXOffset }); // Show dropdown activates.stop(true, true).css('opacity', 0) .slideDown({ queue: false, duration: curr_options.inDuration, easing: 'easeOutCubic', complete: function() { $(this).css('height', ''); } }) .animate( {opacity: 1}, {queue: false, duration: curr_options.inDuration, easing: 'easeOutSine'}); // Add click close handler to document setTimeout(function() { $(document).bind('click.'+ activates.attr('id'), function (e) { hideDropdown(); $(document).unbind('click.'+ activates.attr('id')); }); }, 0); } function hideDropdown() { // Check for simultaneous focus and click events. isFocused = false; activates.fadeOut(curr_options.outDuration); activates.removeClass('active'); origin.removeClass('active'); $(document).unbind('click.'+ activates.attr('id')); setTimeout(function() { activates.css('max-height', ''); }, curr_options.outDuration); } // Hover if (curr_options.hover) { var open = false; origin.unbind('click.' + origin.attr('id')); // Hover handler to show dropdown origin.on('mouseenter', function(e){ // Mouse over if (open === false) { placeDropdown(); open = true; } }); origin.on('mouseleave', function(e){ // If hover on origin then to something other than dropdown content, then close var toEl = e.toElement || e.relatedTarget; // added browser compatibility for target element if(!$(toEl).closest('.dropdown-content').is(activates)) { activates.stop(true, true); hideDropdown(); open = false; } }); activates.on('mouseleave', function(e){ // Mouse out var toEl = e.toElement || e.relatedTarget; if(!$(toEl).closest('.dropdown-button').is(origin)) { activates.stop(true, true); hideDropdown(); open = false; } }); // Click } else { // Click handler to show dropdown origin.unbind('click.' + origin.attr('id')); origin.bind('click.'+origin.attr('id'), function(e){ if (!isFocused) { if ( origin[0] == e.currentTarget && !origin.hasClass('active') && ($(e.target).closest('.dropdown-content').length === 0)) { e.preventDefault(); // Prevents button click from moving window if (curr_options.stopPropagation) { e.stopPropagation(); } placeDropdown('click'); } // If origin is clicked and menu is open, close menu else if (origin.hasClass('active')) { hideDropdown(); $(document).unbind('click.'+ activates.attr('id')); } } }); } // End else // Listen to open and close event - useful for select component origin.on('open', function(e, eventType) { placeDropdown(eventType); }); origin.on('close', hideDropdown); }); }; // End dropdown plugin $(document).ready(function(){ $('.dropdown-button').dropdown(); }); }( jQuery )); ;(function($) { var _stack = 0, _lastID = 0, _generateID = function() { _lastID++; return 'materialize-modal-overlay-' + _lastID; }; var methods = { init : function(options) { var defaults = { opacity: 0.5, inDuration: 350, outDuration: 250, ready: undefined, complete: undefined, dismissible: true, startingTop: '4%', endingTop: '10%' }; // Override defaults options = $.extend(defaults, options); return this.each(function() { var $modal = $(this); var modal_id = $(this).attr("id") || '#' + $(this).data('target'); var closeModal = function() { var overlayID = $modal.data('overlay-id'); var $overlay = $('#' + overlayID); $modal.removeClass('open'); // Enable scrolling $('body').css({ overflow: '', width: '' }); $modal.find('.modal-close').off('click.close'); $(document).off('keyup.modal' + overlayID); $overlay.velocity( { opacity: 0}, {duration: options.outDuration, queue: false, ease: "easeOutQuart"}); // Define Bottom Sheet animation var exitVelocityOptions = { duration: options.outDuration, queue: false, ease: "easeOutCubic", // Handle modal ready callback complete: function() { $(this).css({display:"none"}); // Call complete callback if (typeof(options.complete) === "function") { options.complete.call(this, $modal); } $overlay.remove(); _stack--; } }; if ($modal.hasClass('bottom-sheet')) { $modal.velocity({bottom: "-100%", opacity: 0}, exitVelocityOptions); } else { $modal.velocity( { top: options.startingTop, opacity: 0, scaleX: 0.7}, exitVelocityOptions ); } }; var openModal = function($trigger) { var $body = $('body'); var oldWidth = $body.innerWidth(); $body.css('overflow', 'hidden'); $body.width(oldWidth); if ($modal.hasClass('open')) { return; } var overlayID = _generateID(); var $overlay = $(''); lStack = (++_stack); // Store a reference of the overlay $overlay.attr('id', overlayID).css('z-index', 1000 + lStack * 2); $modal.data('overlay-id', overlayID).css('z-index', 1000 + lStack * 2 + 1); $modal.addClass('open'); $("body").append($overlay); if (options.dismissible) { $overlay.click(function() { closeModal(); }); // Return on ESC $(document).on('keyup.modal' + overlayID, function(e) { if (e.keyCode === 27) { // ESC key closeModal(); } }); } $modal.find(".modal-close").on('click.close', function(e) { closeModal(); }); $overlay.css({ display : "block", opacity : 0 }); $modal.css({ display : "block", opacity: 0 }); $overlay.velocity({opacity: options.opacity}, {duration: options.inDuration, queue: false, ease: "easeOutCubic"}); $modal.data('associated-overlay', $overlay[0]); // Define Bottom Sheet animation var enterVelocityOptions = { duration: options.inDuration, queue: false, ease: "easeOutCubic", // Handle modal ready callback complete: function() { if (typeof(options.ready) === "function") { options.ready.call(this, $modal, $trigger); } } }; if ($modal.hasClass('bottom-sheet')) { $modal.velocity({bottom: "0", opacity: 1}, enterVelocityOptions); } else { $.Velocity.hook($modal, "scaleX", 0.7); $modal.css({ top: options.startingTop }); $modal.velocity({top: options.endingTop, opacity: 1, scaleX: '1'}, enterVelocityOptions); } }; // Reset handlers $(document).off('click.modalTrigger', 'a[href="#' + modal_id + '"], [data-target="' + modal_id + '"]'); $(this).off('openModal'); $(this).off('closeModal'); // Close Handlers $(document).on('click.modalTrigger', 'a[href="#' + modal_id + '"], [data-target="' + modal_id + '"]', function(e) { options.startingTop = ($(this).offset().top - $(window).scrollTop()) /1.15; openModal($(this)); e.preventDefault(); }); // done set on click $(this).on('openModal', function() { var modal_id = $(this).attr("href") || '#' + $(this).data('target'); openModal(); }); $(this).on('closeModal', function() { closeModal(); }); }); // done return }, open : function() { $(this).trigger('openModal'); }, close : function() { $(this).trigger('closeModal'); } }; $.fn.modal = function(methodOrOptions) { if ( methods[methodOrOptions] ) { return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) { // Default to "init" return methods.init.apply( this, arguments ); } else { $.error( 'Method ' + methodOrOptions + ' does not exist on jQuery.modal' ); } }; })(jQuery); ;(function ($) { $.fn.materialbox = function () { return this.each(function() { if ($(this).hasClass('initialized')) { return; } $(this).addClass('initialized'); var overlayActive = false; var doneAnimating = true; var inDuration = 275; var outDuration = 200; var origin = $(this); var placeholder = $('
').addClass('material-placeholder'); var originalWidth = 0; var originalHeight = 0; var ancestorsChanged; var ancestor; var originInlineStyles = origin.attr('style'); origin.wrap(placeholder); origin.on('click', function(){ var placeholder = origin.parent('.material-placeholder'); var windowWidth = window.innerWidth; var windowHeight = window.innerHeight; var originalWidth = origin.width(); var originalHeight = origin.height(); // If already modal, return to original if (doneAnimating === false) { returnToOriginal(); return false; } else if (overlayActive && doneAnimating===true) { returnToOriginal(); return false; } // Set states doneAnimating = false; origin.addClass('active'); overlayActive = true; // Set positioning for placeholder placeholder.css({ width: placeholder[0].getBoundingClientRect().width, height: placeholder[0].getBoundingClientRect().height, position: 'relative', top: 0, left: 0 }); // Find ancestor with overflow: hidden; and remove it ancestorsChanged = undefined; ancestor = placeholder[0].parentNode; var count = 0; while (ancestor !== null && !$(ancestor).is(document)) { var curr = $(ancestor); if (curr.css('overflow') !== 'visible') { curr.css('overflow', 'visible'); if (ancestorsChanged === undefined) { ancestorsChanged = curr; } else { ancestorsChanged = ancestorsChanged.add(curr); } } ancestor = ancestor.parentNode; } // Set css on origin origin.css({ position: 'absolute', 'z-index': 1000, 'will-change': 'left, top, width, height' }) .data('width', originalWidth) .data('height', originalHeight); // Add overlay var overlay = $('
') .css({ opacity: 0 }) .click(function(){ if (doneAnimating === true) returnToOriginal(); }); // Put before in origin image to preserve z-index layering. origin.before(overlay); // Set dimensions if needed var overlayOffset = overlay[0].getBoundingClientRect(); overlay.css({ width: windowWidth, height: windowHeight, left: -1 * overlayOffset.left, top: -1 * overlayOffset.top }) // Animate Overlay overlay.velocity({opacity: 1}, {duration: inDuration, queue: false, easing: 'easeOutQuad'} ); // Add and animate caption if it exists if (origin.data('caption') !== "") { var $photo_caption = $('
'); $photo_caption.text(origin.data('caption')); $('body').append($photo_caption); $photo_caption.css({ "display": "inline" }); $photo_caption.velocity({opacity: 1}, {duration: inDuration, queue: false, easing: 'easeOutQuad'}); } // Resize Image var ratio = 0; var widthPercent = originalWidth / windowWidth; var heightPercent = originalHeight / windowHeight; var newWidth = 0; var newHeight = 0; if (widthPercent > heightPercent) { ratio = originalHeight / originalWidth; newWidth = windowWidth * 0.9; newHeight = windowWidth * 0.9 * ratio; } else { ratio = originalWidth / originalHeight; newWidth = (windowHeight * 0.9) * ratio; newHeight = windowHeight * 0.9; } // Animate image + set z-index if(origin.hasClass('responsive-img')) { origin.velocity({'max-width': newWidth, 'width': originalWidth}, {duration: 0, queue: false, complete: function(){ origin.css({left: 0, top: 0}) .velocity( { height: newHeight, width: newWidth, left: $(document).scrollLeft() + windowWidth/2 - origin.parent('.material-placeholder').offset().left - newWidth/2, top: $(document).scrollTop() + windowHeight/2 - origin.parent('.material-placeholder').offset().top - newHeight/ 2 }, { duration: inDuration, queue: false, easing: 'easeOutQuad', complete: function(){doneAnimating = true;} } ); } // End Complete }); // End Velocity } else { origin.css('left', 0) .css('top', 0) .velocity( { height: newHeight, width: newWidth, left: $(document).scrollLeft() + windowWidth/2 - origin.parent('.material-placeholder').offset().left - newWidth/2, top: $(document).scrollTop() + windowHeight/2 - origin.parent('.material-placeholder').offset().top - newHeight/ 2 }, { duration: inDuration, queue: false, easing: 'easeOutQuad', complete: function(){doneAnimating = true;} } ); // End Velocity } }); // End origin on click // Return on scroll $(window).scroll(function() { if (overlayActive) { returnToOriginal(); } }); // Return on ESC $(document).keyup(function(e) { if (e.keyCode === 27 && doneAnimating === true) { // ESC key if (overlayActive) { returnToOriginal(); } } }); // This function returns the modaled image to the original spot function returnToOriginal() { doneAnimating = false; var placeholder = origin.parent('.material-placeholder'); var windowWidth = window.innerWidth; var windowHeight = window.innerHeight; var originalWidth = origin.data('width'); var originalHeight = origin.data('height'); origin.velocity("stop", true); $('#materialbox-overlay').velocity("stop", true); $('.materialbox-caption').velocity("stop", true); $('#materialbox-overlay').velocity({opacity: 0}, { duration: outDuration, // Delay prevents animation overlapping queue: false, easing: 'easeOutQuad', complete: function(){ // Remove Overlay overlayActive = false; $(this).remove(); } }); // Resize Image origin.velocity( { width: originalWidth, height: originalHeight, left: 0, top: 0 }, { duration: outDuration, queue: false, easing: 'easeOutQuad', complete: function() { placeholder.css({ height: '', width: '', position: '', top: '', left: '' }); origin.removeAttr('style'); origin.attr('style', originInlineStyles); // Remove class origin.removeClass('active'); doneAnimating = true; // Remove overflow overrides on ancestors if (ancestorsChanged) { ancestorsChanged.css('overflow', ''); } } } ); // Remove Caption + reset css settings on image $('.materialbox-caption').velocity({opacity: 0}, { duration: outDuration, // Delay prevents animation overlapping queue: false, easing: 'easeOutQuad', complete: function(){ $(this).remove(); } }); } }); }; $(document).ready(function(){ $('.materialboxed').materialbox(); }); }( jQuery )); ;(function ($) { $.fn.parallax = function () { var window_width = $(window).width(); // Parallax Scripts return this.each(function(i) { var $this = $(this); $this.addClass('parallax'); function updateParallax(initial) { var container_height; if (window_width < 601) { container_height = ($this.height() > 0) ? $this.height() : $this.children("img").height(); } else { container_height = ($this.height() > 0) ? $this.height() : 500; } var $img = $this.children("img").first(); var img_height = $img.height(); var parallax_dist = img_height - container_height; var bottom = $this.offset().top + container_height; var top = $this.offset().top; var scrollTop = $(window).scrollTop(); var windowHeight = window.innerHeight; var windowBottom = scrollTop + windowHeight; var percentScrolled = (windowBottom - top) / (container_height + windowHeight); var parallax = Math.round((parallax_dist * percentScrolled)); if (initial) { $img.css('display', 'block'); } if ((bottom > scrollTop) && (top < (scrollTop + windowHeight))) { $img.css('transform', "translate3D(-50%," + parallax + "px, 0)"); } } // Wait for image load $this.children("img").one("load", function() { updateParallax(true); }).each(function() { if (this.complete) $(this).trigger("load"); }); $(window).scroll(function() { window_width = $(window).width(); updateParallax(false); }); $(window).resize(function() { window_width = $(window).width(); updateParallax(false); }); }); }; }( jQuery )); ;(function ($) { var methods = { init : function(options) { var defaults = { onShow: null, swipeable: false, responsiveThreshold: Infinity, // breakpoint for swipeable }; options = $.extend(defaults, options); var namespace = Materialize.objectSelectorString($(this)); return this.each(function(i) { var uniqueNamespace = namespace+i; // For each set of tabs, we want to keep track of // which tab is active and its associated content var $this = $(this), window_width = $(window).width(); var $active, $content, $links = $this.find('li.tab a'), $tabs_width = $this.width(), $tabs_content = $(), $tabs_wrapper, $tab_width = Math.max($tabs_width, $this[0].scrollWidth) / $links.length, $indicator, index = prev_index = 0, clicked = false, clickedTimeout, transition = 300; // Finds right attribute for indicator based on active tab. // el: jQuery Object var calcRightPos = function(el) { return Math.ceil($tabs_width - el.position().left - el.outerWidth() - $this.scrollLeft()); }; // Finds left attribute for indicator based on active tab. // el: jQuery Object var calcLeftPos = function(el) { return Math.floor(el.position().left + $this.scrollLeft()); }; // Animates Indicator to active tab. // prev_index: Number var animateIndicator = function(prev_index) { if ((index - prev_index) >= 0) { $indicator.velocity({"right": calcRightPos($active) }, { duration: transition, queue: false, easing: 'easeOutQuad'}); $indicator.velocity({"left": calcLeftPos($active) }, {duration: transition, queue: false, easing: 'easeOutQuad', delay: 90}); } else { $indicator.velocity({"left": calcLeftPos($active) }, { duration: transition, queue: false, easing: 'easeOutQuad'}); $indicator.velocity({"right": calcRightPos($active) }, {duration: transition, queue: false, easing: 'easeOutQuad', delay: 90}); } }; // Change swipeable according to responsive threshold if (options.swipeable) { if (window_width > options.responsiveThreshold) { options.swipeable = false; } } // If the location.hash matches one of the links, use that as the active tab. $active = $($links.filter('[href="'+location.hash+'"]')); // If no match is found, use the first link or any with class 'active' as the initial active tab. if ($active.length === 0) { $active = $(this).find('li.tab a.active').first(); } if ($active.length === 0) { $active = $(this).find('li.tab a').first(); } $active.addClass('active'); index = $links.index($active); if (index < 0) { index = 0; } if ($active[0] !== undefined) { $content = $($active[0].hash); $content.addClass('active'); } // append indicator then set indicator width to tab width if (!$this.find('.indicator').length) { $this.append('
'); } $indicator = $this.find('.indicator'); // we make sure that the indicator is at the end of the tabs $this.append($indicator); if ($this.is(":visible")) { // $indicator.css({"right": $tabs_width - ((index + 1) * $tab_width)}); // $indicator.css({"left": index * $tab_width}); setTimeout(function() { $indicator.css({"right": calcRightPos($active) }); $indicator.css({"left": calcLeftPos($active) }); }, 0); } $(window).off('resize.tabs-'+uniqueNamespace).on('resize.tabs-'+uniqueNamespace, function () { $tabs_width = $this.width(); $tab_width = Math.max($tabs_width, $this[0].scrollWidth) / $links.length; if (index < 0) { index = 0; } if ($tab_width !== 0 && $tabs_width !== 0) { $indicator.css({"right": calcRightPos($active) }); $indicator.css({"left": calcLeftPos($active) }); } }); // Initialize Tabs Content. if (options.swipeable) { // TODO: Duplicate calls with swipeable? handle multiple div wrapping. $links.each(function () { var $curr_content = $(Materialize.escapeHash(this.hash)); $curr_content.addClass('carousel-item'); $tabs_content = $tabs_content.add($curr_content); }); $tabs_wrapper = $tabs_content.wrapAll(''); $tabs_content.css('display', ''); $('.tabs-content.carousel').carousel({ fullWidth: true, noWrap: true, onCycleTo: function(item) { if (!clicked) { var prev_index = index; index = $tabs_wrapper.index(item); $active = $links.eq(index); animateIndicator(prev_index); } }, }); } else { // Hide the remaining content $links.not($active).each(function () { $(Materialize.escapeHash(this.hash)).hide(); }); } // Bind the click event handler $this.off('click.tabs').on('click.tabs', 'a', function(e) { if ($(this).parent().hasClass('disabled')) { e.preventDefault(); return; } // Act as regular link if target attribute is specified. if (!!$(this).attr("target")) { return; } clicked = true; $tabs_width = $this.width(); $tab_width = Math.max($tabs_width, $this[0].scrollWidth) / $links.length; // Make the old tab inactive. $active.removeClass('active'); var $oldContent = $content // Update the variables with the new link and content $active = $(this); $content = $(Materialize.escapeHash(this.hash)); $links = $this.find('li.tab a'); var activeRect = $active.position(); // Make the tab active. $active.addClass('active'); prev_index = index; index = $links.index($(this)); if (index < 0) { index = 0; } // Change url to current tab // window.location.hash = $active.attr('href'); // Swap content if (options.swipeable) { if ($tabs_content.length) { $tabs_content.carousel('set', index); } } else { if ($content !== undefined) { $content.show(); $content.addClass('active'); if (typeof(options.onShow) === "function") { options.onShow.call(this, $content); } } if ($oldContent !== undefined && !$oldContent.is($content)) { $oldContent.hide(); $oldContent.removeClass('active'); } } // Reset clicked state clickedTimeout = setTimeout(function(){ clicked = false; }, transition); // Update indicator animateIndicator(prev_index); // Prevent the anchor's default click action e.preventDefault(); }); }); }, select_tab : function( id ) { this.find('a[href="#' + id + '"]').trigger('click'); } }; $.fn.tabs = function(methodOrOptions) { if ( methods[methodOrOptions] ) { return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) { // Default to "init" return methods.init.apply( this, arguments ); } else { $.error( 'Method ' + methodOrOptions + ' does not exist on jQuery.tabs' ); } }; $(document).ready(function(){ $('ul.tabs').tabs(); }); }( jQuery )); ;(function ($) { $.fn.tooltip = function (options) { var timeout = null, margin = 5; // Defaults var defaults = { delay: 350, tooltip: '', position: 'bottom', html: false }; // Remove tooltip from the activator if (options === "remove") { this.each(function() { $('#' + $(this).attr('data-tooltip-id')).remove(); $(this).off('mouseenter.tooltip mouseleave.tooltip'); }); return false; } options = $.extend(defaults, options); return this.each(function() { var tooltipId = Materialize.guid(); var origin = $(this); // Destroy old tooltip if (origin.attr('data-tooltip-id')) { $('#' + origin.attr('data-tooltip-id')).remove(); } origin.attr('data-tooltip-id', tooltipId); // Get attributes. var allowHtml, tooltipDelay, tooltipPosition, tooltipText, tooltipEl, backdrop; var setAttributes = function() { allowHtml = origin.attr('data-html') ? origin.attr('data-html') === 'true' : options.html; tooltipDelay = origin.attr('data-delay'); tooltipDelay = (tooltipDelay === undefined || tooltipDelay === '') ? options.delay : tooltipDelay; tooltipPosition = origin.attr('data-position'); tooltipPosition = (tooltipPosition === undefined || tooltipPosition === '') ? options.position : tooltipPosition; tooltipText = origin.attr('data-tooltip'); tooltipText = (tooltipText === undefined || tooltipText === '') ? options.tooltip : tooltipText; }; setAttributes(); var renderTooltipEl = function() { var tooltip = $('
'); // Create Text span if (allowHtml) { tooltipText = $('').html(tooltipText); } else{ tooltipText = $('').text(tooltipText); } // Create tooltip tooltip.append(tooltipText) .appendTo($('body')) .attr('id', tooltipId); // Create backdrop backdrop = $('
'); backdrop.appendTo(tooltip); return tooltip; }; tooltipEl = renderTooltipEl(); // Destroy previously binded events origin.off('mouseenter.tooltip mouseleave.tooltip'); // Mouse In var started = false, timeoutRef; origin.on({'mouseenter.tooltip': function(e) { var showTooltip = function() { setAttributes(); started = true; tooltipEl.velocity('stop'); backdrop.velocity('stop'); tooltipEl.css({ visibility: 'visible', left: '0px', top: '0px' }); // Tooltip positioning var originWidth = origin.outerWidth(); var originHeight = origin.outerHeight(); var tooltipHeight = tooltipEl.outerHeight(); var tooltipWidth = tooltipEl.outerWidth(); var tooltipVerticalMovement = '0px'; var tooltipHorizontalMovement = '0px'; var backdropOffsetWidth = backdrop[0].offsetWidth; var backdropOffsetHeight = backdrop[0].offsetHeight; var scaleXFactor = 8; var scaleYFactor = 8; var scaleFactor = 0; var targetTop, targetLeft, newCoordinates; if (tooltipPosition === "top") { // Top Position targetTop = origin.offset().top - tooltipHeight - margin; targetLeft = origin.offset().left + originWidth/2 - tooltipWidth/2; newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); tooltipVerticalMovement = '-10px'; backdrop.css({ bottom: 0, left: 0, borderRadius: '14px 14px 0 0', transformOrigin: '50% 100%', marginTop: tooltipHeight, marginLeft: (tooltipWidth/2) - (backdropOffsetWidth/2) }); } // Left Position else if (tooltipPosition === "left") { targetTop = origin.offset().top + originHeight/2 - tooltipHeight/2; targetLeft = origin.offset().left - tooltipWidth - margin; newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); tooltipHorizontalMovement = '-10px'; backdrop.css({ top: '-7px', right: 0, width: '14px', height: '14px', borderRadius: '14px 0 0 14px', transformOrigin: '95% 50%', marginTop: tooltipHeight/2, marginLeft: tooltipWidth }); } // Right Position else if (tooltipPosition === "right") { targetTop = origin.offset().top + originHeight/2 - tooltipHeight/2; targetLeft = origin.offset().left + originWidth + margin; newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); tooltipHorizontalMovement = '+10px'; backdrop.css({ top: '-7px', left: 0, width: '14px', height: '14px', borderRadius: '0 14px 14px 0', transformOrigin: '5% 50%', marginTop: tooltipHeight/2, marginLeft: '0px' }); } else { // Bottom Position targetTop = origin.offset().top + origin.outerHeight() + margin; targetLeft = origin.offset().left + originWidth/2 - tooltipWidth/2; newCoordinates = repositionWithinScreen(targetLeft, targetTop, tooltipWidth, tooltipHeight); tooltipVerticalMovement = '+10px'; backdrop.css({ top: 0, left: 0, marginLeft: (tooltipWidth/2) - (backdropOffsetWidth/2) }); } // Set tooptip css placement tooltipEl.css({ top: newCoordinates.y, left: newCoordinates.x }); // Calculate Scale to fill scaleXFactor = Math.SQRT2 * tooltipWidth / parseInt(backdropOffsetWidth); scaleYFactor = Math.SQRT2 * tooltipHeight / parseInt(backdropOffsetHeight); scaleFactor = Math.max(scaleXFactor, scaleYFactor); tooltipEl.velocity({ translateY: tooltipVerticalMovement, translateX: tooltipHorizontalMovement}, { duration: 350, queue: false }) .velocity({opacity: 1}, {duration: 300, delay: 50, queue: false}); backdrop.css({ visibility: 'visible' }) .velocity({opacity:1},{duration: 55, delay: 0, queue: false}) .velocity({scaleX: scaleFactor, scaleY: scaleFactor}, {duration: 300, delay: 0, queue: false, easing: 'easeInOutQuad'}); }; timeoutRef = setTimeout(showTooltip, tooltipDelay); // End Interval // Mouse Out }, 'mouseleave.tooltip': function(){ // Reset State started = false; clearTimeout(timeoutRef); // Animate back setTimeout(function() { if (started !== true) { tooltipEl.velocity({ opacity: 0, translateY: 0, translateX: 0}, { duration: 225, queue: false}); backdrop.velocity({opacity: 0, scaleX: 1, scaleY: 1}, { duration:225, queue: false, complete: function(){ backdrop.css({ visibility: 'hidden' }); tooltipEl.css({ visibility: 'hidden' }); started = false;} }); } },225); } }); }); }; var repositionWithinScreen = function(x, y, width, height) { var newX = x; var newY = y; if (newX < 0) { newX = 4; } else if (newX + width > window.innerWidth) { newX -= newX + width - window.innerWidth; } if (newY < 0) { newY = 4; } else if (newY + height > window.innerHeight + $(window).scrollTop) { newY -= newY + height - window.innerHeight; } return {x: newX, y: newY}; }; $(document).ready(function(){ $('.tooltipped').tooltip(); }); }( jQuery )); ;/*! * Waves v0.6.4 * http://fian.my.id/Waves * * Copyright 2014 Alfiana E. Sibuea and other contributors * Released under the MIT license * https://github.com/fians/Waves/blob/master/LICENSE */ ;(function(window) { 'use strict'; var Waves = Waves || {}; var $$ = document.querySelectorAll.bind(document); // Find exact position of element function isWindow(obj) { return obj !== null && obj === obj.window; } function getWindow(elem) { return isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView; } function offset(elem) { var docElem, win, box = {top: 0, left: 0}, doc = elem && elem.ownerDocument; docElem = doc.documentElement; if (typeof elem.getBoundingClientRect !== typeof undefined) { box = elem.getBoundingClientRect(); } win = getWindow(doc); return { top: box.top + win.pageYOffset - docElem.clientTop, left: box.left + win.pageXOffset - docElem.clientLeft }; } function convertStyle(obj) { var style = ''; for (var a in obj) { if (obj.hasOwnProperty(a)) { style += (a + ':' + obj[a] + ';'); } } return style; } var Effect = { // Effect delay duration: 750, show: function(e, element) { // Disable right click if (e.button === 2) { return false; } var el = element || this; // Create ripple var ripple = document.createElement('div'); ripple.className = 'waves-ripple'; el.appendChild(ripple); // Get click coordinate and element witdh var pos = offset(el); var relativeY = (e.pageY - pos.top); var relativeX = (e.pageX - pos.left); var scale = 'scale('+((el.clientWidth / 100) * 10)+')'; // Support for touch devices if ('touches' in e) { relativeY = (e.touches[0].pageY - pos.top); relativeX = (e.touches[0].pageX - pos.left); } // Attach data to element ripple.setAttribute('data-hold', Date.now()); ripple.setAttribute('data-scale', scale); ripple.setAttribute('data-x', relativeX); ripple.setAttribute('data-y', relativeY); // Set ripple position var rippleStyle = { 'top': relativeY+'px', 'left': relativeX+'px' }; ripple.className = ripple.className + ' waves-notransition'; ripple.setAttribute('style', convertStyle(rippleStyle)); ripple.className = ripple.className.replace('waves-notransition', ''); // Scale the ripple rippleStyle['-webkit-transform'] = scale; rippleStyle['-moz-transform'] = scale; rippleStyle['-ms-transform'] = scale; rippleStyle['-o-transform'] = scale; rippleStyle.transform = scale; rippleStyle.opacity = '1'; rippleStyle['-webkit-transition-duration'] = Effect.duration + 'ms'; rippleStyle['-moz-transition-duration'] = Effect.duration + 'ms'; rippleStyle['-o-transition-duration'] = Effect.duration + 'ms'; rippleStyle['transition-duration'] = Effect.duration + 'ms'; rippleStyle['-webkit-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)'; rippleStyle['-moz-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)'; rippleStyle['-o-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)'; rippleStyle['transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)'; ripple.setAttribute('style', convertStyle(rippleStyle)); }, hide: function(e) { TouchHandler.touchup(e); var el = this; var width = el.clientWidth * 1.4; // Get first ripple var ripple = null; var ripples = el.getElementsByClassName('waves-ripple'); if (ripples.length > 0) { ripple = ripples[ripples.length - 1]; } else { return false; } var relativeX = ripple.getAttribute('data-x'); var relativeY = ripple.getAttribute('data-y'); var scale = ripple.getAttribute('data-scale'); // Get delay beetween mousedown and mouse leave var diff = Date.now() - Number(ripple.getAttribute('data-hold')); var delay = 350 - diff; if (delay < 0) { delay = 0; } // Fade out ripple after delay setTimeout(function() { var style = { 'top': relativeY+'px', 'left': relativeX+'px', 'opacity': '0', // Duration '-webkit-transition-duration': Effect.duration + 'ms', '-moz-transition-duration': Effect.duration + 'ms', '-o-transition-duration': Effect.duration + 'ms', 'transition-duration': Effect.duration + 'ms', '-webkit-transform': scale, '-moz-transform': scale, '-ms-transform': scale, '-o-transform': scale, 'transform': scale, }; ripple.setAttribute('style', convertStyle(style)); setTimeout(function() { try { el.removeChild(ripple); } catch(e) { return false; } }, Effect.duration); }, delay); }, // Little hack to make can perform waves effect wrapInput: function(elements) { for (var a = 0; a < elements.length; a++) { var el = elements[a]; if (el.tagName.toLowerCase() === 'input') { var parent = el.parentNode; // If input already have parent just pass through if (parent.tagName.toLowerCase() === 'i' && parent.className.indexOf('waves-effect') !== -1) { continue; } // Put element class and style to the specified parent var wrapper = document.createElement('i'); wrapper.className = el.className + ' waves-input-wrapper'; var elementStyle = el.getAttribute('style'); if (!elementStyle) { elementStyle = ''; } wrapper.setAttribute('style', elementStyle); el.className = 'waves-button-input'; el.removeAttribute('style'); // Put element as child parent.replaceChild(wrapper, el); wrapper.appendChild(el); } } } }; /** * Disable mousedown event for 500ms during and after touch */ var TouchHandler = { /* uses an integer rather than bool so there's no issues with * needing to clear timeouts if another touch event occurred * within the 500ms. Cannot mouseup between touchstart and * touchend, nor in the 500ms after touchend. */ touches: 0, allowEvent: function(e) { var allow = true; if (e.type === 'touchstart') { TouchHandler.touches += 1; //push } else if (e.type === 'touchend' || e.type === 'touchcancel') { setTimeout(function() { if (TouchHandler.touches > 0) { TouchHandler.touches -= 1; //pop after 500ms } }, 500); } else if (e.type === 'mousedown' && TouchHandler.touches > 0) { allow = false; } return allow; }, touchup: function(e) { TouchHandler.allowEvent(e); } }; /** * Delegated click handler for .waves-effect element. * returns null when .waves-effect element not in "click tree" */ function getWavesEffectElement(e) { if (TouchHandler.allowEvent(e) === false) { return null; } var element = null; var target = e.target || e.srcElement; while (target.parentElement !== null) { if (!(target instanceof SVGElement) && target.className.indexOf('waves-effect') !== -1) { element = target; break; } else if (target.classList.contains('waves-effect')) { element = target; break; } target = target.parentElement; } return element; } /** * Bubble the click and show effect if .waves-effect elem was found */ function showEffect(e) { var element = getWavesEffectElement(e); if (element !== null) { Effect.show(e, element); if ('ontouchstart' in window) { element.addEventListener('touchend', Effect.hide, false); element.addEventListener('touchcancel', Effect.hide, false); } element.addEventListener('mouseup', Effect.hide, false); element.addEventListener('mouseleave', Effect.hide, false); } } Waves.displayEffect = function(options) { options = options || {}; if ('duration' in options) { Effect.duration = options.duration; } //Wrap input inside tag Effect.wrapInput($$('.waves-effect')); if ('ontouchstart' in window) { document.body.addEventListener('touchstart', showEffect, false); } document.body.addEventListener('mousedown', showEffect, false); }; /** * Attach Waves to an input element (or any element which doesn't * bubble mouseup/mousedown events). * Intended to be used with dynamically loaded forms/inputs, or * where the user doesn't want a delegated click handler. */ Waves.attach = function(element) { //FUTURE: automatically add waves classes and allow users // to specify them with an options param? Eg. light/classic/button if (element.tagName.toLowerCase() === 'input') { Effect.wrapInput([element]); element = element.parentElement; } if ('ontouchstart' in window) { element.addEventListener('touchstart', showEffect, false); } element.addEventListener('mousedown', showEffect, false); }; window.Waves = Waves; document.addEventListener('DOMContentLoaded', function() { Waves.displayEffect(); }, false); })(window); ;Materialize.toast = function (message, displayLength, className, completeCallback) { className = className || ""; var container = document.getElementById('toast-container'); // Create toast container if it does not exist if (container === null) { // create notification container container = document.createElement('div'); container.id = 'toast-container'; document.body.appendChild(container); } // Select and append toast var newToast = createToast(message); // only append toast if message is not undefined if(message){ container.appendChild(newToast); } newToast.style.opacity = 0; // Animate toast in Vel(newToast, {translateY: '-35px', opacity: 1 }, {duration: 300, easing: 'easeOutCubic', queue: false}); // Allows timer to be pause while being panned var timeLeft = displayLength; var counterInterval; if (timeLeft != null) { counterInterval = setInterval (function(){ if (newToast.parentNode === null) window.clearInterval(counterInterval); // If toast is not being dragged, decrease its time remaining if (!newToast.classList.contains('panning')) { timeLeft -= 20; } if (timeLeft <= 0) { // Animate toast out Vel(newToast, {"opacity": 0, marginTop: '-40px'}, { duration: 375, easing: 'easeOutExpo', queue: false, complete: function(){ // Call the optional callback if(typeof(completeCallback) === "function") completeCallback(); // Remove toast after it times out this[0].parentNode.removeChild(this[0]); } }); window.clearInterval(counterInterval); } }, 20); } function createToast(html) { // Create toast var toast = document.createElement('div'); toast.classList.add('toast'); if (className) { var classes = className.split(' '); for (var i = 0, count = classes.length; i < count; i++) { toast.classList.add(classes[i]); } } // If type of parameter is HTML Element if ( typeof HTMLElement === "object" ? html instanceof HTMLElement : html && typeof html === "object" && html !== null && html.nodeType === 1 && typeof html.nodeName==="string" ) { toast.appendChild(html); } else if (html instanceof jQuery) { // Check if it is jQuery object toast.appendChild(html[0]); } else { // Insert as text; toast.innerHTML = html; } // Bind hammer var hammerHandler = new Hammer(toast, {prevent_default: false}); hammerHandler.on('pan', function(e) { var deltaX = e.deltaX; var activationDistance = 80; // Change toast state if (!toast.classList.contains('panning')){ toast.classList.add('panning'); } var opacityPercent = 1-Math.abs(deltaX / activationDistance); if (opacityPercent < 0) opacityPercent = 0; Vel(toast, {left: deltaX, opacity: opacityPercent }, {duration: 50, queue: false, easing: 'easeOutQuad'}); }); hammerHandler.on('panend', function(e) { var deltaX = e.deltaX; var activationDistance = 80; // If toast dragged past activation point if (Math.abs(deltaX) > activationDistance) { Vel(toast, {marginTop: '-40px'}, { duration: 375, easing: 'easeOutExpo', queue: false, complete: function(){ if(typeof(completeCallback) === "function") { completeCallback(); } toast.parentNode.removeChild(toast); } }); } else { toast.classList.remove('panning'); // Put toast back into original position Vel(toast, { left: 0, opacity: 1 }, { duration: 300, easing: 'easeOutExpo', queue: false }); } }); return toast; } }; ;(function ($) { var methods = { init : function(options) { var defaults = { menuWidth: 300, edge: 'left', closeOnClick: false, draggable: true }; options = $.extend(defaults, options); $(this).each(function(){ var $this = $(this); var menuId = $this.attr('data-activates'); var menu = $("#"+ menuId); // Set to width if (options.menuWidth != 300) { menu.css('width', options.menuWidth); } // Add Touch Area var $dragTarget = $('.drag-target[data-sidenav="' + menuId + '"]'); if (options.draggable) { // Regenerate dragTarget if ($dragTarget.length) { $dragTarget.remove(); } $dragTarget = $('
').attr('data-sidenav', menuId); $('body').append($dragTarget); } else { $dragTarget = $(); } if (options.edge == 'left') { menu.css('transform', 'translateX(-100%)'); $dragTarget.css({'left': 0}); // Add Touch Area } else { menu.addClass('right-aligned') // Change text-alignment to right .css('transform', 'translateX(100%)'); $dragTarget.css({'right': 0}); // Add Touch Area } // If fixed sidenav, bring menu out if (menu.hasClass('fixed')) { if (window.innerWidth > 992) { menu.css('transform', 'translateX(0)'); } } // Window resize to reset on large screens fixed if (menu.hasClass('fixed')) { $(window).resize( function() { if (window.innerWidth > 992) { // Close menu if window is resized bigger than 992 and user has fixed sidenav if ($('#sidenav-overlay').length !== 0 && menuOut) { removeMenu(true); } else { // menu.removeAttr('style'); menu.css('transform', 'translateX(0%)'); // menu.css('width', options.menuWidth); } } else if (menuOut === false){ if (options.edge === 'left') { menu.css('transform', 'translateX(-100%)'); } else { menu.css('transform', 'translateX(100%)'); } } }); } // if closeOnClick, then add close event for all a tags in side sideNav if (options.closeOnClick === true) { menu.on("click.itemclick", "a:not(.collapsible-header)", function(){ removeMenu(); }); } var removeMenu = function(restoreNav) { panning = false; menuOut = false; // Reenable scrolling $('body').css({ overflow: '', width: '' }); $('#sidenav-overlay').velocity({opacity: 0}, {duration: 200, queue: false, easing: 'easeOutQuad', complete: function() { $(this).remove(); } }); if (options.edge === 'left') { // Reset phantom div $dragTarget.css({width: '', right: '', left: '0'}); menu.velocity( {'translateX': '-100%'}, { duration: 200, queue: false, easing: 'easeOutCubic', complete: function() { if (restoreNav === true) { // Restore Fixed sidenav menu.removeAttr('style'); menu.css('width', options.menuWidth); } } }); } else { // Reset phantom div $dragTarget.css({width: '', right: '0', left: ''}); menu.velocity( {'translateX': '100%'}, { duration: 200, queue: false, easing: 'easeOutCubic', complete: function() { if (restoreNav === true) { // Restore Fixed sidenav menu.removeAttr('style'); menu.css('width', options.menuWidth); } } }); } }; // Touch Event var panning = false; var menuOut = false; if (options.draggable) { $dragTarget.on('click', function(){ if (menuOut) { removeMenu(); } }); $dragTarget.hammer({ prevent_default: false }).bind('pan', function(e) { if (e.gesture.pointerType == "touch") { var direction = e.gesture.direction; var x = e.gesture.center.x; var y = e.gesture.center.y; var velocityX = e.gesture.velocityX; // Disable Scrolling var $body = $('body'); var $overlay = $('#sidenav-overlay'); var oldWidth = $body.innerWidth(); $body.css('overflow', 'hidden'); $body.width(oldWidth); // If overlay does not exist, create one and if it is clicked, close menu if ($overlay.length === 0) { $overlay = $('
'); $overlay.css('opacity', 0).click( function(){ removeMenu(); }); $('body').append($overlay); } // Keep within boundaries if (options.edge === 'left') { if (x > options.menuWidth) { x = options.menuWidth; } else if (x < 0) { x = 0; } } if (options.edge === 'left') { // Left Direction if (x < (options.menuWidth / 2)) { menuOut = false; } // Right Direction else if (x >= (options.menuWidth / 2)) { menuOut = true; } menu.css('transform', 'translateX(' + (x - options.menuWidth) + 'px)'); } else { // Left Direction if (x < (window.innerWidth - options.menuWidth / 2)) { menuOut = true; } // Right Direction else if (x >= (window.innerWidth - options.menuWidth / 2)) { menuOut = false; } var rightPos = (x - options.menuWidth / 2); if (rightPos < 0) { rightPos = 0; } menu.css('transform', 'translateX(' + rightPos + 'px)'); } // Percentage overlay var overlayPerc; if (options.edge === 'left') { overlayPerc = x / options.menuWidth; $overlay.velocity({opacity: overlayPerc }, {duration: 10, queue: false, easing: 'easeOutQuad'}); } else { overlayPerc = Math.abs((x - window.innerWidth) / options.menuWidth); $overlay.velocity({opacity: overlayPerc }, {duration: 10, queue: false, easing: 'easeOutQuad'}); } } }).bind('panend', function(e) { if (e.gesture.pointerType == "touch") { var $overlay = $('#sidenav-overlay'); var velocityX = e.gesture.velocityX; var x = e.gesture.center.x; var leftPos = x - options.menuWidth; var rightPos = x - options.menuWidth / 2; if (leftPos > 0 ) { leftPos = 0; } if (rightPos < 0) { rightPos = 0; } panning = false; if (options.edge === 'left') { // If velocityX <= 0.3 then the user is flinging the menu closed so ignore menuOut if ((menuOut && velocityX <= 0.3) || velocityX < -0.5) { // Return menu to open if (leftPos !== 0) { menu.velocity({'translateX': [0, leftPos]}, {duration: 300, queue: false, easing: 'easeOutQuad'}); } $overlay.velocity({opacity: 1 }, {duration: 50, queue: false, easing: 'easeOutQuad'}); $dragTarget.css({width: '50%', right: 0, left: ''}); menuOut = true; } else if (!menuOut || velocityX > 0.3) { // Enable Scrolling $('body').css({ overflow: '', width: '' }); // Slide menu closed menu.velocity({'translateX': [-1 * options.menuWidth - 10, leftPos]}, {duration: 200, queue: false, easing: 'easeOutQuad'}); $overlay.velocity({opacity: 0 }, {duration: 200, queue: false, easing: 'easeOutQuad', complete: function () { $(this).remove(); }}); $dragTarget.css({width: '10px', right: '', left: 0}); } } else { if ((menuOut && velocityX >= -0.3) || velocityX > 0.5) { // Return menu to open if (rightPos !== 0) { menu.velocity({'translateX': [0, rightPos]}, {duration: 300, queue: false, easing: 'easeOutQuad'}); } $overlay.velocity({opacity: 1 }, {duration: 50, queue: false, easing: 'easeOutQuad'}); $dragTarget.css({width: '50%', right: '', left: 0}); menuOut = true; } else if (!menuOut || velocityX < -0.3) { // Enable Scrolling $('body').css({ overflow: '', width: '' }); // Slide menu closed menu.velocity({'translateX': [options.menuWidth + 10, rightPos]}, {duration: 200, queue: false, easing: 'easeOutQuad'}); $overlay.velocity({opacity: 0 }, {duration: 200, queue: false, easing: 'easeOutQuad', complete: function () { $(this).remove(); }}); $dragTarget.css({width: '10px', right: 0, left: ''}); } } } }); } $this.off('click.sidenav').on('click.sidenav', function() { if (menuOut === true) { menuOut = false; panning = false; removeMenu(); } else { // Disable Scrolling var $body = $('body'); var $overlay = $('
'); var oldWidth = $body.innerWidth(); $body.css('overflow', 'hidden'); $body.width(oldWidth); // Push current drag target on top of DOM tree $('body').append($dragTarget); if (options.edge === 'left') { $dragTarget.css({width: '50%', right: 0, left: ''}); menu.velocity({'translateX': [0, -1 * options.menuWidth]}, {duration: 300, queue: false, easing: 'easeOutQuad'}); } else { $dragTarget.css({width: '50%', right: '', left: 0}); menu.velocity({'translateX': [0, options.menuWidth]}, {duration: 300, queue: false, easing: 'easeOutQuad'}); } $overlay.css('opacity', 0) .click(function(){ menuOut = false; panning = false; removeMenu(); $overlay.velocity({opacity: 0}, {duration: 300, queue: false, easing: 'easeOutQuad', complete: function() { $(this).remove(); } }); }); $('body').append($overlay); $overlay.velocity({opacity: 1}, {duration: 300, queue: false, easing: 'easeOutQuad', complete: function () { menuOut = true; panning = false; } }); } return false; }); }); }, destroy: function () { var $overlay = $('#sidenav-overlay'); var $dragTarget = $('.drag-target[data-sidenav="' + $(this).attr('data-activates') + '"]'); $overlay.trigger('click'); $dragTarget.remove(); $(this).off('click'); $overlay.remove(); }, show : function() { this.trigger('click'); }, hide : function() { $('#sidenav-overlay').trigger('click'); } }; $.fn.sideNav = function(methodOrOptions) { if ( methods[methodOrOptions] ) { return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) { // Default to "init" return methods.init.apply( this, arguments ); } else { $.error( 'Method ' + methodOrOptions + ' does not exist on jQuery.sideNav' ); } }; // Plugin end }( jQuery ));