From 190d0af4e6a1b63776207478e5bfcd661e484ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20T=C3=B6rnqvist?= Date: Mon, 15 Sep 2014 13:47:21 +0300 Subject: [PATCH 1/2] Fix whitespace-only lines and trailing whitespaces. --- jquery.imgareaselect.dev.js | 240 ++++++++++++++++++------------------ 1 file changed, 120 insertions(+), 120 deletions(-) diff --git a/jquery.imgareaselect.dev.js b/jquery.imgareaselect.dev.js index fe499a5..57a78f0 100755 --- a/jquery.imgareaselect.dev.js +++ b/jquery.imgareaselect.dev.js @@ -16,7 +16,7 @@ /* * Math functions will be used extensively, so it's convenient to make a few * shortcuts - */ + */ var abs = Math.abs, max = Math.max, min = Math.min, @@ -24,7 +24,7 @@ var abs = Math.abs, /** * Create a new HTML div element - * + * * @return A jQuery object representing the new element */ function div() { @@ -33,22 +33,22 @@ function div() { /** * imgAreaSelect initialization - * + * * @param img * A HTML image element to attach the plugin to * @param options * An options object */ $.imgAreaSelect = function (img, options) { - var - /* jQuery object representing the image */ + var + /* jQuery object representing the image */ $img = $(img), - + /* Has the image finished loading? */ imgLoaded, - + /* Plugin elements */ - + /* Container box */ $box = div(), /* Selection area */ @@ -59,78 +59,78 @@ $.imgAreaSelect = function (img, options) { $outer = div().add(div()).add(div()).add(div()), /* Handles (empty by default, initialized in setOptions()) */ $handles = $([]), - + /* * Additional element to work around a cursor problem in Opera * (explained later) */ $areaOpera, - + /* Image position (relative to viewport) */ left, top, - + /* Image offset (as returned by .offset()) */ imgOfs = { left: 0, top: 0 }, - + /* Image dimensions (as returned by .width() and .height()) */ imgWidth, imgHeight, - + /* * jQuery object representing the parent element that the plugin * elements are appended to */ $parent, - + /* Parent element offset (as returned by .offset()) */ parOfs = { left: 0, top: 0 }, - + /* Base z-index for plugin elements */ zIndex = 0, - + /* Plugin elements position */ position = 'absolute', - - /* X/Y coordinates of the starting point for move/resize operations */ + + /* X/Y coordinates of the starting point for move/resize operations */ startX, startY, - + /* Horizontal and vertical scaling factors */ scaleX, scaleY, - + /* Current resize mode ("nw", "se", etc.) */ resize, - + /* Selection area constraints */ minWidth, minHeight, maxWidth, maxHeight, - + /* Aspect ratio to maintain (floating point number) */ aspectRatio, - + /* Are the plugin elements currently displayed? */ shown, - + /* Current selection (relative to parent element) */ x1, y1, x2, y2, - + /* Current selection (relative to scaled image) */ selection = { x1: 0, y1: 0, x2: 0, y2: 0, width: 0, height: 0 }, - + /* Document element */ docElem = document.documentElement, /* User agent */ ua = navigator.userAgent, - - /* Various helper variables used throughout the code */ + + /* Various helper variables used throughout the code */ $p, d, i, o, w, h, adjusted; /* * Translate selection coordinates (relative to scaled image) to viewport * coordinates (relative to parent element) */ - + /** * Translate selection X to viewport X - * + * * @param x * Selection X * @return Viewport X @@ -141,7 +141,7 @@ $.imgAreaSelect = function (img, options) { /** * Translate selection Y to viewport Y - * + * * @param y * Selection Y * @return Viewport Y @@ -153,10 +153,10 @@ $.imgAreaSelect = function (img, options) { /* * Translate viewport coordinates to selection coordinates */ - + /** * Translate viewport X to selection X - * + * * @param x * Viewport X * @return Selection X @@ -167,7 +167,7 @@ $.imgAreaSelect = function (img, options) { /** * Translate viewport Y to selection Y - * + * * @param y * Viewport Y * @return Selection Y @@ -175,15 +175,15 @@ $.imgAreaSelect = function (img, options) { function selY(y) { return y - imgOfs.top + parOfs.top; } - + /* * Translate event coordinates (relative to document) to viewport * coordinates */ - + /** * Get event X and translate it to viewport X - * + * * @param event * The event object * @return Viewport X @@ -194,7 +194,7 @@ $.imgAreaSelect = function (img, options) { /** * Get event Y and translate it to viewport Y - * + * * @param event * The event object * @return Viewport Y @@ -205,7 +205,7 @@ $.imgAreaSelect = function (img, options) { /** * Get the current selection - * + * * @param noScale * If set to true, scaling is not applied to the * returned selection @@ -213,7 +213,7 @@ $.imgAreaSelect = function (img, options) { */ function getSelection(noScale) { var sx = noScale || scaleX, sy = noScale || scaleY; - + return { x1: round(selection.x1 * sx), y1: round(selection.y1 * sy), x2: round(selection.x2 * sx), @@ -221,10 +221,10 @@ $.imgAreaSelect = function (img, options) { width: round(selection.x2 * sx) - round(selection.x1 * sx), height: round(selection.y2 * sy) - round(selection.y1 * sy) }; } - + /** * Set the current selection - * + * * @param x1 * X coordinate of the upper left corner of the selection area * @param y1 @@ -239,14 +239,14 @@ $.imgAreaSelect = function (img, options) { */ function setSelection(x1, y1, x2, y2, noScale) { var sx = noScale || scaleX, sy = noScale || scaleY; - + selection = { x1: round(x1 / sx || 0), y1: round(y1 / sy || 0), x2: round(x2 / sx || 0), y2: round(y2 / sy || 0) }; - + selection.width = selection.x2 - selection.x1; selection.height = selection.y2 - selection.y1; } @@ -262,17 +262,17 @@ $.imgAreaSelect = function (img, options) { */ if (!imgLoaded || !$img.width()) return; - + /* * Get image offset. The .offset() method returns float values, so they * need to be rounded. */ imgOfs = { left: round($img.offset().left), top: round($img.offset().top) }; - + /* Get image dimensions */ imgWidth = $img.innerWidth(); imgHeight = $img.innerHeight(); - + imgOfs.top += ($img.outerHeight() - imgHeight) >> 1; imgOfs.left += ($img.outerWidth() - imgWidth) >> 1; @@ -281,7 +281,7 @@ $.imgAreaSelect = function (img, options) { minHeight = round(options.minHeight / scaleY) || 0; maxWidth = round(min(options.maxWidth / scaleX || 1<<24, imgWidth)); maxHeight = round(min(options.maxHeight / scaleY || 1<<24, imgHeight)); - + /* * Workaround for jQuery 1.3.2 incorrect offset calculation, originally * observed in Safari 3. Firefox 2 is also affected. @@ -293,17 +293,17 @@ $.imgAreaSelect = function (img, options) { imgOfs.left += max(document.body.scrollLeft, docElem.scrollLeft); } - /* Determine parent element offset */ + /* Determine parent element offset */ parOfs = /absolute|relative/.test($parent.css('position')) ? { left: round($parent.offset().left) - $parent.scrollLeft(), top: round($parent.offset().top) - $parent.scrollTop() } : position == 'fixed' ? { left: $(document).scrollLeft(), top: $(document).scrollTop() } : { left: 0, top: 0 }; - + left = viewX(0); top = viewY(0); - + /* * Check if selection area is within image boundaries, adjust if * necessary @@ -314,7 +314,7 @@ $.imgAreaSelect = function (img, options) { /** * Update plugin elements - * + * * @param resetKeyPress * If set to false, this instance's keypress * event handler is not activated @@ -333,7 +333,7 @@ $.imgAreaSelect = function (img, options) { /* * Reset the position of selection area, borders, and handles (IE6/IE7 * position them incorrectly if we don't do this) - */ + */ $area.add($border).add($handles).css({ left: 0, top: 0 }); /* Set border dimensions */ @@ -350,10 +350,10 @@ $.imgAreaSelect = function (img, options) { width: imgWidth - selection.x2, height: imgHeight }); $($outer[3]).css({ left: left + selection.x1, top: top + selection.y2, width: w, height: imgHeight - selection.y2 }); - + w -= $handles.outerWidth(); h -= $handles.outerHeight(); - + /* Arrange handles */ switch ($handles.length) { case 8: @@ -391,21 +391,21 @@ $.imgAreaSelect = function (img, options) { * broken). This workaround is not perfect, as it requires setTimeout() * and thus causes the border to flicker a bit, but I haven't found a * better solution. - * + * * Note: This only happens with CSS borders, set with the borderWidth, * borderOpacity, borderColor1, and borderColor2 options (which are now * deprecated). Borders created with GIF background images are fine. - */ + */ if (msie && $border.outerWidth() - $border.innerWidth() == 2) { $border.css('margin', 0); setTimeout(function () { $border.css('margin', 'auto'); }, 0); } } - + /** * Do the complete update sequence: recalculate offsets, update the * elements, and set the correct values of x1, y1, x2, and y2. - * + * * @param resetKeyPress * If set to false, this instance's keypress * event handler is not activated @@ -416,29 +416,29 @@ $.imgAreaSelect = function (img, options) { x1 = viewX(selection.x1); y1 = viewY(selection.y1); x2 = viewX(selection.x2); y2 = viewY(selection.y2); } - + /** * Hide or fade out an element (or multiple elements) - * + * * @param $elem * A jQuery object containing the element(s) to hide/fade out * @param fn * Callback function to be called when fadeOut() completes */ function hide($elem, fn) { - options.fadeSpeed ? $elem.fadeOut(options.fadeSpeed, fn) : $elem.hide(); + options.fadeSpeed ? $elem.fadeOut(options.fadeSpeed, fn) : $elem.hide(); } /** * Selection area mousemove event handler - * + * * @param event * The event object */ function areaMouseMove(event) { var x = selX(evX(event)) - selection.x1, y = selY(evY(event)) - selection.y1; - + if (!adjusted) { adjust(); adjusted = true; @@ -472,7 +472,7 @@ $.imgAreaSelect = function (img, options) { /** * Document mouseup event handler - * + * * @param event * The event object */ @@ -488,13 +488,13 @@ $.imgAreaSelect = function (img, options) { $(document).unbind('mousemove', selectingMouseMove); $box.mousemove(areaMouseMove); - + options.onSelectEnd(img, getSelection()); } /** * Selection area mousedown event handler - * + * * @param event * The event object * @return false @@ -510,7 +510,7 @@ $.imgAreaSelect = function (img, options) { x1 = viewX(selection[/w/.test(resize) ? 'x2' : 'x1']); y1 = viewY(selection[/n/.test(resize) ? 'y2' : 'y1']); - + $(document).mousemove(selectingMouseMove) .one('mouseup', docMouseUp); $box.unbind('mousemove', areaMouseMove); @@ -537,7 +537,7 @@ $.imgAreaSelect = function (img, options) { /** * Adjust the x2/y2 coordinates to maintain aspect ratio (if defined) - * + * * @param xFirst * If set to true, calculate x2 first. Otherwise, * calculate y2 first. @@ -546,7 +546,7 @@ $.imgAreaSelect = function (img, options) { if (aspectRatio) if (xFirst) { x2 = max(left, min(left + imgWidth, - x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1))); + x1 + abs(y2 - y1) * aspectRatio * (x2 > x1 || -1))); y2 = round(max(top, min(top + imgHeight, y1 + abs(x2 - x1) / aspectRatio * (y2 > y1 || -1)))); x2 = round(x2); @@ -572,7 +572,7 @@ $.imgAreaSelect = function (img, options) { */ x1 = min(x1, left + imgWidth); y1 = min(y1, top + imgHeight); - + if (abs(x2 - x1) < minWidth) { /* Selection width is smaller than minWidth */ x2 = x1 - minWidth * (x2 < x1 || -1); @@ -595,7 +595,7 @@ $.imgAreaSelect = function (img, options) { x2 = max(left, min(x2, left + imgWidth)); y2 = max(top, min(y2, top + imgHeight)); - + fixAspectRatio(abs(x2 - x1) < abs(y2 - y1) * aspectRatio); if (abs(x2 - x1) > maxWidth) { @@ -621,7 +621,7 @@ $.imgAreaSelect = function (img, options) { /** * Mousemove event handler triggered when the user is selecting an area - * + * * @param event * The event object * @return false @@ -632,12 +632,12 @@ $.imgAreaSelect = function (img, options) { doResize(); - return false; + return false; } /** * Move the selection area - * + * * @param newX1 * New viewport X1 * @param newY1 @@ -657,7 +657,7 @@ $.imgAreaSelect = function (img, options) { /** * Mousemove event handler triggered when the selection area is being moved - * + * * @param event * The event object * @return false @@ -668,7 +668,7 @@ $.imgAreaSelect = function (img, options) { doMove(x1, y1); - event.preventDefault(); + event.preventDefault(); return false; } @@ -680,7 +680,7 @@ $.imgAreaSelect = function (img, options) { adjust(); x2 = x1; - y2 = y1; + y2 = y1; doResize(); resize = ''; @@ -705,9 +705,9 @@ $.imgAreaSelect = function (img, options) { $(document).unbind('mousemove', startSelection) .unbind('mouseup', cancelSelection); hide($box.add($outer)); - + setSelection(selX(x1), selY(y1), selX(x1), selY(y1)); - + /* If this is an API call, callback functions should not be triggered */ if (!(this instanceof $.imgAreaSelect)) { options.onSelectChange(img, getSelection()); @@ -717,7 +717,7 @@ $.imgAreaSelect = function (img, options) { /** * Image mousedown event handler - * + * * @param event * The event object * @return false @@ -735,7 +735,7 @@ $.imgAreaSelect = function (img, options) { return false; } - + /** * Window resize event handler */ @@ -764,7 +764,7 @@ $.imgAreaSelect = function (img, options) { }, options)); $box.add($outer).css({ visibility: '' }); - + if (options.show) { shown = true; adjust(); @@ -782,14 +782,14 @@ $.imgAreaSelect = function (img, options) { /** * Document keypress event handler - * + * * @param event * The event object * @return false */ var docKeyPress = function(event) { var k = options.keys, d, t, key = event.keyCode; - + d = !isNaN(k.alt) && (event.altKey || event.originalEvent.altKey) ? k.alt : !isNaN(k.ctrl) && event.ctrlKey ? k.ctrl : !isNaN(k.shift) && event.shiftKey ? k.shift : @@ -800,7 +800,7 @@ $.imgAreaSelect = function (img, options) { (k.alt == 'resize' && (event.altKey || event.originalEvent.altKey))) { /* Resize selection */ - + switch (key) { case 37: /* Left */ @@ -830,7 +830,7 @@ $.imgAreaSelect = function (img, options) { } else { /* Move selection */ - + x1 = min(x1, x2); y1 = min(y1, y2); @@ -861,7 +861,7 @@ $.imgAreaSelect = function (img, options) { /** * Apply style options to plugin element (or multiple elements) - * + * * @param $elem * A jQuery object representing the element(s) to style * @param props @@ -876,14 +876,14 @@ $.imgAreaSelect = function (img, options) { /** * Set plugin options - * + * * @param newOptions * The new options object */ function setOptions(newOptions) { if (newOptions.parent) ($parent = $(newOptions.parent)).append($box).append($outer); - + /* Merge the new options with the existing ones */ $.extend(options, newOptions); @@ -898,7 +898,7 @@ $.imgAreaSelect = function (img, options) { while (i--) $handles = $handles.add(div()); - + /* Add a class to handles and set the CSS properties */ $handles.addClass(options.classPrefix + '-handle').css({ position: 'absolute', @@ -909,14 +909,14 @@ $.imgAreaSelect = function (img, options) { fontSize: 0, zIndex: zIndex + 1 || 1 }); - + /* * If handle width/height has not been set with CSS rules, set the * default 5px */ if (!parseInt($handles.css('width')) >= 0) $handles.width(5).height(5); - + /* * If the borderWidth option is in use, add a solid border to * handles @@ -973,7 +973,7 @@ $.imgAreaSelect = function (img, options) { if (o = ($border.css('filter')||'').match(/opacity=(\d+)/)) $border.css('opacity', o[1]/100); } - + if (newOptions.hide) hide($box.add($outer)); else if (newOptions.show && imgLoaded) { @@ -986,7 +986,7 @@ $.imgAreaSelect = function (img, options) { aspectRatio = (d = (options.aspectRatio || '').split(/:/))[0] / d[1]; $img.add($outer).unbind('mousedown', imgMouseDown); - + if (options.disable || options.enable === false) { /* Disable the plugin */ $box.unbind('mousemove', areaMouseMove).unbind('mousedown', areaMouseDown); @@ -997,17 +997,17 @@ $.imgAreaSelect = function (img, options) { /* Enable the plugin */ if (options.resizable || options.movable) $box.mousemove(areaMouseMove).mousedown(areaMouseDown); - + $(window).resize(windowResize); } if (!options.persistent) $img.add($outer).mousedown(imgMouseDown); } - + options.enable = options.disable = undefined; } - + /** * Remove plugin completely */ @@ -1018,39 +1018,39 @@ $.imgAreaSelect = function (img, options) { setOptions({ disable: true }); $box.add($outer).remove(); }; - + /* * Public API */ - + /** * Get current options - * + * * @return An object containing the set of options currently in use */ this.getOptions = function () { return options; }; - + /** * Set plugin options - * + * * @param newOptions * The new options object */ this.setOptions = setOptions; - + /** * Get the current selection - * + * * @param noScale * If set to true, scaling is not applied to the * returned selection * @return Selection object */ this.getSelection = getSelection; - + /** * Set the current selection - * + * * @param x1 * X coordinate of the upper left corner of the selection area * @param y1 @@ -1064,15 +1064,15 @@ $.imgAreaSelect = function (img, options) { * new selection */ this.setSelection = setSelection; - + /** * Cancel selection */ this.cancelSelection = cancelSelection; - + /** * Update plugin elements - * + * * @param resetKeyPress * If set to false, this instance's keypress * event handler is not activated @@ -1084,7 +1084,7 @@ $.imgAreaSelect = function (img, options) { opera = /opera/i.test(ua), safari = /webkit/i.test(ua) && !/chrome/i.test(ua); - /* + /* * Traverse the image's parent elements (up to ) and find the * highest z-index */ @@ -1093,13 +1093,13 @@ $.imgAreaSelect = function (img, options) { while ($p.length) { zIndex = max(zIndex, !isNaN($p.css('z-index')) ? $p.css('z-index') : zIndex); - /* Also check if any of the ancestor elements has fixed position */ + /* Also check if any of the ancestor elements has fixed position */ if ($p.css('position') == 'fixed') position = 'fixed'; $p = $p.parent(':not(body)'); } - + /* * If z-index is given as an option, it overrides the one found by the * above loop @@ -1121,7 +1121,7 @@ $.imgAreaSelect = function (img, options) { * event, we're adding an additional div to $box and we're going to toggle * it when mouse moves inside the selection area. */ - if (opera) + if (opera) $areaOpera = div().css({ width: '100%', height: '100%', position: 'absolute', zIndex: zIndex + 2 || 2 }); @@ -1136,7 +1136,7 @@ $.imgAreaSelect = function (img, options) { overflow: 'hidden', zIndex: zIndex || '0' }); $box.css({ zIndex: zIndex + 2 || 2 }); $area.add($border).css({ position: 'absolute', fontSize: 0 }); - + /* * If the image has been fully loaded, or if it is not really an image (eg. * a div), call imgLoad() immediately; otherwise, bind it to be called once @@ -1145,7 +1145,7 @@ $.imgAreaSelect = function (img, options) { img.complete || img.readyState == 'complete' || !$img.is('img') ? imgLoad() : $img.one('load', imgLoad); - /* + /* * MSIE 9.0 doesn't always fire the image load event -- resetting the src * attribute seems to trigger it. The check is for version 7 and above to * accommodate for MSIE 9 running in compatibility mode. @@ -1156,7 +1156,7 @@ $.imgAreaSelect = function (img, options) { /** * Invoke imgAreaSelect on a jQuery object containing the image(s) - * + * * @param options * Options object * @return The jQuery object or a reference to imgAreaSelect instance (if the @@ -1180,18 +1180,18 @@ $.fn.imgAreaSelect = function (options) { } else if (!options.remove) { /* No exising instance -- create a new one */ - + /* * If neither the "enable" nor the "disable" option is present, add * "enable" as the default - */ + */ if (options.enable === undefined && options.disable === undefined) options.enable = true; $(this).data('imgAreaSelect', new $.imgAreaSelect(this, options)); } }); - + if (options.instance) /* * Return the imgAreaSelect instance bound to the first element in the From f08efcc6090f288b411b16b9863a90cca9fb2a72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20T=C3=B6rnqvist?= Date: Mon, 15 Sep 2014 16:03:32 +0300 Subject: [PATCH 2/2] Snap to grid --- jquery.imgareaselect.dev.js | 75 ++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/jquery.imgareaselect.dev.js b/jquery.imgareaselect.dev.js index 57a78f0..592b397 100755 --- a/jquery.imgareaselect.dev.js +++ b/jquery.imgareaselect.dev.js @@ -105,6 +105,12 @@ $.imgAreaSelect = function (img, options) { /* Aspect ratio to maintain (floating point number) */ aspectRatio, + /* Snap to grid X, pixels */ + snapX, + + /* Snap to grid Y, pixels */ + snapY, + /* Are the plugin elements currently displayed? */ shown, @@ -203,6 +209,40 @@ $.imgAreaSelect = function (img, options) { return event.pageY - parOfs.top; } + /** + * Snap coordinate to wherever it needs to be + * + * @param coord + * Coordinate to snap + * @return Coordinate + */ + function snapSingle(coord, isX) { + if (isX && snapX) + return snapX * round(coord/snapX); + else if (snapY) + return snapY * round(coord/snapY); + return coord; + } + + /** + * Makes sure a selection is snapped properly + * + * @param selection + * Selection to fix + * @return Selection + */ + function snap(selection) { + if (snapX) { + selection.x1 = snapSingle(selection.x1, true); + selection.x2 = snapSingle(selection.x2, true); + } + if (snapY) { + selection.y1 = snapSingle(selection.y1, false); + selection.y2 = snapSingle(selection.y2, false); + } + return selection; + } + /** * Get the current selection * @@ -214,12 +254,16 @@ $.imgAreaSelect = function (img, options) { function getSelection(noScale) { var sx = noScale || scaleX, sy = noScale || scaleY; - return { x1: round(selection.x1 * sx), + var _selection = { x1: round(selection.x1 * sx), y1: round(selection.y1 * sy), x2: round(selection.x2 * sx), y2: round(selection.y2 * sy), width: round(selection.x2 * sx) - round(selection.x1 * sx), height: round(selection.y2 * sy) - round(selection.y1 * sy) }; + + _selection = snap(_selection); + // console.log('getSelection', _selection); + return _selection; } /** @@ -246,6 +290,8 @@ $.imgAreaSelect = function (img, options) { x2: round(x2 / sx || 0), y2: round(y2 / sy || 0) }; + if (snapX || snapY) + selection = snap(selection); selection.width = selection.x2 - selection.x1; selection.height = selection.y2 - selection.y1; @@ -511,6 +557,11 @@ $.imgAreaSelect = function (img, options) { x1 = viewX(selection[/w/.test(resize) ? 'x2' : 'x1']); y1 = viewY(selection[/n/.test(resize) ? 'y2' : 'y1']); + if (snapX || snapY) { + x1 = snapSingle(x1, true); + y1 = snapSingle(y1, false); + } + $(document).mousemove(selectingMouseMove) .one('mouseup', docMouseUp); $box.unbind('mousemove', areaMouseMove); @@ -572,6 +623,10 @@ $.imgAreaSelect = function (img, options) { */ x1 = min(x1, left + imgWidth); y1 = min(y1, top + imgHeight); + if (snapX || snapY) { + x1 = snapSingle(x1, true); + y1 = snapSingle(y1, false); + } if (abs(x2 - x1) < minWidth) { /* Selection width is smaller than minWidth */ @@ -595,6 +650,10 @@ $.imgAreaSelect = function (img, options) { x2 = max(left, min(x2, left + imgWidth)); y2 = max(top, min(y2, top + imgHeight)); + if (snapX || snapY) { + x2 = snapSingle(x2, true); + y2 = snapSingle(y2, false); + } fixAspectRatio(abs(x2 - x1) < abs(y2 - y1) * aspectRatio); @@ -613,6 +672,8 @@ $.imgAreaSelect = function (img, options) { selection = { x1: selX(min(x1, x2)), x2: selX(max(x1, x2)), y1: selY(min(y1, y2)), y2: selY(max(y1, y2)), width: abs(x2 - x1), height: abs(y2 - y1) }; + if (snapX || snapY) + selection = snap(selection); update(); @@ -649,6 +710,8 @@ $.imgAreaSelect = function (img, options) { $.extend(selection, { x1: selX(x1), y1: selY(y1), x2: selX(x2), y2: selY(y2) }); + if (snapX || snapY) + selection = snap(selection); update(); @@ -666,6 +729,11 @@ $.imgAreaSelect = function (img, options) { x1 = max(left, min(startX + evX(event), left + imgWidth - selection.width)); y1 = max(top, min(startY + evY(event), top + imgHeight - selection.height)); + if (snapX || snapY) { + x1 = snapSingle(x1, true); + y1 = snapSingle(y1, false); + } + doMove(x1, y1); event.preventDefault(); @@ -681,6 +749,7 @@ $.imgAreaSelect = function (img, options) { x2 = x1; y2 = y1; + doResize(); resize = ''; @@ -985,6 +1054,10 @@ $.imgAreaSelect = function (img, options) { /* Calculate the aspect ratio factor */ aspectRatio = (d = (options.aspectRatio || '').split(/:/))[0] / d[1]; + /* Snap to grid? */ + snapX = (newOptions.snapX || options.snapX || null); + snapY = (newOptions.snapY || options.snapY || null); + $img.add($outer).unbind('mousedown', imgMouseDown); if (options.disable || options.enable === false) {