|
1 | 1 | /*! |
2 | | - * jQuery Magnify Plugin v2.0.0 by T. H. Doan (http://thdoan.github.io/magnify/) |
| 2 | + * jQuery Magnify Plugin v2.1.0 by T. H. Doan (http://thdoan.github.io/magnify/) |
3 | 3 | * Based on http://thecodeplayer.com/walkthrough/magnifying-glass-for-images-using-jquery-and-css3 |
4 | 4 | * |
5 | 5 | * jQuery Magnify by T. H. Doan is licensed under the MIT License. |
|
10 | 10 | $.fn.magnify = function(oOptions) { |
11 | 11 | // Default options |
12 | 12 | oOptions = $.extend({ |
13 | | - 'speed': 100, |
14 | 13 | 'src': '', |
| 14 | + 'speed': 100, |
15 | 15 | 'timeout': -1, |
16 | | - 'afterLoad': function(){}, |
17 | 16 | 'finalWidth': null, |
18 | 17 | 'finalHeight': null, |
19 | 18 | 'magnifiedWidth': null, |
20 | | - 'magnifiedHeight': null |
| 19 | + 'magnifiedHeight': null, |
| 20 | + 'limitBounds': false, |
| 21 | + 'afterLoad': function(){} |
21 | 22 | }, oOptions); |
22 | 23 |
|
23 | 24 | var $that = this, // Preserve scope |
| 25 | + $html = $('html'), |
24 | 26 |
|
25 | 27 | // Initiate |
26 | 28 | init = function(el) { |
|
45 | 47 | nMagnifiedHeight, |
46 | 48 | nLensWidth, |
47 | 49 | nLensHeight, |
| 50 | + nBoundX = 0, |
| 51 | + nBoundY = 0, |
48 | 52 | oContainerOffset, // Relative to document |
49 | 53 | oImageOffset, // Relative to container |
50 | 54 | // Get true offsets |
|
63 | 67 | // Hide the lens |
64 | 68 | hideLens = function() { |
65 | 69 | if ($lens.is(':visible')) $lens.fadeOut(oOptions['speed'], function() { |
66 | | - $('html').removeClass('magnifying').trigger('magnifyend'); // Reset overflow-x |
| 70 | + $html.removeClass('magnifying').trigger('magnifyend'); // Reset overflow-x |
67 | 71 | }); |
68 | 72 | }; |
69 | 73 |
|
70 | 74 | // Data attributes have precedence over options object |
71 | 75 | if (!isNaN(+oDataAttr['speed'])) oOptions['speed'] = +oDataAttr['speed']; |
72 | 76 | if (!isNaN(+oDataAttr['timeout'])) oOptions['timeout'] = +oDataAttr['timeout']; |
73 | | - if (typeof window[oDataAttr['afterLoad']]==='function') oOptions.afterLoad = window[oDataAttr['afterLoad']]; |
74 | 77 | if (!isNaN(+oDataAttr['finalWidth'])) oOptions['finalWidth'] = +oDataAttr['finalWidth']; |
75 | 78 | if (!isNaN(+oDataAttr['finalHeight'])) oOptions['finalHeight'] = +oDataAttr['finalHeight']; |
76 | 79 | if (!isNaN(+oDataAttr['magnifiedWidth'])) oOptions['magnifiedWidth'] = +oDataAttr['magnifiedWidth']; |
77 | 80 | if (!isNaN(+oDataAttr['magnifiedHeight'])) oOptions['magnifiedHeight'] = +oDataAttr['magnifiedHeight']; |
| 81 | + if (oDataAttr['limitBounds']==='true') oOptions['limitBounds'] = true; |
| 82 | + if (typeof window[oDataAttr['afterLoad']]==='function') oOptions.afterLoad = window[oDataAttr['afterLoad']]; |
78 | 83 |
|
79 | 84 | // Save any inline styles for resetting |
80 | 85 | $image.data('originalStyle', $image.attr('style')); |
|
88 | 93 | // this image object. |
89 | 94 | var elZoomImage = new Image(); |
90 | 95 | $(elZoomImage).on({ |
91 | | - load: function() { |
| 96 | + 'load': function() { |
92 | 97 | // [2] Got image dimensions OK. |
93 | 98 |
|
94 | 99 | var nX, nY; |
|
119 | 124 | nLensWidth = $lens.width(); |
120 | 125 | nLensHeight = $lens.height(); |
121 | 126 | oContainerOffset = getOffset(); // Required by refresh() |
| 127 | + // Set zoom boundaries |
| 128 | + if (oOptions['limitBounds']) { |
| 129 | + nBoundX = (nLensWidth/2) / (nMagnifiedWidth/nImageWidth); |
| 130 | + nBoundY = (nLensHeight/2) / (nMagnifiedHeight/nImageHeight); |
| 131 | + } |
122 | 132 | // Enforce non-native large image size? |
123 | 133 | if (nMagnifiedWidth!==elZoomImage.width || nMagnifiedHeight!==elZoomImage.height) { |
124 | 134 | $lens.css('background-size', nMagnifiedWidth + 'px ' + nMagnifiedHeight + 'px'); |
|
150 | 160 | nY = (e.pageY || e.originalEvent.touches[0].pageY) - oContainerOffset['top']; |
151 | 161 | // Toggle magnifying lens |
152 | 162 | if (!$lens.is(':animated')) { |
153 | | - if (nX<nImageWidth && nY<nImageHeight && nX>0 && nY>0) { |
| 163 | + if (nX>nBoundX && nX<nImageWidth-nBoundX && nY>nBoundY && nY<nImageHeight-nBoundY) { |
154 | 164 | if ($lens.is(':hidden')) { |
155 | | - $('html').addClass('magnifying').trigger('magnifystart'); // Hide overflow-x while zooming |
| 165 | + $html.addClass('magnifying').trigger('magnifystart'); // Hide overflow-x while zooming |
156 | 166 | $lens.fadeIn(oOptions['speed']); |
157 | 167 | } |
158 | 168 | } else { |
|
161 | 171 | } |
162 | 172 | if ($lens.is(':visible')) { |
163 | 173 | // Move the magnifying lens with the mouse |
164 | | - var nPosX = nX - nLensWidth/2, |
165 | | - nPosY = nY - nLensHeight/2; |
| 174 | + var sBgPos = ''; |
166 | 175 | if (nMagnifiedWidth && nMagnifiedHeight) { |
167 | 176 | // Change the background position of .magnify-lens according to the position of |
168 | 177 | // the mouse over the .magnify-image image. This allows us to get the ratio of |
169 | 178 | // the pixel under the mouse pointer with respect to the image and use that to |
170 | 179 | // position the large image inside the magnifying lens. |
171 | | - var nRatioX = Math.round(nX/nImageWidth*nMagnifiedWidth - nLensWidth/2)*-1, |
172 | | - nRatioY = Math.round(nY/nImageHeight*nMagnifiedHeight - nLensHeight/2)*-1, |
173 | | - sBgPos = nRatioX + 'px ' + nRatioY + 'px'; |
| 180 | + var nRatioX = -Math.round(nX/nImageWidth*nMagnifiedWidth-nLensWidth/2), |
| 181 | + nRatioY = -Math.round(nY/nImageHeight*nMagnifiedHeight-nLensHeight/2); |
| 182 | + if (oOptions['limitBounds']) { |
| 183 | + // Enforce bounds to ensure only image is visible in lens |
| 184 | + var nBoundRight = -Math.round((nImageWidth-nBoundX)/nImageWidth*nMagnifiedWidth-nLensWidth/2), |
| 185 | + nBoundBottom = -Math.round((nImageHeight-nBoundY)/nImageHeight*nMagnifiedHeight-nLensHeight/2); |
| 186 | + // Left and right edges |
| 187 | + if (nRatioX>0) nRatioX = 0; |
| 188 | + else if (nRatioX<nBoundRight) nRatioX = nBoundRight; |
| 189 | + // Top and bottom edges |
| 190 | + if (nRatioY>0) nRatioY = 0; |
| 191 | + else if (nRatioY<nBoundBottom) nRatioY = nBoundBottom; |
| 192 | + } |
| 193 | + sBgPos = nRatioX + 'px ' + nRatioY + 'px'; |
174 | 194 | } |
175 | 195 | // Now the lens moves with the mouse. The logic is to deduct half of the lens's |
176 | 196 | // width and height from the mouse coordinates to place it with its center at the |
177 | 197 | // mouse coordinates. If you hover on the image now, you should see the magnifying |
178 | 198 | // lens in action. |
179 | 199 | $lens.css({ |
180 | | - top: Math.round(nPosY) + oImageOffset['top'] + 'px', |
181 | | - left: Math.round(nPosX) + oImageOffset['left'] + 'px', |
182 | | - backgroundPosition: sBgPos || '' |
| 200 | + 'top': Math.round(nY-nLensHeight/2) + oImageOffset['top'] + 'px', |
| 201 | + 'left': Math.round(nX-nLensWidth/2) + oImageOffset['left'] + 'px', |
| 202 | + 'background-position': sBgPos |
183 | 203 | }); |
184 | 204 | } |
185 | 205 | }, |
|
242 | 262 | } |
243 | 263 |
|
244 | 264 | }, |
245 | | - error: function() { |
| 265 | + 'error': function() { |
246 | 266 | // Clean up |
247 | 267 | elZoomImage = null; |
248 | 268 | } |
|
0 commit comments