/*************************************************************************************************** LoadingOverlay - A flexible loading overlay jQuery plugin Author : Gaspare Sganga Version : 2.1.6 License : MIT Documentation : https://gasparesganga.com/labs/jquery-loading-overlay/ ***************************************************************************************************/ ;(function(factory){ if (typeof define === "function" && define.amd) { // AMD. Register as an anonymous module define(["jquery"], factory); } else if (typeof module === "object" && module.exports) { // Node/CommonJS factory(require("jquery")); } else { // Browser globals factory(jQuery); } }(function($, undefined){ "use strict"; // Default Settings var _defaults = { // Background background : "rgba(255, 255, 255, 0.8)", backgroundClass : "", // Image image : "", imageAnimation : "2000ms rotate_right", imageAutoResize : true, imageResizeFactor : 1, imageColor : "#202020", imageClass : "", imageOrder : 1, // Font Awesome fontawesome : "", fontawesomeAnimation : "", fontawesomeAutoResize : true, fontawesomeResizeFactor : 1, fontawesomeColor : "#202020", fontawesomeOrder : 2, // Custom custom : "", customAnimation : "", customAutoResize : true, customResizeFactor : 1, customOrder : 3, // Text text : "", textAnimation : "", textAutoResize : true, textResizeFactor : 0.5, textColor : "#202020", textClass : "", textOrder : 4, // Progress progress : false, progressAutoResize : true, progressResizeFactor : 0.25, progressColor : "#a0a0a0", progressClass : "", progressOrder : 5, progressFixedPosition : "", progressSpeed : 200, progressMin : 0, progressMax : 100, // Sizing size : 50, maxSize : 120, minSize : 20, // Misc direction : "column", fade : true, resizeInterval : 50, zIndex : 2147483647 }; // Required CSS var _css = { overlay : { "box-sizing" : "border-box", "position" : "relative", "display" : "flex", "flex-wrap" : "nowrap", "align-items" : "center", "justify-content" : "space-around" }, element : { "box-sizing" : "border-box", "overflow" : "visible", "flex" : "0 0 auto", "display" : "flex", "justify-content" : "center", "align-items" : "center" }, element_svg : { "width" : "100%", "height" : "100%" }, progress_fixed : { "position" : "absolute", "left" : "0", "width" : "100%" }, progress_wrapper : { "position" : "absolute", "top" : "0", "left" : "0", "width" : "100%", "height" : "100%" }, progress_bar : { "position" : "absolute", "left" : "0" } }; // Data Template var _dataTemplate = { "count" : 0, "container" : undefined, "settings" : undefined, "wholePage" : undefined, "resizeIntervalId" : undefined, "text" : undefined, "progress" : undefined }; // Whitelists var _whitelists = { animations : [ "rotate_right", "rotate_left", "fadein", "pulse" ], progressPosition : [ "top", "bottom" ] }; // Default Values var _defaultValues = { animations : { name : "rotate_right", time : "2000ms" }, fade : [400, 200] }; $.LoadingOverlaySetup = function(settings){ $.extend(true, _defaults, settings); }; $.LoadingOverlay = function(action, options){ switch (action.toLowerCase()) { case "show": var settings = $.extend(true, {}, _defaults, options); Show("body", settings); break; case "hide": Hide("body", options); break; case "resize": Resize("body", options); break; case "text": Text("body", options); break; case "progress": Progress("body", options); break; } }; $.fn.LoadingOverlay = function(action, options){ switch (action.toLowerCase()) { case "show": var settings = $.extend(true, {}, _defaults, options); return this.each(function(){ Show(this, settings); }); case "hide": return this.each(function(){ Hide(this, options); }); case "resize": return this.each(function(){ Resize(this, options); }); case "text": return this.each(function(){ Text(this, options); }); case "progress": return this.each(function(){ Progress(this, options); }); } }; function Show(container, settings){ container = $(container); settings.size = _ParseSize(settings.size); settings.maxSize = parseInt(settings.maxSize, 10) || 0; settings.minSize = parseInt(settings.minSize, 10) || 0; settings.resizeInterval = parseInt(settings.resizeInterval, 10) || 0; var overlay = _GetOverlay(container); var data = _GetData(container); if (data === false) { // Init data data = $.extend({}, _dataTemplate); data.container = container; data.wholePage = container.is("body"); // Overlay overlay = $("
", { "class" : "loadingoverlay" }) .css(_css.overlay) .css("flex-direction", settings.direction.toLowerCase() === "row" ? "row" : "column"); if (settings.backgroundClass) { overlay.addClass(settings.backgroundClass); } else { overlay.css("background", settings.background); } if (data.wholePage) { overlay.css({ "position" : "fixed", "top" : 0, "left" : 0, "width" : "100%", "height" : "100%" }); } if (typeof settings.zIndex !== "undefined") overlay.css("z-index", settings.zIndex); // Image if (settings.image) { if ($.isArray(settings.imageColor)) { if (settings.imageColor.length === 0) { settings.imageColor = false; } else if (settings.imageColor.length === 1) { settings.imageColor = { "fill" : settings.imageColor[0] }; } else { settings.imageColor = { "fill" : settings.imageColor[0], "stroke" : settings.imageColor[1] }; } } else if (settings.imageColor) { settings.imageColor = { "fill" : settings.imageColor }; } var element = _CreateElement(overlay, settings.imageOrder, settings.imageAutoResize, settings.imageResizeFactor, settings.imageAnimation); if (settings.image.slice(0, 4).toLowerCase() === "") { // Inline SVG element.append(settings.image); element.children().css(_css.element_svg); if (!settings.imageClass && settings.imageColor) element.find("*").css(settings.imageColor); } else if (settings.image.slice(-4).toLowerCase() === ".svg" || settings.image.slice(0, 14).toLowerCase() === "data:image/svg") { // SVG file or base64-encoded SVG $.ajax({ url : settings.image, type : "GET", dataType : "html", global : false }).done(function(data){ element.html(data); element.children().css(_css.element_svg); if (!settings.imageClass && settings.imageColor) element.find("*").css(settings.imageColor); }); } else { // Raster element.css({ "background-image" : "url(" + settings.image + ")", "background-position" : "center", "background-repeat" : "no-repeat", "background-size" : "cover" }); } if (settings.imageClass) element.addClass(settings.imageClass); } // Font Awesome if (settings.fontawesome) { var element = _CreateElement(overlay, settings.fontawesomeOrder, settings.fontawesomeAutoResize, settings.fontawesomeResizeFactor, settings.fontawesomeAnimation) .addClass("loadingoverlay_fa"); $("
", { "class" : settings.fontawesome }).appendTo(element); if (settings.fontawesomeColor) element.css("color", settings.fontawesomeColor); } // Custom if (settings.custom) { var element = _CreateElement(overlay, settings.customOrder, settings.customAutoResize, settings.customResizeFactor, settings.customAnimation) .append(settings.custom); } // Text if (settings.text) { data.text = _CreateElement(overlay, settings.textOrder, settings.textAutoResize, settings.textResizeFactor, settings.textAnimation) .addClass("loadingoverlay_text") .text(settings.text); if (settings.textClass) { data.text.addClass(settings.textClass); } else if (settings.textColor) { data.text.css("color", settings.textColor); } } // Progress if (settings.progress) { var element = _CreateElement(overlay, settings.progressOrder, settings.progressAutoResize, settings.progressResizeFactor, false) .addClass("loadingoverlay_progress"); var wrapper = $("
") .css(_css.progress_wrapper) .appendTo(element); data.progress = { bar : $("
").css(_css.progress_bar).appendTo(wrapper), fixed : false, margin : 0, min : parseFloat(settings.progressMin), max : parseFloat(settings.progressMax), speed : parseInt(settings.progressSpeed, 10) }; var progressPositionParts = (settings.progressFixedPosition + "").replace(/\s\s+/g, " ").toLowerCase().split(" "); if (progressPositionParts.length === 2 && _ValidateProgressPosition(progressPositionParts[0])) { data.progress.fixed = progressPositionParts[0]; data.progress.margin = _ParseSize(progressPositionParts[1]); } else if (progressPositionParts.length === 2 && _ValidateProgressPosition(progressPositionParts[1])) { data.progress.fixed = progressPositionParts[1]; data.progress.margin = _ParseSize(progressPositionParts[0]); } else if (progressPositionParts.length === 1 && _ValidateProgressPosition(progressPositionParts[0])) { data.progress.fixed = progressPositionParts[0]; data.progress.margin = 0; } if (data.progress.fixed === "top") { element .css(_css.progress_fixed) .css("top", data.progress.margin ? data.progress.margin.value + (data.progress.margin.fixed ? data.progress.margin.units : "%") : 0); } else if (data.progress.fixed === "bottom") { element .css(_css.progress_fixed) .css("top", "auto"); } if (settings.progressClass) { data.progress.bar.addClass(settings.progressClass); } else if (settings.progressColor) { data.progress.bar.css("background", settings.progressColor); } } // Fade if (!settings.fade) { settings.fade = [0, 0]; } else if (settings.fade === true) { settings.fade = _defaultValues.fade; } else if (typeof settings.fade === "string" || typeof settings.fade === "number") { settings.fade = [settings.fade, settings.fade]; } else if ($.isArray(settings.fade) && settings.fade.length < 2) { settings.fade = [settings.fade[0], settings.fade[0]]; } settings.fade = [parseInt(settings.fade[0], 10), parseInt(settings.fade[1], 10)] // Save settings data.settings = settings; // Save data overlay.data("loadingoverlay_data", data); // Save reference to overlay container.data("loadingoverlay", overlay); // Resize overlay .fadeTo(0, 0.01) .appendTo("body"); _IntervalResize(container, true); if (settings.resizeInterval > 0) { data.resizeIntervalId = setInterval(function(){ _IntervalResize(container, false); }, settings.resizeInterval); } // Show LoadingOverlay overlay.fadeTo(settings.fade[0], 1); } data.count++; } function Hide(container, force){ container = $(container); var overlay = _GetOverlay(container); var data = _GetData(container); if (data === false) return; data.count--; if (force || data.count <= 0) { overlay.animate({ "opacity" : 0 }, data.settings.fade[1], function(){ if (data.resizeIntervalId) clearInterval(data.resizeIntervalId); $(this).remove(); container.removeData("loadingoverlay"); }); } } function Resize(container){ _IntervalResize($(container), true); } function Text(container, value){ container = $(container); var data = _GetData(container); if (data === false || !data.text) return; if (value === false) { data.text.hide(); } else { data.text .show() .text(value); } } function Progress(container, value){ container = $(container); var data = _GetData(container); if (data === false || !data.progress) return; if (value === false) { data.progress.bar.hide(); } else { var v = ((parseFloat(value) || 0) - data.progress.min) * 100 / (data.progress.max - data.progress.min); if (v < 0) v = 0; if (v > 100) v = 100; data.progress.bar .show() .animate({ "width" : v + "%" }, data.progress.speed); } } function _IntervalResize(container, force){ var overlay = _GetOverlay(container); var data = _GetData(container); if (data === false) return; // Overlay if (!data.wholePage) { var isFixed = container.css("position") === "fixed"; var pos = isFixed ? container[0].getBoundingClientRect() : container.offset(); overlay.css({ "position" : isFixed ? "fixed" : "absolute", "top" : pos.top + parseInt(container.css("border-top-width"), 10), "left" : pos.left + parseInt(container.css("border-left-width"), 10), "width" : container.innerWidth(), "height" : container.innerHeight() }); } // Elements if (data.settings.size) { var c = data.wholePage ? $(window) : container; var size = data.settings.size.value; if (!data.settings.size.fixed) { size = Math.min(c.innerWidth(), c.innerHeight()) * size / 100; if (data.settings.maxSize && size > data.settings.maxSize) size = data.settings.maxSize; if (data.settings.minSize && size < data.settings.minSize) size = data.settings.minSize; } overlay.children(".loadingoverlay_element").each(function(){ var $this = $(this); if (force || $this.data("loadingoverlay_autoresize")) { var resizeFactor = $this.data("loadingoverlay_resizefactor"); if ($this.hasClass("loadingoverlay_fa") || $this.hasClass("loadingoverlay_text")) { $this.css("font-size", (size * resizeFactor) + data.settings.size.units); } else if ($this.hasClass("loadingoverlay_progress")) { data.progress.bar.css("height", (size * resizeFactor) + data.settings.size.units); if (!data.progress.fixed) { data.progress.bar .css("top", $this.position().top) .css("top", "-=" + (size * resizeFactor * 0.5) + data.settings.size.units); } else if (data.progress.fixed === "bottom") { $this .css("bottom", data.progress.margin ? data.progress.margin.value + (data.progress.margin.fixed ? data.progress.margin.units : "%") : 0) .css("bottom", "+=" + (size * resizeFactor) + data.settings.size.units); } } else { $this.css({ "width" : (size * resizeFactor) + data.settings.size.units, "height" : (size * resizeFactor) + data.settings.size.units }); } } }); } } function _GetOverlay(container){ return container.data("loadingoverlay"); } function _GetData(container){ var overlay = _GetOverlay(container); var data = (typeof overlay === "undefined") ? undefined : overlay.data("loadingoverlay_data"); if (typeof data === "undefined") { // Clean DOM $(".loadingoverlay").each(function(){ var $this = $(this); var data = $this.data("loadingoverlay_data"); if (!document.body.contains(data.container[0])) { if (data.resizeIntervalId) clearInterval(data.resizeIntervalId); $this.remove(); } }); return false; } else { overlay.toggle(container.is(":visible")); return data; } } function _CreateElement(overlay, order, autoResize, resizeFactor, animation){ var element = $("
", { "class" : "loadingoverlay_element", "css" : { "order" : order } }) .css(_css.element) .data({ "loadingoverlay_autoresize" : autoResize, "loadingoverlay_resizefactor" : resizeFactor }) .appendTo(overlay); // Parse animation if (animation === true) animation = _defaultValues.animations.time + " " + _defaultValues.animations.name; if (typeof animation === "string") { var animationName; var animationTime; var parts = animation.replace(/\s\s+/g, " ").toLowerCase().split(" "); if (parts.length === 2 && _ValidateCssTime(parts[0]) && _ValidateAnimation(parts[1])) { animationName = parts[1]; animationTime = parts[0]; } else if (parts.length === 2 && _ValidateCssTime(parts[1]) && _ValidateAnimation(parts[0])) { animationName = parts[0]; animationTime = parts[1]; } else if (parts.length === 1 && _ValidateCssTime(parts[0])) { animationName = _defaultValues.animations.name; animationTime = parts[0]; } else if (parts.length === 1 && _ValidateAnimation(parts[0])) { animationName = parts[0]; animationTime = _defaultValues.animations.time; } element.css({ "animation-name" : "loadingoverlay_animation__" + animationName, "animation-duration" : animationTime, "animation-timing-function" : "linear", "animation-iteration-count" : "infinite" }); } return element; } function _ValidateCssTime(value){ return !isNaN(parseFloat(value)) && (value.slice(-1) === "s" || value.slice(-2) === "ms"); } function _ValidateAnimation(value){ return _whitelists.animations.indexOf(value) > -1; } function _ValidateProgressPosition(value){ return _whitelists.progressPosition.indexOf(value) > -1; } function _ParseSize(value){ if (!value || value < 0) { return false; } else if (typeof value === "string" && ["vmin", "vmax"].indexOf(value.slice(-4)) > -1) { return { fixed : true, units : value.slice(-4), value : value.slice(0, -4) }; } else if (typeof value === "string" && ["rem"].indexOf(value.slice(-3)) > -1) { return { fixed : true, units : value.slice(-3), value : value.slice(0, -3) }; } else if (typeof value === "string" && ["px", "em", "cm", "mm", "in", "pt", "pc", "vh", "vw"].indexOf(value.slice(-2)) > -1) { return { fixed : true, units : value.slice(-2), value : value.slice(0, -2) }; } else { return { fixed : false, units : "px", value : parseFloat(value) }; } } $(function(){ $("head").append([ "" ].join(" ")); }); }));