Skip to content

Commit 560b535

Browse files
author
Tom Doan
committed
Add limitBounds option
1 parent d941b8f commit 560b535

File tree

3 files changed

+49
-25
lines changed

3 files changed

+49
-25
lines changed

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ If you don't use jQuery, then you can use [TrySound's vanilla JS version](https:
1010

1111
**[See a demo inside an accordion »](https://thdoan.github.io/magnify/demo-accordion.html)**
1212

13+
**[See a demo with background image »](https://thdoan.github.io/magnify/demo-background.html)**
14+
1315
**[See a demo with CSS animation »](https://thdoan.github.io/magnify/demo-animation.html)**
1416

1517
**[See a demo with an image map »](https://thdoan.github.io/magnify/demo-map.html)**
@@ -77,25 +79,27 @@ The options below can be set in a JavaScript object when calling `.magnify()`.
7779

7880
Name | Type | Default | Description
7981
----------- | -------- | ------- | -----------
80-
`speed` | number | 100 | Fade-in/out animation speed in ms when the lens moves on/off the image.
8182
`src` | string | '' | URI of the large image that will be shown in the magnifying lens.
83+
`speed` | number | 100 | Fade-in/out animation speed in ms when the lens moves on/off the image.
8284
`timeout` | number | -1 | Wait period in ms before hiding the magnifying lens on touch devices. Set to `-1` to disable.
83-
`afterLoad` | function | | Anonymous callback function to execute after magnification is loaded.
8485
`finalWidth` | number | | Width of the main image. Set this only if the image animates into view and has a different initial width. If the image doesn't animate, then you should set the image width in CSS or via the `width` attribute.
8586
`finalHeight` | number | | Height of the main image. Set this only if the image animates into view and has a different initial height. If the image doesn't animate, then you should set the image height in CSS or via the `height` attribute.
8687
`magnifiedWidth` | number | | Width of the image displayed inside the magnifying lens. Set this only if you want to override the large image's native width.
8788
`magnifiedHeight` | number | | Height of the image displayed inside the magnifying lens. Set this only if you want to override the large image's native height.
89+
`limitBounds` | boolean | false | Set this to `true` to keep the edge of the image within the magnifying lens.
90+
`afterLoad` | function | | Anonymous callback function to execute after magnification is loaded.
8891

8992
Options can also be set directly in the `<img>` tag by adding the following data attributes, which will take precedence over the corresponding options set inside an object:
9093

91-
- `data-magnify-speed` - equivalent to `speed`
9294
- `data-magnify-src` - equivalent to `src`
95+
- `data-magnify-speed` - equivalent to `speed`
9396
- `data-magnify-timeout` - equivalent to `timeout`
94-
- `data-magnify-afterload` - equivalent to `afterLoad`, except the value must be a declared function name
9597
- `data-magnify-finalwidth` - equivalent to `finalWidth`
9698
- `data-magnify-finalheight` - equivalent to `finalHeight`
9799
- `data-magnify-magnifiedwidth` - equivalent to `magnifiedWidth`
98100
- `data-magnify-magnifiedheight` - equivalent to `magnifiedHeight`
101+
- `data-magnify-limitbounds` - equivalent to `limitBounds`
102+
- `data-magnify-afterload` - equivalent to `afterLoad`, except the value must be a declared function name
99103

100104
## Methods
101105

dist/js/jquery.magnify-mobile.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
$magnifyMobile.toggle();
6464
});
6565
$magnify.children('img').on({
66-
touchend: function() {
66+
'touchend': function() {
6767
// Only execute on tap
6868
if ($(this).data('drag')) return;
6969
var oScrollOffset = $(this).data('scrollOffset');
@@ -72,11 +72,11 @@
7272
$lensMobile.scrollLeft(oScrollOffset.x);
7373
$lensMobile.scrollTop(oScrollOffset.y);
7474
},
75-
touchmove: function() {
75+
'touchmove': function() {
7676
// Set drag state
7777
$(this).data('drag', true);
7878
},
79-
touchstart: function(e) {
79+
'touchstart': function(e) {
8080
// Render zoom image
8181
// NOTE: In iOS background-image is url(...), not url("...").
8282
$lensMobile.html('<img src="' + $(this).prev('.magnify-lens').css('background-image').replace(/url\(["']?|["']?\)/g, '') + '" alt="">');

dist/js/jquery.magnify.js

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*!
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/)
33
* Based on http://thecodeplayer.com/walkthrough/magnifying-glass-for-images-using-jquery-and-css3
44
*
55
* jQuery Magnify by T. H. Doan is licensed under the MIT License.
@@ -10,17 +10,19 @@
1010
$.fn.magnify = function(oOptions) {
1111
// Default options
1212
oOptions = $.extend({
13-
'speed': 100,
1413
'src': '',
14+
'speed': 100,
1515
'timeout': -1,
16-
'afterLoad': function(){},
1716
'finalWidth': null,
1817
'finalHeight': null,
1918
'magnifiedWidth': null,
20-
'magnifiedHeight': null
19+
'magnifiedHeight': null,
20+
'limitBounds': false,
21+
'afterLoad': function(){}
2122
}, oOptions);
2223

2324
var $that = this, // Preserve scope
25+
$html = $('html'),
2426

2527
// Initiate
2628
init = function(el) {
@@ -45,6 +47,8 @@
4547
nMagnifiedHeight,
4648
nLensWidth,
4749
nLensHeight,
50+
nBoundX = 0,
51+
nBoundY = 0,
4852
oContainerOffset, // Relative to document
4953
oImageOffset, // Relative to container
5054
// Get true offsets
@@ -63,18 +67,19 @@
6367
// Hide the lens
6468
hideLens = function() {
6569
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
6771
});
6872
};
6973

7074
// Data attributes have precedence over options object
7175
if (!isNaN(+oDataAttr['speed'])) oOptions['speed'] = +oDataAttr['speed'];
7276
if (!isNaN(+oDataAttr['timeout'])) oOptions['timeout'] = +oDataAttr['timeout'];
73-
if (typeof window[oDataAttr['afterLoad']]==='function') oOptions.afterLoad = window[oDataAttr['afterLoad']];
7477
if (!isNaN(+oDataAttr['finalWidth'])) oOptions['finalWidth'] = +oDataAttr['finalWidth'];
7578
if (!isNaN(+oDataAttr['finalHeight'])) oOptions['finalHeight'] = +oDataAttr['finalHeight'];
7679
if (!isNaN(+oDataAttr['magnifiedWidth'])) oOptions['magnifiedWidth'] = +oDataAttr['magnifiedWidth'];
7780
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']];
7883

7984
// Save any inline styles for resetting
8085
$image.data('originalStyle', $image.attr('style'));
@@ -88,7 +93,7 @@
8893
// this image object.
8994
var elZoomImage = new Image();
9095
$(elZoomImage).on({
91-
load: function() {
96+
'load': function() {
9297
// [2] Got image dimensions OK.
9398

9499
var nX, nY;
@@ -119,6 +124,11 @@
119124
nLensWidth = $lens.width();
120125
nLensHeight = $lens.height();
121126
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+
}
122132
// Enforce non-native large image size?
123133
if (nMagnifiedWidth!==elZoomImage.width || nMagnifiedHeight!==elZoomImage.height) {
124134
$lens.css('background-size', nMagnifiedWidth + 'px ' + nMagnifiedHeight + 'px');
@@ -150,9 +160,9 @@
150160
nY = (e.pageY || e.originalEvent.touches[0].pageY) - oContainerOffset['top'];
151161
// Toggle magnifying lens
152162
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) {
154164
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
156166
$lens.fadeIn(oOptions['speed']);
157167
}
158168
} else {
@@ -161,25 +171,35 @@
161171
}
162172
if ($lens.is(':visible')) {
163173
// Move the magnifying lens with the mouse
164-
var nPosX = nX - nLensWidth/2,
165-
nPosY = nY - nLensHeight/2;
174+
var sBgPos = '';
166175
if (nMagnifiedWidth && nMagnifiedHeight) {
167176
// Change the background position of .magnify-lens according to the position of
168177
// the mouse over the .magnify-image image. This allows us to get the ratio of
169178
// the pixel under the mouse pointer with respect to the image and use that to
170179
// 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';
174194
}
175195
// Now the lens moves with the mouse. The logic is to deduct half of the lens's
176196
// width and height from the mouse coordinates to place it with its center at the
177197
// mouse coordinates. If you hover on the image now, you should see the magnifying
178198
// lens in action.
179199
$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
183203
});
184204
}
185205
},
@@ -242,7 +262,7 @@
242262
}
243263

244264
},
245-
error: function() {
265+
'error': function() {
246266
// Clean up
247267
elZoomImage = null;
248268
}

0 commit comments

Comments
 (0)