PageSourceSearch

https://paiza.cloud/en/js/jquery.BlackAndWhite.js

js paiza.cloud collected 2026-10-02 06:48:25 UTC 12,979 bytes, 377 lines download raw bytes

1/**
2 *
3 * Version: 0.3.6
4 * Author:  Gianluca Guarini
5 * Contact: [email protected]
6 * Website: http://www.gianlucaguarini.com/
7 * Twitter: @gianlucaguarini
8 *
9 * Copyright (c) Gianluca Guarini
10 *
11 * Permission is hereby granted, free of charge, to any person
12 * obtaining a copy of this software and associated documentation
13 * files (the "Software"), to deal in the Software without
14 * restriction, including without limitation the rights to use,
15 * copy, modify, merge, publish, distribute, sublicense, and/or sell
16 * copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following
18 * conditions:
19 *
20 * The above copyright notice and this permission notice shall be
21 * included in all copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
25 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
28 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30 * OTHER DEALINGS IN THE SOFTWARE.
31 **/
32(function ($) {
33  $.fn.extend({
34    BlackAndWhite: function (customOptions) {
35      'use strict';
36      var $el = this,
37
38        /**
39         *
40         * Options
41         *
42         */
43
44        options = $.extend({
45          hoverEffect: true,
46          webworkerPath: false,
47          invertHoverEffect: false,
48          speed: 500,
49          onImageReady: null,
50          intensity: 1
51        }, customOptions),
52
53        // options shorthand
54        hoverEffect = options.hoverEffect,
55        webworkerPath = options.webworkerPath,
56        invertHoverEffect = options.invertHoverEffect,
57        intensity = (typeof options.intensity === 'number' && options.intensity < 1 && options.intensity > 0) ? options.intensity : 1,
58        fadeSpeedIn = $.isPlainObject(options.speed) ? options.speed.fadeIn : options.speed,
59        fadeSpeedOut = $.isPlainObject(options.speed) ? options.speed.fadeOut : options.speed,
60        $window = $(window),
61
62        /**
63         *
64         * Private vars
65         *
66         */
67
68        _evtNamespace = '.BlackAndWhite',
69        _isIE7 = (document.all && !window.opera && window.XMLHttpRequest) ? true : false,
70        _browserPrefixes = ' -webkit- -moz- -o- -ms- '.split(' '),
71        _cssPrefixString = {},
72
73        /**
74         *
75         * features detection
76         *
77         */
78
79        _cssPrefix = function (property) {
80          if (_cssPrefixString[property] || _cssPrefixString[property] === '') {
81            return _cssPrefixString[property] + property;
82          }
83          var e = document.createElement('div'),
84            prefixes = ['', 'Moz', 'Webkit', 'O', 'ms', 'Khtml']; // Various supports...
85          for (var i in prefixes) {
86            if (typeof e.style[prefixes[i] + property] !== 'undefined') {
87              _cssPrefixString[property] = prefixes[i];
88              return prefixes[i] + property;
89            }
90          }
91          return property.toLowerCase();
92        },
93        // https://github.com/Modernizr/Modernizr/blob/master/feature-detects/css-filters.js
94        _cssfilters = (function () {
95          var el = document.createElement('div');
96          el.style.cssText = _browserPrefixes.join('filter' + ':blur(2px); ');
97          return !!el.style.length && ((document.documentMode === undefined || document.documentMode > 9));
98        }()),
99        _supportsCanvas = !!document.createElement('canvas').getContext,
100        /* Check if Web Workers are supported */
101        _supportWebworker = (function () {
102          return (typeof (Worker) !== 'undefined') ? true : false;
103        }()),
104        _cssFilter = _cssPrefix('Filter'),
105        _imagesArray = [],
106        _webWorker = _supportWebworker && webworkerPath ? new Worker(webworkerPath + 'BnWWorker.js') : false,
107
108        /**
109         *
110         * Private methods
111         *
112         */
113
114        /**
115         * Mouse leave event callback delegated to the the images container
116         * @param  { Object } e jquery event object
117         */
118        _onMouseLeave = function (e) {
119          $(e.currentTarget)
120            .find('.BWfade')
121            .stop(true, true)
122            .animate({
123              opacity: invertHoverEffect ? 0 : 1
124            }
124, fadeSpeedOut);
125        },
126        /**
127         * mouseenter event callback delegated to the the images container ($el)
128         * @param  { Object } e jquery event object
129         */
130        _onMouseEnter = function (e) {
131          $(e.currentTarget)
132            .find('.BWfade')
133            .stop(true, true)
134            .animate({
135              opacity: invertHoverEffect ? 1 : 0
136            }, fadeSpeedOut);
137        },
138        /**
139         * Callback triggered anytime an image gets loaded and converted
140         * @param  { Object } img: DOM image object
141         */
142        _onImageReady = function (img) {
143          if (typeof options.onImageReady === 'function') {
144            options.onImageReady(img);
145          }
146        },
147        /**
148         * Initialize the webworker loop
149         * @param  { Int } imagesToLoadlength: the amount of images passed to the plugin but not loaded yet
150         */
151        _initWebworker = function (imagesToLoadlength) {
152          // start the webworker when all the images are ready
153          if (_webWorker && _supportsCanvas && !_cssfilters && !imagesToLoadlength) {
154            // web worker implementation
155            _webWorkerLoop();
156          }
157        },
158        /**
159         * Loop all the images converting them by using the a webworker script (this process is unobstrusive and it does not block the page loading)
160         */
161        _webWorkerLoop = function () {
162
163          if (!_imagesArray.length) {
164            // terminate the worker
165            // the standard way - http://www.w3.org/TR/workers/#dedicated-workers-and-the-worker-interface
166            if (_webWorker.terminate) {
167              _webWorker.terminate();
168            }
169            // IE 10 specific - http://msdn.microsoft.com/en-us/library/ie/hh673568(v=vs.85).aspx
170            if (_webWorker.close) {
171              _webWorker.close();
172            }
173            return;
174          }
175
176          // dispatch the image data to the webworker
177          _webWorker.postMessage({
178            imgData: _imagesArray[0].imageData,
179            intensity: intensity
180          });
181
182          // anytime a new image gets converted we continue the loop
183          _webWorker.onmessage = function (event) {
184            _imagesArray[0].ctx.putImageData(event.data, 0, 0);
185            _onImageReady(_imagesArray[0].img);
186            _imagesArray.splice(0, 1);
187            _webWorkerLoop();
188          };
189        },
190        /**
191         * Helper function to check whether an image has been completely loaded
192         * @param  { Object } img: DOM image object
193         */
194        _isImageLoaded = function (img) {
195          return img.complete || (typeof img.naturalWidth !== 'undefined' && img.naturalWidth);
196        },
197        /**
198         * Use the HTML5 canvas to generate a B&W image
199         * @param  { Object } img: DOM image object
200         * @param  { Object } canvas: canvas element where we are going to draw
201         * @param  { Int } width: image width
202         * @param  { Int } height: image height
203         */
204        _generateCanvasImage = function (img, canvas, width, height) {
205          var ctx = canvas.getContext('2d'),
206            currImg = img,
207            i = 0,
208            grey;
209
210          ctx.drawImage(img, 0, 0, width, height);
211
212          var imageData = ctx.getImageData(0, 0, width, height),
213            px = imageData.data,
214            length = px.length;
215
216          // web worker superfast implementation
217          if (_webWorker) {
218            _imagesArray.push({
219              imageData: imageData,
220              ctx: ctx,
221              img: img
222            });
223          } else {
224
225            // no webworker slow implementation
226            for (; i < length; i += 4) {
227              var k = px[i] * 0.3 + px[i + 1] * 0.59 + px[i + 2] * 0.11;
228              px[i] = ~~(k * intensity + px[i] * (1 - intensity));
229              px[i + 1] = ~~(k * intensity + px[i + 1] * (1 - intensity));
230              px[i + 2] = ~~(k * intensity + px[i + 2] * (1 - intensity));
231            }
232
233            ctx.putImageData(imageData, 0, 0);
234
235            _onImageReady(img);
236          }
237        },
238        /**
239         * Print the html element needed to show the B&W image
240         * @param  { Array } $img: jQuery array containing the image
241         * @param  { Array } $imageWrapper: jQuery array containing the image parent element
242         */
243        _injectTags = function ($img, $imageWrapper) {
244
245          var img = $img[0],
246            src = img.src,
247            offset = $img.position(),
248            css = {
249              top: offset.top,
250              left: offset.left,
251              position: 'absolute',
252              '-webkit-transform': 'translate3d(0,0,0)', // fix for webkit browsers
253              opacity: invertHoverEffect ? 0 : 1
254            },
255            $overlay;
256
257          img.crossOrigin = 'anonymous';
258
259          if (_supportsCanvas && !_cssfilters) {
260            // add the canvas
261            $overlay = $('<canvas width="' + img.naturalWidth + '" height="' + img.naturalHeight + '" class="BWfade"></canvas>');
262
263            css.width = $img.width();
264            css.height = $img.height();
265            _generateCanvasImage(img, $overlay.get(0), img.naturalWidth, img.naturalHeight);
266
267          } else {
268
269            // it's a modern browser but it doesn't support the css filters
270            if (_supportsCanvas) {
271              css[_cssFilter] = 'grayscale(' + intensity * 100 + '%)';
272            } else {
273              // it's an old IE
274              css.filter = 'progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)';
275            }
276            // clone the original image using the css filters
277            $overlay = $img.clone().addClass('BWFilter BWfade');
278            _onImageReady(img);
279
280          }
281
282          $overlay
283            .css(css)
284            .prependTo($imageWrapper);
285
286          // fix opacity on the old browsers
287          if (!$.support.opacity && invertHoverEffect) {
288            $overlay.animate({
289              opacity: 0
290            }, 0);
291          }
292        },
293        _resizeCanvases = function () {
294          $el.each(function (index, currImageWrapper) {
295            var img = $(currImageWrapper).find('img'),
296              currWidth = $(img).width(),
297              currHeight = $(img).height();
298
299            $(this).find('canvas').css({
300              width: currWidth,
301              height: currHeight
302            });
303
304          });
305        },
306        /**
307         * Init the plugin stuff
308         */
309        _init = function () {
310          var imagesToLoadlength = $el.find('img').filter(function () {
311            return !$(this).data('_b&w');
312          }).length;
313          // convert all the images
314          $el.each(function (index, tmpImageWrapper) {
315            var $imageWrapper = $(tmpImageWrapper),
316              $img = $imageWrapper.find('img');
317            // this image got already converted
318            if ($img.data('_b&w')) {
319              return;
320            }
321            // if this image is not loaded yet
322            if (!_isImageLoaded($img[0])) {
323              $img.on('load', function () {
324                if ($img.data('_b&w_loaded') || !$img[0].complete) {
325                  setTimeout(function () {
326                    $img.load();
327                  }, 20);
328                  return;
329                }
330                _injectTags($img, $imageWrapper);
331                $img.data('_b&w_loaded', true);
332                imagesToLoadlength--;
333                _initWebworker(imagesToLoadlength);
334              }).load();
335            } else {
336              imagesToLoadlength--;
337              _injectTags($img, $imageWrapper);
338            }
339            $img.data('_b&w', true);
340          });
341
342          _initWebworker(imagesToLoadlength);
343
344          // binding the hover effect
345          if (hoverEffect) {
346            $el
347              .unbind(_evtNamespace)
348              .on('mouseleave' + _evtNamespace, _onMouseLeave)
349              .on('mouseenter' + _evtNamespace, _onMouseEnter);
350          }
351          if (_supportsCanvas && !_cssfilters) {
352            $window
353              .unbind(_evtNamespace)
354              .on('resize' + _evtNamespace + ' orientationchange' + _evtNamespace, _resizeCanvases);
355          }
356
357        };
358
359      /**
360       *
361       * Public Api
362       *
363       */
364
365      var destroy = function () {
366        $el.off(_evtNamespace);
367        $window.off(_evtNamespace);
368      };
369
370      _init();
371
372      return {
373        destroy: destroy
374      };
375    }
376  });
377}(jQuery));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.