1/*! 2 * jQuery Magnify Plugin v1.6.19 by T. H. Doan (http://thdoan.github.io/magnify/) 3 * Based on http://thecodeplayer.com/walkthrough/magnifying-glass-for-images-using-jquery-and-css3 4 * 5 * jQuery Magnify by T. H. Doan is licensed under the MIT License. 6 * Read a copy of the license in the LICENSE file or at 7 * http://choosealicense.com/licenses/mit 8 */ 9 10(function($) { 11 $.fn.magnify = function(oOptions) { 12 13 var $that = this, // Preserve scope 14 oSettings = $.extend({ 15 /* Default options */ 16 speed: 100, 17 timeout: -1, 18 afterLoad: function(){} 19 }, oOptions), 20 init = function(el) { 21 // Initiate 22 var $image = $(el), 23 $anchor = $image.closest('a'), 24 $container, 25 $lens, 26 oContainerOffset, 27 nContainerWidth, 28 nContainerHeight, 29 nImageWidth, 30 nImageHeight, 31 nLensWidth, 32 nLensHeight, 33 nMagnifiedWidth = 0, 34 nMagnifiedHeight = 0, 35 sImgSrc = $image.attr('data-magnify-src') || oSettings.src || $anchor.attr('href') || '', 36 hideLens = function() { 37 if ($lens.is(':visible')) $lens.fadeOut(oSettings.speed, function() { 38 $('html').removeClass('magnifying').trigger('magnifyend'); // Reset overflow-x 39 }); 40 }; 41 // Disable zooming if no valid zoom image source 42 if (!sImgSrc) return; 43 44 // Save any inline styles for resetting 45 $image.data('originalStyle', $image.attr('style')); 46 47 // Activate magnification: 48 // 1. Try to get zoom image dimensions 49 // 2. Proceed only if able to get zoom image dimensions OK 50 51 // [1] Calculate the native (magnified) image dimensions. The zoomed 52 // version is only shown after the native dimensions are available. To 53 // get the actual dimensions we have to create this image object. 54 var elImage = new Image(); 55 $(elImage).on({ 56 load: function() { 57 // [2] Got image dimensions OK 58 59 var nX, nY; 60 61 // Fix overlap bug at the edges during magnification 62 $image.css('display', 'block'); 63 // Create container div if necessary 64 if (!$image.parent('.magnify').length) { 65 $image.wrap('<div class="magnify"></div>'); 66 } 67 $container = $image.parent('.magnify'); 68 // Create the magnifying lens div if necessary 69 if ($image.prev('.magnify-lens').length) { 70 $container.children('.magnify-lens').css('background-image', 'url(\'' + sImgSrc + '\')'); 71 } else { 72 $image.before('<div class="magnify-lens loading" style="background:url(\'' + sImgSrc + '\') no-repeat 0 0"></div>'); 73 } 74 $lens = $container.children('.magnify-lens'); 75 // Remove the "Loading..." text 76 $lens.removeClass('loading'); 77 // Cache offsets and dimensions for improved performance 78 // NOTE: This code is inside the load() function, which is 79 // important. The width and height of the object would return 0 if 80 // accessed before the image is fully loaded. 81 oContainerOffset = $container.offset(); 82 nContainerWidth = $container.width(); 83 nContainerHeight = $container.height(); 84 nImageWidth = $image.innerWidth(); // Correct width with padding 85 nImageHeight = $image.innerHeight(); // Correct height with padding 86 nLensWidth = $lens.width(); 87 nLensHeight = $lens.height(); 88 nMagnifiedWidth = elImage.width; 89 nMagnifiedHeight = elImage.height; 90 // Store dimensions for mobile plugin 91 $image.data('zoomSize', { 92 width: nMagnifiedWidth, 93 height: nMagnifiedHeight 94 }); 95 // Clean up 96 elImage = null; 97 // Execute callback 98 oSettings.afterLoad(); 99 // Handle mouse movements 100 $container.off().on({ 101 'mousemove touchmove': function(e) { 102 e.preventDefault(); 103 // Reinitialize if image initially hidden 104 if (!nContainerHeight) { 105 refresh(); 106 return; 107 } 108 // x/y coordinates of the mouse pointer or touch point 109 // This is the position of .magnify relative to the document. 110 // 111 // We deduct the positions of .magnify from the mouse or touch 112 // positions relative to the document to get the mouse or touch 113 // positions relative to the container (.magnify). 114 nX = (e.pageX || e.originalEvent.touches[0].pageX) - oContainerOffset.left, 115 nY = (e.pageY || e.originalEvent.touches[0].pageY) - oContainerOffset.top; 116 // Toggle magnifying lens 117 if (!$lens.is(':animated')) { 118 if (nX<nContainerWidth && nY<nContainerHeight && nX>0 && nY>0) { 119 if ($lens.is(':hidden')) { 120 $('html').addClass('magnifying').trigger('magnifystart'); // Hide overflow-x while zooming 121 $lens.fadeIn(oSettings.speed); 122 } 123 } else { 124 hideLens(); 125 } 126 } 127 if ($lens.is(':visible')) { 128 // Move the magnifying lens with the mouse 129 var nPosX = nX - nLensWidth/2, 130 nPosY = nY - nLensHeight/2; 131 if (nMagnifiedWidth && nMagnifiedHeight) { 132 // Change the background position of .magnify-lens according 133 // to the position of the mouse over the .magnify-image image. 134 // This allows us to get the ratio of the pixel under the 135 // mouse pointer with respect to the image and use that to 136 // position the large image inside the magnifying lens. 137 var nRatioX = Math.round(nX/nImageWidth*nMagnifiedWidth - nLensWidth/2)*-1, 138 nRatioY = Math.round(nY/nImageHeight*nMagnifiedHeight - nLensHeight/2)*-1, 139 sBgPos = nRatioX + 'px ' + nRatioY + 'px'; 140 } 141 // Now the lens moves with the mouse. The logic is to deduct 142 // half of the lens's width and height from the mouse 143 // coordinates to place it with its center at the mouse 144 // coordinates. If you hover on the image now, you should see 145 // the magnifying lens in action. 146 $lens.css({ 147 top: Math.round(nPosY) + 'px', 148 left: Math.round(nPosX) + 'px', 149 backgroundPosition: sBgPos || '' 150 }); 151 } 152 }, 153 'mouseenter': function() {
vendor: 3,607 bytes, lines 154-259
154 // Need to update offsets here to support accordions 155 oContainerOffset = $container.offset(); 156 }, 157 'mouseleave': hideLens 158 }); 159 160 // Prevent magnifying lens from getting "stuck" 161 if (oSettings.timeout>=0) { 162 $container.on('touchend', function() { 163 setTimeout(hideLens, oSettings.timeout); 164 }); 165 } 166 // Ensure lens is closed when tapping outside of it 167 $('body').not($container).on('touchstart', hideLens); 168 169 // Support image map click-throughs while zooming 170 var sUsemap = $image.attr('usemap'); 171 if (sUsemap) { 172 var $map = $('map[name=' + sUsemap.slice(1) + ']'); 173 // Image map needs to be on the same DOM level as image source 174 $image.after($map); 175 $container.click(function(e) { 176 // Trigger click on image below lens at current cursor position 177 if (e.clientX || e.clientY) { 178 $lens.hide(); 179 var elPoint = document.elementFromPoint( 180 e.clientX || e.originalEvent.touches[0].clientX, 181 e.clientY || e.originalEvent.touches[0].clientY 182 ); 183 if (elPoint.nodeName==='AREA') { 184 elPoint.click(); 185 } else { 186 // Workaround for buggy implementation of elementFromPoint() 187 // See https://bugzilla.mozilla.org/show_bug.cgi?id=1227469 188 $('area', $map).each(function() { 189 var a = $(this).attr('coords').split(','); 190 if (nX>=a[0] && nX<=a[2] && nY>=a[1] && nY<=a[3]) { 191 this.click(); 192 return false; 193 } 194 }); 195 } 196 } 197 }); 198 } 199 200 if ($anchor.length) { 201 // Make parent anchor inline-block to have correct dimensions 202 $anchor.css('display', 'inline-block'); 203 // Disable parent anchor if it's sourcing the large image 204 if ($anchor.attr('href') && !($image.attr('data-magnify-src') || oSettings.src)) { 205 $anchor.click(function(e) { 206 e.preventDefault(); 207 }); 208 } 209 } 210 211 }, 212 error: function() { 213 // Clean up 214 elImage = null; 215 } 216 }); 217 218 elImage.src = sImgSrc; 219 }, 220 // Simple debounce 221 nTimer = 0, 222 refresh = function() { 223 clearTimeout(nTimer); 224 nTimer = setTimeout(function() { 225 $that.destroy(); 226 $that.magnify(oSettings); 227 }, 100); 228 }; 229 230 /* Public methods */ 231 232 // Turn off zoom and reset to original state 233 this.destroy = function() { 234 this.each(function() { 235 var $this = $(this), 236 $lens = $this.prev('div.magnify-lens'), 237 sStyle = $this.data('originalStyle'); 238 if ($this.parent('div.magnify').length && $lens.length) { 239 if (sStyle) $this.attr('style', sStyle); 240 else $this.removeAttr('style'); 241 $this.unwrap(); 242 $lens.remove(); 243 } 244 }); 245 // Unregister event handler 246 $(window).off('resize', refresh); 247 return $that; 248 } 249 250 // Handle window resizing 251 $(window).resize(refresh); 252 253 return this.each(function() { 254 // Initiate magnification powers 255 init(this); 256 }); 257 258 }; 259}(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.