From be8072cbf4d86f8e3926616fc3fd4e7ef2584ab5 Mon Sep 17 00:00:00 2001 From: Gianluca Guarini Date: Mon, 23 Jun 2014 23:26:31 +0200 Subject: [PATCH] pre release --- .jsbeautifyrc | 4 +- .jshintrc | 2 +- src/BnWWorker.js | 2 +- src/jquery.BlackAndWhite.js | 640 +++++++++++++++++++----------------- 4 files changed, 334 insertions(+), 314 deletions(-) diff --git a/.jsbeautifyrc b/.jsbeautifyrc index e72a31a..30364c1 100644 --- a/.jsbeautifyrc +++ b/.jsbeautifyrc @@ -1,6 +1,6 @@ { - "indent_size": 4, - "indent_char": " ", + "indent_size": 2, + "indent_char": " ", "indent_level": 0, "indent_with_tabs": true, "preserve_newlines": true, diff --git a/.jshintrc b/.jshintrc index 6334115..4941a9c 100644 --- a/.jshintrc +++ b/.jshintrc @@ -8,5 +8,5 @@ "sub": true, // true: Tolerate using `[]` notation when it can still be expressed in dot notation "boss": true, // true: Tolerate assignments where comparisons would be expected "eqnull": true, // true: Tolerate use of `== null` - "indent":4 + "indent":2 } diff --git a/src/BnWWorker.js b/src/BnWWorker.js index be79341..4d75d2a 100755 --- a/src/BnWWorker.js +++ b/src/BnWWorker.js @@ -1,4 +1,4 @@ -this.onmessage = function(event) { +this.onmessage = function (event) { var imagedata = event.data.imgData, intensity = event.data.intensity, px = imagedata.data, diff --git a/src/jquery.BlackAndWhite.js b/src/jquery.BlackAndWhite.js index ae81773..6923378 100755 --- a/src/jquery.BlackAndWhite.js +++ b/src/jquery.BlackAndWhite.js @@ -29,314 +29,334 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. **/ -(function($) { - $.fn.extend({ - BlackAndWhite: function(customOptions) { - 'use strict'; - var $el = this, - - /** - * - * Options - * - */ - - options = $.extend({ - hoverEffect: true, - webworkerPath: false, - invertHoverEffect: false, - speed: 500, - onImageReady: null, - intensity: 1 - }, customOptions), - - // options shorthand - hoverEffect = options.hoverEffect, - webworkerPath = options.webworkerPath, - invertHoverEffect = options.invertHoverEffect, - intensity = (typeof options.intensity === 'number' && options.intensity < 1 && options.intensity > 0) ? options.intensity : 1, - fadeSpeedIn = $.isPlainObject(options.speed) ? options.speed.fadeIn : options.speed, - fadeSpeedOut = $.isPlainObject(options.speed) ? options.speed.fadeOut : options.speed, - $window = $(window), - - /** - * - * Private vars - * - */ - - _tmpID = '_' + new Date().getTime(), - _isIE7 = (document.all && !window.opera && window.XMLHttpRequest) ? true : false, - _browserPrefixes = ' -webkit- -moz- -o- -ms- '.split(' '), - _cssPrefixString = {}, - - /** - * - * features detection - * - */ - - _cssPrefix = function(property) { - if (_cssPrefixString[property] || _cssPrefixString[property] === '') { - return _cssPrefixString[property] + property; - } - var e = document.createElement('div'), - prefixes = ['', 'Moz', 'Webkit', 'O', 'ms', 'Khtml']; // Various supports... - for (var i in prefixes) { - if (typeof e.style[prefixes[i] + property] !== 'undefined') { - _cssPrefixString[property] = prefixes[i]; - return prefixes[i] + property; - } - } - return property.toLowerCase(); - }, - // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/css-filters.js - _cssfilters = (function() { - var el = document.createElement('div'); - el.style.cssText = _browserPrefixes.join('filter' + ':blur(2px); '); - return !!el.style.length && ((document.documentMode === undefined || document.documentMode > 9)); - }()), - _supportsCanvas = !!document.createElement('canvas').getContext, - /* Check if Web Workers are supported */ - _supportWebworker = (function() { - return (typeof(Worker) !== 'undefined') ? true : false; - }()), - _cssFilter = _cssPrefix('Filter'), - _imagesArray = [], - _webWorker = _supportWebworker && webworkerPath ? new Worker(webworkerPath + 'BnWWorker.js') : false, - - /** - * - * Private methods - * - */ - - /** - * Mouse leave event callback delegated to the the images container - * @param { Object } e jquery event object - */ - _onMouseLeave = function(e) { - $(e.currentTarget) - .find('.BWfade') - .stop(true, true) - .animate({ - opacity: invertHoverEffect ? 0 : 1 - },fadeSpeedOut); - }, - /** - * mouseenter event callback delegated to the the images container ($el) - * @param { Object } e jquery event object - */ - _onMouseEnter = function(e) { - $(e.currentTarget) - .find('.BWfade') - .stop(true, true) - .animate({ - opacity: invertHoverEffect ? 1 : 0 - },fadeSpeedOut); - }, - /** - * Callback triggered anytime an image gets loaded and converted - * @param { Object } img: DOM image object - */ - _onImageReady = function(img) { - if (typeof options.onImageReady === 'function') { - options.onImageReady(img); - } - }, - /** - * Initialize the webworker loop - * @param { Int } imagesToLoadlength: the amount of images passed to the plugin but not loaded yet - */ - _initWebworker = function(imagesToLoadlength) { - // start the webworker when all the images are ready - if (_webWorker && _supportsCanvas && !_cssfilters && !imagesToLoadlength) { - // web worker implementation - _webWorkerLoop(); - } - }, - /** - * Loop all the images converting them by using the a webworker script (this process is unobstrusive and it does not block the page loading) - */ - _webWorkerLoop = function() { - - if (!_imagesArray.length) { - // terminate the worker - // the standard way - http://www.w3.org/TR/workers/#dedicated-workers-and-the-worker-interface - if (_webWorker.terminate) { - _webWorker.terminate(); - } - // IE 10 specific - http://msdn.microsoft.com/en-us/library/ie/hh673568(v=vs.85).aspx - if (_webWorker.close) { - _webWorker.close(); - } - return; - } - - // dispatch the image data to the webworker - _webWorker.postMessage({ - imgData: _imagesArray[0].imageData, - intensity: intensity - }); - - // anytime a new image gets converted we continue the loop - _webWorker.onmessage = function(event) { - _imagesArray[0].ctx.putImageData(event.data, 0, 0); - _onImageReady(_imagesArray[0].img); - _imagesArray.splice(0, 1); - _webWorkerLoop(); - }; - }, - /** - * Helper function to check whether an image has been completely loaded - * @param { Object } img: DOM image object - */ - _isImageLoaded = function(img) { - return img.complete || (typeof img.naturalWidth !== 'undefined' && img.naturalWidth); - }, - /** - * Use the HTML5 canvas to generate a B&W image - * @param { Object } img: DOM image object - * @param { Object } canvas: canvas element where we are going to draw - * @param { Int } width: image width - * @param { Int } height: image height - */ - _generateCanvasImage = function(img, canvas, width, height) { - var ctx = canvas.getContext('2d'), - currImg = img, - i = 0, - grey; - - ctx.drawImage(img, 0, 0, width, height); - - var imageData = ctx.getImageData(0, 0, width, height), - px = imageData.data, - length = px.length; - - // web worker superfast implementation - if (_webWorker) { - _imagesArray.push({ - imageData: imageData, - ctx: ctx, - img: img - }); - } else { - - // no webworker slow implementation - for (; i < length; i += 4) { - var k = px[i] * 0.3 + px[i + 1] * 0.59 + px[i + 2] * 0.11; - px[i] = ~~ (k * intensity + px[i] * (1 - intensity)); - px[i + 1] = ~~ (k * intensity + px[i + 1] * (1 - intensity)); - px[i + 2] = ~~ (k * intensity + px[i + 2] * (1 - intensity)); - } - - ctx.putImageData(imageData, 0, 0); - - _onImageReady(img); - } - }, - /** - * Print the html element needed to show the B&W image - * @param { Array } $img: jQuery array containing the image - * @param { Array } $imageWrapper: jQuery array containing the image parent element - */ - _injectTags = function($img, $imageWrapper) { - - var img = $img[0], - src = img.src, - css = { - position: 'absolute', - '-webkit-transform': 'translate3d(0,0,0)', // fix for webkit browsers - opacity: invertHoverEffect ? 0 : 1 - }, - $overlay; - - img.crossOrigin = 'anonymous'; - - if (_supportsCanvas && !_cssfilters) { - // add the canvas - $overlay = $(''); - _generateCanvasImage(img, $overlay.get(0), img.width, img.height); - - } else { - css[_cssFilter] = 'grayscale(' + intensity * 100 + '%)'; - // clone the original image using the css filters - $overlay = $img.clone().addClass('BWFilter BWfade'); - _onImageReady(img); - } - - $overlay - .css($.extend(css, { - 'filter': 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)' - })) - .prependTo($imageWrapper); - - // fix opacity on the old browsers - if (!$.support.opacity && invertHoverEffect) { - $overlay.animate({ - opacity:0 - },0); - } - }, - /** - * Init the plugin stuff - */ - _init = function() { - var imagesToLoadlength = $el.find('img').filter(function() { - return !$(this).data('_b&w'); - }).length; - // convert all the images - $el.each(function(index, tmpImageWrapper) { - var $imageWrapper = $(tmpImageWrapper), - $img = $imageWrapper.find('img'); - // this image got already converted - if ($img.data('_b&w')) { - return; - } - // if this image is not loaded yet - if (!_isImageLoaded($img[0])) { - $img.on('load', function() { - if ($img.data('_b&w_loaded') || !$img[0].complete) { - setTimeout(function() { - $img.load(); - }, 20); - return; - } - _injectTags($img, $imageWrapper); - $img.data('_b&w_loaded', true); - imagesToLoadlength--; - _initWebworker(imagesToLoadlength); - }).load(); - } else { - imagesToLoadlength--; - _injectTags($img, $imageWrapper); - } - $img.data('_b&w', true); - }); - - _initWebworker(imagesToLoadlength); - // binding the hover effect - if (hoverEffect) { - $el.on('mouseleave.' + _tmpID, _onMouseLeave); - $el.on('mouseenter.' + _tmpID, _onMouseEnter); - } - }; - - /** - * - * Public Api - * - */ - - var destroy = function() { - $el.off('.' + _tmpID); - }; - - _init(); - - return { - destroy: destroy - }; - } - }); +(function ($) { + $.fn.extend({ + BlackAndWhite: function (customOptions) { + 'use strict'; + var $el = this, + + /** + * + * Options + * + */ + + options = $.extend({ + hoverEffect: true, + webworkerPath: false, + invertHoverEffect: false, + speed: 500, + onImageReady: null, + intensity: 1 + }, customOptions), + + // options shorthand + hoverEffect = options.hoverEffect, + webworkerPath = options.webworkerPath, + invertHoverEffect = options.invertHoverEffect, + intensity = (typeof options.intensity === 'number' && options.intensity < 1 && options.intensity > 0) ? options.intensity : 1, + fadeSpeedIn = $.isPlainObject(options.speed) ? options.speed.fadeIn : options.speed, + fadeSpeedOut = $.isPlainObject(options.speed) ? options.speed.fadeOut : options.speed, + $window = $(window), + + /** + * + * Private vars + * + */ + + _tmpID = '_' + new Date().getTime(), + _isIE7 = (document.all && !window.opera && window.XMLHttpRequest) ? true : false, + _browserPrefixes = ' -webkit- -moz- -o- -ms- '.split(' '), + _cssPrefixString = {}, + + /** + * + * features detection + * + */ + + _cssPrefix = function (property) { + if (_cssPrefixString[property] || _cssPrefixString[property] === '') { + return _cssPrefixString[property] + property; + } + var e = document.createElement('div'), + prefixes = ['', 'Moz', 'Webkit', 'O', 'ms', 'Khtml']; // Various supports... + for (var i in prefixes) { + if (typeof e.style[prefixes[i] + property] !== 'undefined') { + _cssPrefixString[property] = prefixes[i]; + return prefixes[i] + property; + } + } + return property.toLowerCase(); + }, + // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/css-filters.js + _cssfilters = (function () { + var el = document.createElement('div'); + el.style.cssText = _browserPrefixes.join('filter' + ':blur(2px); '); + return !!el.style.length && ((document.documentMode === undefined || document.documentMode > 9)); + }()), + _supportsCanvas = !!document.createElement('canvas').getContext, + /* Check if Web Workers are supported */ + _supportWebworker = (function () { + return (typeof (Worker) !== 'undefined') ? true : false; + }()), + _cssFilter = _cssPrefix('Filter'), + _imagesArray = [], + _webWorker = _supportWebworker && webworkerPath ? new Worker(webworkerPath + 'BnWWorker.js') : false, + + /** + * + * Private methods + * + */ + + /** + * Mouse leave event callback delegated to the the images container + * @param { Object } e jquery event object + */ + _onMouseLeave = function (e) { + $(e.currentTarget) + .find('.BWfade') + .stop(true, true) + .animate({ + opacity: invertHoverEffect ? 0 : 1 + }, fadeSpeedOut); + }, + /** + * mouseenter event callback delegated to the the images container ($el) + * @param { Object } e jquery event object + */ + _onMouseEnter = function (e) { + $(e.currentTarget) + .find('.BWfade') + .stop(true, true) + .animate({ + opacity: invertHoverEffect ? 1 : 0 + }, fadeSpeedOut); + }, + /** + * Callback triggered anytime an image gets loaded and converted + * @param { Object } img: DOM image object + */ + _onImageReady = function (img) { + if (typeof options.onImageReady === 'function') { + options.onImageReady(img); + } + }, + /** + * Initialize the webworker loop + * @param { Int } imagesToLoadlength: the amount of images passed to the plugin but not loaded yet + */ + _initWebworker = function (imagesToLoadlength) { + // start the webworker when all the images are ready + if (_webWorker && _supportsCanvas && !_cssfilters && !imagesToLoadlength) { + // web worker implementation + _webWorkerLoop(); + } + }, + /** + * Loop all the images converting them by using the a webworker script (this process is unobstrusive and it does not block the page loading) + */ + _webWorkerLoop = function () { + + if (!_imagesArray.length) { + // terminate the worker + // the standard way - http://www.w3.org/TR/workers/#dedicated-workers-and-the-worker-interface + if (_webWorker.terminate) { + _webWorker.terminate(); + } + // IE 10 specific - http://msdn.microsoft.com/en-us/library/ie/hh673568(v=vs.85).aspx + if (_webWorker.close) { + _webWorker.close(); + } + return; + } + + // dispatch the image data to the webworker + _webWorker.postMessage({ + imgData: _imagesArray[0].imageData, + intensity: intensity + }); + + // anytime a new image gets converted we continue the loop + _webWorker.onmessage = function (event) { + _imagesArray[0].ctx.putImageData(event.data, 0, 0); + _onImageReady(_imagesArray[0].img); + _imagesArray.splice(0, 1); + _webWorkerLoop(); + }; + }, + /** + * Helper function to check whether an image has been completely loaded + * @param { Object } img: DOM image object + */ + _isImageLoaded = function (img) { + return img.complete || (typeof img.naturalWidth !== 'undefined' && img.naturalWidth); + }, + /** + * Use the HTML5 canvas to generate a B&W image + * @param { Object } img: DOM image object + * @param { Object } canvas: canvas element where we are going to draw + * @param { Int } width: image width + * @param { Int } height: image height + */ + _generateCanvasImage = function (img, canvas, width, height) { + var ctx = canvas.getContext('2d'), + currImg = img, + i = 0, + grey; + + ctx.drawImage(img, 0, 0, width, height); + + var imageData = ctx.getImageData(0, 0, width, height), + px = imageData.data, + length = px.length; + + // web worker superfast implementation + if (_webWorker) { + _imagesArray.push({ + imageData: imageData, + ctx: ctx, + img: img + }); + } else { + + // no webworker slow implementation + for (; i < length; i += 4) { + var k = px[i] * 0.3 + px[i + 1] * 0.59 + px[i + 2] * 0.11; + px[i] = ~~ (k * intensity + px[i] * (1 - intensity)); + px[i + 1] = ~~ (k * intensity + px[i + 1] * (1 - intensity)); + px[i + 2] = ~~ (k * intensity + px[i + 2] * (1 - intensity)); + } + + ctx.putImageData(imageData, 0, 0); + + _onImageReady(img); + } + }, + /** + * Print the html element needed to show the B&W image + * @param { Array } $img: jQuery array containing the image + * @param { Array } $imageWrapper: jQuery array containing the image parent element + */ + _injectTags = function ($img, $imageWrapper) { + + var img = $img[0], + src = img.src, + css = { + position: 'absolute', + '-webkit-transform': 'translate3d(0,0,0)', // fix for webkit browsers + opacity: invertHoverEffect ? 0 : 1 + }, + $overlay; + + img.crossOrigin = 'anonymous'; + + if (_supportsCanvas && !_cssfilters) { + // add the canvas + $overlay = $(''); + + css.width = $img.width(); + css.height = $img.height(); + _generateCanvasImage(img, $overlay.get(0), img.naturalWidth, img.naturalHeight); + + } else { + css[_cssFilter] = 'grayscale(' + intensity * 100 + '%)'; + // clone the original image using the css filters + $overlay = $img.clone().addClass('BWFilter BWfade'); + _onImageReady(img); + } + + $overlay + .css($.extend(css, { + 'filter': 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)' + })) + .prependTo($imageWrapper); + + // fix opacity on the old browsers + if (!$.support.opacity && invertHoverEffect) { + $overlay.animate({ + opacity: 0 + }, 0); + } + }, + _resizeCanvases = function () { + $el.each(function (index, currImageWrapper) { + var img = $(currImageWrapper).find('img'), + currWidth = $(img).width(), + currHeight = $(img).height(); + + $(this).find('canvas').css({ + width: currWidth, + height: currHeight + }); + + }); + }, + /** + * Init the plugin stuff + */ + _init = function () { + var imagesToLoadlength = $el.find('img').filter(function () { + return !$(this).data('_b&w'); + }).length; + // convert all the images + $el.each(function (index, tmpImageWrapper) { + var $imageWrapper = $(tmpImageWrapper), + $img = $imageWrapper.find('img'); + // this image got already converted + if ($img.data('_b&w')) { + return; + } + // if this image is not loaded yet + if (!_isImageLoaded($img[0])) { + $img.on('load', function () { + if ($img.data('_b&w_loaded') || !$img[0].complete) { + setTimeout(function () { + $img.load(); + }, 20); + return; + } + _injectTags($img, $imageWrapper); + $img.data('_b&w_loaded', true); + imagesToLoadlength--; + _initWebworker(imagesToLoadlength); + }).load(); + } else { + imagesToLoadlength--; + _injectTags($img, $imageWrapper); + } + $img.data('_b&w', true); + }); + + _initWebworker(imagesToLoadlength); + // binding the hover effect + if (hoverEffect) { + $el.on('mouseleave.' + _tmpID, _onMouseLeave); + $el.on('mouseenter.' + _tmpID, _onMouseEnter); + } + if (_supportsCanvas && !_cssfilters) { + $window.on('resize.' + _tmpID + ' orientationchange.' + _tmpID, _resizeCanvases); + } + }; + + /** + * + * Public Api + * + */ + + var destroy = function () { + $el.off('.' + _tmpID); + $window.off('.' + _tmpID); + }; + + _init(); + + return { + destroy: destroy + }; + } + }); }(jQuery)); \ No newline at end of file