UNPKG

hae

Version:

Mobile web UI based on Vux

266 lines (222 loc) 8.63 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+xmlbase64,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 } */ import Eventor from '../../libs/eventor' // 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 (name, attrs) { var element = document.createElementNS(SVG.svgns, name) if (attrs) { SVG.setAttr(element, attrs) } return element }, // setting attributes setAttr (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 = element.offsetWidth this.height = element.offsetHeight this.element = element this.parent = this.element.parentNode this.options = Object.assign({}, Blur.DEFAULTS, options) this.overlayEl = this.createOverlay() this.blurredImage = null this.attachListeners() this.generateBlurredImage(this.options.url) } Blur.VERSION = '0.0.1' Eventor.mixTo(Blur) Blur.DEFAULTS = { url: '', // 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.setBlurAmount = function (blurAmount) { this.options.blurAmount = blurAmount } Blur.prototype.attachListeners = function () { this.on('ui.blur.loaded', this.fadeIn.bind(this)) this.on('ui.blur.unload', this.fadeOut.bind(this)) } Blur.prototype.fadeIn = function () { } Blur.prototype.fadeOut = function () { } Blur.prototype.generateBlurredImage = function (url) { const previousImage = this.blurredImage this.internalID = randomID() if (previousImage) { previousImage.parentNode.removeChild(previousImage) } this.blurredImage = this.createSVG(url, this.width, this.height) } Blur.prototype.createOverlay = function () { if (this.options.overlayClass && this.options.overlayClass !== '') { const div = document.createElement('div') div.classList.add(this.options.overlayClass) this.parent.insertBefore(div, this.element) return div } 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.emit('ui.blur.loaded') }, true) image.addEventListener('SVGLoad', function () { that.emit('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 // 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.style.opacity = 0 window.setTimeout(function () { if (getStyle(svg, 'opacity') === '0') { svg.style.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 const styles = { // 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) } for (var i in styles) { originalImage.style[i] = styles[i] } originalImage.setAttribute('id', this.internalID) originalImage.onload = function () { that.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 (getStyle(originalImage, 'opacity') === '0') { originalImage.style.opacity = 1 } }, this.options.duration + 100) } return originalImage } Blur.prototype.prependImage = function (url) { const img = document.createElement('img') img.url = url img.setAttribute('id', this.internalID) img.classList.add(this.options.imageClass) if (this.overlayEl) { this.parent.insertBefore(img, this.overlayEl) } else { this.parent.insertBefore(img, this.parent.firstChild) } return img } export default Blur function getStyle (ele, prop) { return window.getComputedStyle(ele, null).getPropertyValue(prop) }