UNPKG

background-blur

Version:

jQuery Plugin for cross-browser blurring of images

382 lines (322 loc) 12.5 kB
/* Image Blur plugin, author @msurguy Usage: Create a set of elements that follows the following HTML structure: <div class="container"> <div class="content"> ... </div> </div> Add the following css: .container { overflow: hidden; width: 100%; position: relative; } .container .bg-blur-overlay { z-index: -1; position: absolute; width: 100%; height: 100%; background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4gPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PGxpbmVhckdyYWRpZW50IGlkPSJncmFkIiBncmFkaWVudFVuaXRzPSJvYmplY3RCb3VuZGluZ0JveCIgeDE9IjAuNSIgeTE9IjAuMCIgeDI9IjAuNSIgeTI9IjEuMCI+PHN0b3Agb2Zmc2V0PSI0NiUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC4wOCIvPjxzdG9wIG9mZnNldD0iNTklIiBzdG9wLWNvbG9yPSIjMDAwMDAwIiBzdG9wLW9wYWNpdHk9IjAuMDgiLz48c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiMwMDAwMDAiIHN0b3Atb3BhY2l0eT0iMC45Ii8+PC9saW5lYXJHcmFkaWVudD48L2RlZnM+PHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgZmlsbD0idXJsKCNncmFkKSIgLz48L3N2Zz4g'); background-size: 100%; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(46%, rgba(0, 0, 0, 0.08)), color-stop(59%, rgba(0, 0, 0, 0.08)), color-stop(100%, rgba(0, 0, 0, 0.9))); background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0.08) 46%, rgba(0, 0, 0, 0.08) 59%, rgba(0, 0, 0, 0.9) 100%); background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.08) 46%, rgba(0, 0, 0, 0.08) 59%, rgba(0, 0, 0, 0.9) 100%); background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.08) 46%, rgba(0, 0, 0, 0.08) 59%, rgba(0, 0, 0, 0.9) 100%); } .container .bg-blur { z-index: -2; opacity: 0; position: absolute; width: 100%; min-height: 100%; height: auto; display: block; top: 0; left: 0; } .container .content { z-index: 1; } Call the plugin on the container element to add a blurred background to it: $('.container').backgroundBlur({ imageURL : 'http://website.com/images/img.jpg', // URL to the image that will be used for blurring blurAmount : 10, // Amount of blurrines imageClass : 'bg-blur', // CSS class that will be applied to the image and to the SVG element, overlayClass : 'bg-blur-overlay', // CSS class of an element that will overlay the blur background (useful for additional effects) duration : 1000, // If the image needs to be faded in, how long that should take endOpacity : 0.6 // Specify the final opacity that the image will have }); Available methods of the plugin are : $('.container').backgroundBlur('string'); // swap the image to another image while using initial settings for animation $('.container').backgroundBlur('fadeIn'); // fade in $('.container').backgroundBlur('fadeOut'); // fade out */ ;(function ($) { 'use strict'; // IE version detection var ie = (function() { var undef, v = 3, div = document.createElement('div'), all = div.getElementsByTagName('i'); while ( div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->', all[0] ){} return v > 4 ? v : undef; }()); // Random ID generator var randomID = function () { return '_' + Math.random().toString(36).substr(2, 9); }; //micro lib that creates SVG elements and adds attributes to it var SVG = { //namespaces svgns: 'http://www.w3.org/2000/svg', xlink: 'http://www.w3.org/1999/xlink', //creating of SVG element createElement: function(name, attrs) { var element = document.createElementNS(SVG.svgns, name); if (attrs) { SVG.setAttr(element, attrs); } return element; }, //setting attributes setAttr: function(element, attrs) { for (var i in attrs) { if (i === 'href') { //path of an image should be stored as xlink:href attribute element.setAttributeNS(SVG.xlink, i, attrs[i]); } else { //other common attribute element.setAttribute(i, attrs[i]); } } return element; } }; // backgroundBlur PUBLIC CLASS DEFINITION // ================================ var Blur = function (element, options) { this.internalID = randomID(); this.$element = $(element); this.$width = this.$element.width(); this.$height = this.$element.height(); this.element = element; this.options = $.extend({}, Blur.DEFAULTS, options); this.$overlayEl = this.createOverlay(); this.$blurredImage = {}; this.useVelocity = this.detectVelocity(); // If Velocity.js is present, use it for performant animation this.attachListeners(); this.generateBlurredImage(this.options.imageURL); }; Blur.VERSION = '0.1.1'; Blur.DEFAULTS = { imageURL : '', // URL to the image blurAmount : 10, // Amount of blurrines imageClass : '', // CSS class that will be applied to the image and to the SVG element, overlayClass : '', // CSS class of the element that will overlay the blur image duration : false, // If the image needs to be faded in, how long should that take opacity : 1 // Specify the final opacity }; Blur.prototype.detectVelocity= function() { return !!window.jQuery.Velocity; }; Blur.prototype.attachListeners = function() { this.$element.on('ui.blur.loaded', $.proxy(this.fadeIn, this)); this.$element.on('ui.blur.unload', $.proxy(this.fadeOut, this)); }; Blur.prototype.fadeIn = function () { if (this.options.duration && this.options.duration > 0) { if (this.useVelocity) { this.$blurredImage .velocity({ opacity: this.options.opacity }, { duration: this.options.duration }); } else { this.$blurredImage .animate({ opacity: this.options.opacity }, { duration: this.options.duration }); } } }; Blur.prototype.fadeOut = function () { if (this.options.duration && this.options.duration > 0) { if (this.useVelocity) { this.$blurredImage .velocity({ opacity: 0 }, { duration: this.options.duration }); } else { this.$blurredImage .animate({ opacity: 0 }, { duration: this.options.duration }); } } else { this.$blurredImage.css({'opacity' : 0 }); } }; Blur.prototype.generateBlurredImage = function (url) { var $previousImage = this.$blurredImage; this.internalID = randomID(); if( $previousImage.length > 0) { if (this.options.duration && this.options.duration > 0) { if (this.useVelocity) { $previousImage.first().velocity({ opacity: 0 },{ duration : this.options.duration, complete : function() { $previousImage.remove(); } }); } else { $previousImage.first().animate({ opacity: 0 },{ duration : this.options.duration, complete : function() { $previousImage.remove(); } }); } } else { $previousImage.remove(); } } if (!ie) { this.$blurredImage = this.createSVG(url, this.$width, this.$height); } else { this.$blurredImage = this.createIMG(url, this.$width, this.$height); } }; Blur.prototype.createOverlay = function () { if (this.options.overlayClass && this.options.overlayClass !== ''){ return $('<div></div>').prependTo(this.$element).addClass(this.options.overlayClass); } return false; }; Blur.prototype.createSVG = function(url, width, height){ var that = this; var svg = SVG.createElement('svg', { //our SVG element xmlns: SVG.svgns, version: '1.1', width: width, height: height, id: 'blurred' + this.internalID, 'class': this.options.imageClass, viewBox: '0 0 ' + width + ' '+ height, preserveAspectRatio: 'none' }); var filterId = 'blur' + this.internalID; //id of the filter that is called by image element var filter = SVG.createElement('filter', { //filter id: filterId }); var gaussianBlur = SVG.createElement('feGaussianBlur', { // gaussian blur element 'in': 'SourceGraphic', //"in" is keyword. Opera generates an error if we don't put quotes stdDeviation: this.options.blurAmount // intensity of blur }); var image = SVG.createElement('image', { //The image that uses the filter of blur x: 0, y: 0, width: width, height: height, 'externalResourcesRequired' : 'true', href: url, style: 'filter:url(#' + filterId + ')', //filter link preserveAspectRatio: 'none' }); image.addEventListener('load', function() { that.$element.trigger('ui.blur.loaded'); }, true); image.addEventListener('SVGLoad', function() { that.$element.trigger('ui.blur.loaded'); }, true); filter.appendChild(gaussianBlur); //adding the element of blur into the element of filter svg.appendChild(filter); //adding the filter into the SVG svg.appendChild(image); //adding an element of an image into the SVG var $svg = $(svg); // Ensure that the image is shown after duration + 100 msec in case the SVG load event didn't fire or took too long if (that.options.duration && that.options.duration > 0) { $svg.css({ opacity : 0}); window.setTimeout(function(){ if ($svg.css('opacity') === '0') { $svg.css({ opacity : 1}); } }, this.options.duration + 100); } this.element.insertBefore(svg, this.element.firstChild); return $svg; }; Blur.prototype.createIMG = function(url, width, height){ var that = this; var $originalImage = this.prependImage(url); var newBlurAmount = ((this.options.blurAmount * 2) > 100) ? 100 : (this.options.blurAmount * 2); // apply special CSS attributes to the image to blur it $originalImage.css({ //filter property; here the intensity of blur multipied by two is around equal to the intensity in common browsers. filter: 'progid:DXImageTransform.Microsoft.Blur(pixelradius=' + newBlurAmount + ') ', //aligning of the blurred image by vertical and horizontal top: -this.options.blurAmount * 2.5, left: -this.options.blurAmount * 2.5, width: width + (this.options.blurAmount * 2.5), height: height + (this.options.blurAmount * 2.5) }) .attr('id', 'blurred' + this.internalID); $originalImage.load(function(){ that.$element.trigger('ui.blur.loaded'); }); // Ensure that the image is shown after duration + 100 msec in case the image load event didn't fire or took too long if (this.options.duration && this.options.duration > 0) { window.setTimeout(function(){ if ($originalImage.css('opacity') === '0') { $originalImage.css({ opacity : 1}); } }, this.options.duration + 100); } return $originalImage; }; Blur.prototype.prependImage = function(url) { var $image; var $imageEl = $('<img src="'+url+'" />'); if (this.$overlayEl) { $image = $imageEl.insertBefore(this.$overlayEl).attr('id', this.internalID).addClass(this.options.imageClass); } else { $image = $imageEl.prependTo(this.$element).attr('id', this.internalID).addClass(this.options.imageClass); } return $image; }; // backgroundBlur PLUGIN DEFINITION // ========================== function Plugin(option) { return this.each(function () { var $this = $(this); var data = $this.data('plugin.backgroundBlur'); var options = $.extend({}, Blur.DEFAULTS, $this.data(), typeof option === 'object' && option); if (!data) { $this.data('plugin.backgroundBlur', (data = new Blur(this, options))); } if (option === 'fadeIn') { data.fadeIn(); } else if (option === 'fadeOut') { data.fadeOut(); } else if (typeof option === 'string') { data.generateBlurredImage(option); } }); } var old = $.fn.backgroundBlur; $.fn.backgroundBlur = Plugin; $.fn.backgroundBlur.Constructor = Blur; // NO CONFLICT // ==================== $.fn.backgroundBlur.noConflict = function () { $.fn.backgroundBlur = old; return this; }; })(jQuery);