From ed73fa078ee5dbbc4b30350da897be5f04674b88 Mon Sep 17 00:00:00 2001 From: techfg Date: Sat, 21 Dec 2024 19:38:59 -0800 Subject: [PATCH] feat: add scaleMapBounds config option --- examples/index.html | 1 + examples/scalebounds.html | 217 ++++++++++++++++++ .../docs/reference/configuration-reference.md | 26 ++- src/core.js | 1 + src/mapdata.js | 3 +- src/scale.js | 15 +- tests/resize.tests.js | 95 ++++++++ 7 files changed, 351 insertions(+), 7 deletions(-) create mode 100644 examples/scalebounds.html diff --git a/examples/index.html b/examples/index.html index 1a58acb..7522c17 100644 --- a/examples/index.html +++ b/examples/index.html @@ -22,6 +22,7 @@

ImageMapster Examples

  • Navigate - Full
  • Automatic Resize
  • Manual Resize
  • +
  • Scaling Boundary
  • Shape Attribute Values
  • Nohref & Href Attribute Values
  • StaticState Values
  • diff --git a/examples/scalebounds.html b/examples/scalebounds.html new file mode 100644 index 0000000..f39e19a --- /dev/null +++ b/examples/scalebounds.html @@ -0,0 +1,217 @@ + + + + + Scaling Boundary Demo + + + + + + + + + + + + + + +

    Scaling Boundary Demo

    + +
    +

    + When pressing the buttons, the image is resized by the corresponding + percentage of the images natural size, but the map area is only scaled + if the percentage of natural size is less than or equal to 99% or + greater than or equal to 101%. +

    +

    + Note - Floating point calculations are not precise which could result in + otherwise unexpected fractional differences in precision when adjusting + image size. +

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + +
    Shrink + + + + + + + + + + + +
    Grow + + + + + + + + + + + +
    +
    +
    + +
    + Percentage Difference: TBD%
    + Percentage of Natural Size: TBD% +
    +
    + Actual Size: TBD
    + Natural Size: TBD +
    +
    +
    + +
    + 1024 x 768 +
    + + + +
    + + diff --git a/site/src/content/docs/reference/configuration-reference.md b/site/src/content/docs/reference/configuration-reference.md index caa1e06..16322cf 100644 --- a/site/src/content/docs/reference/configuration-reference.md +++ b/site/src/content/docs/reference/configuration-reference.md @@ -1077,7 +1077,8 @@ $('#myimage').mapster({ ### scaleMap **Type:** `boolean`
    -**Default:** `true` +**Default:** `true`
    +**See Also:** [`scaleMapBounds`](#scalemapbounds) Automatically scale image maps to the current display size of the image. @@ -1093,6 +1094,29 @@ $('#myimage').mapster({ }); ``` +### scaleMapBounds + +**Type:** `false | { below: number, above: number }`
    +**Default:** `{ below: 0.98, above: 1.02 }`
    +**See Also:** [`scaleMap`](#scalemap) + +The boundary to restrict scaling when [scaleMap](#scalemap) is enabled. + +When an image map is resized, it's map area coordinates are scaled to correspond with the displayed image size. + +When the percentage of the displayed image size relative to the natural image size is between `below` and `after` (not inclusive), the map area coordinates will be scaled based on 100% of the natural image size. When the percentage is outside of this boundary (inclusive), map area coordinates will be scaled based on the displayed image size. + +By default, scaling will occur when the displayed image size is 98% (or less) or 102% (or more) of its natural image size. + +Setting this value to `false` will scale the map areas based on displayed image size without any restrictions. + +```js +$('#myimage').mapster({ + // scale down to any size but restrict scaling up to 105% or greater + scaleMapBounds: { below: 1, above: 1.05 } +}); +``` + ## Bound List Options ImageMapster supports assocating an image map to an external list in order to simplyfing synchronization of the map and the list. This allows for things such as selecting an item in a list and having the corresponding area in the image map become selected. You can provide a static collection of list items via the [boundList](#boundlist) option or generate the list items dynamically using the data provided in the [onGetList](#ongetlist) callback which supplies the list of all `area` elements ImageMapster found for the image map. diff --git a/src/core.js b/src/core.js index 9454719..5c426ce 100644 --- a/src/core.js +++ b/src/core.js @@ -66,6 +66,7 @@ configTimeout: 30000, noHrefIsMask: true, scaleMap: true, + scaleMapBounds: { below: 0.98, above: 1.02 }, enableAutoResizeSupport: false, // TODO: Remove in next major release autoResize: false, autoResizeDelay: 0, diff --git a/src/mapdata.js b/src/mapdata.js index 021faff..1613a34 100644 --- a/src/mapdata.js +++ b/src/mapdata.js @@ -777,7 +777,8 @@ me.scaleInfo = scale = u.scaleMap( me.images[0], me.images[1], - opts.scaleMap + opts.scaleMap, + opts.scaleMapBounds ); me.base_canvas = base_canvas = me.graphics.createVisibleCanvas(me); diff --git a/src/scale.js b/src/scale.js index 203ab81..de30d1e 100644 --- a/src/scale.js +++ b/src/scale.js @@ -11,7 +11,7 @@ u = m.utils, p = m.MapArea.prototype; - m.utils.getScaleInfo = function (eff, actual) { + m.utils.getScaleInfo = function (eff, actual, scaleMapBounds) { var pct; if (!actual) { pct = 1; @@ -19,7 +19,11 @@ } else { pct = eff.width / actual.width || eff.height / actual.height; // make sure a float error doesn't muck us up - if (pct > 0.98 && pct < 1.02) { + if ( + scaleMapBounds && + pct > scaleMapBounds.below && + pct < scaleMapBounds.above + ) { pct = 1; } } @@ -34,7 +38,7 @@ }; }; // Scale a set of AREAs, return old data as an array of objects - m.utils.scaleMap = function (image, imageRaw, scale) { + m.utils.scaleMap = function (image, imageRaw, scale, scaleMapBounds) { // stunningly, jQuery width can return zero even as width does not, seems to happen only // with adBlock or maybe other plugins. These must interfere with onload events somehow. @@ -47,7 +51,7 @@ if (!vis.complete()) { vis = raw; } - return this.getScaleInfo(vis, scale ? raw : null); + return this.getScaleInfo(vis, scale ? raw : null, scaleMapBounds); }; /** @@ -123,7 +127,8 @@ { width: me.scaleInfo.realWidth, height: me.scaleInfo.realHeight - } + }, + me.options.scaleMapBounds ); $.each(me.data, function (_, e) { $.each(e.areas(), function (_, e) { diff --git a/tests/resize.tests.js b/tests/resize.tests.js index 76e50a9..5fc3748 100644 --- a/tests/resize.tests.js +++ b/tests/resize.tests.js @@ -88,6 +88,101 @@ this.tests.push( }) ); +this.tests.push( + iqtest + .create('getScaleInfo', 'getScaleInfo scaleMapBounds') + .add('respects scale boundaries', function (a) { + 'use strict'; + + var result, + mu = $.mapster.utils, + bounds = { below: 0.95, above: 1.05 }, + actual = { width: 100, height: 100 }; + + // scale up + result = mu.getScaleInfo( + { width: 104.998, height: 104.998 }, + actual, + bounds + ); + a.equals( + { scale: result.scale, scalePct: result.scalePct }, + { scale: false, scalePct: 1 }, + 'should not have scaled up when less than above bound' + ); + + result = mu.getScaleInfo({ width: 105, height: 105 }, actual, bounds); + a.equals( + { scale: result.scale, scalePct: result.scalePct }, + { scale: true, scalePct: 105 / 100 }, + 'should have scaled up when equal to above bound' + ); + + result = mu.getScaleInfo( + { width: 105.00000000001, height: 105.00000000001 }, + actual, + 0.04999 + ); + a.equals( + { scale: result.scale, scalePct: result.scalePct }, + { scale: true, scalePct: 105.00000000001 / 100 }, + 'should have scaled up when greater than above bound' + ); + + result = mu.getScaleInfo( + { width: 104.998, height: 104.998 }, + actual, + undefined + ); + a.equals( + { scale: result.scale, scalePct: result.scalePct }, + { scale: true, scalePct: 104.998 / 100 }, + 'should have scaled up when no boundary' + ); + + // scale down + result = mu.getScaleInfo( + { width: 95.0000001, height: 95.0000001 }, + actual, + bounds + ); + a.equals( + { scale: result.scale, scalePct: result.scalePct }, + { scale: false, scalePct: 1 }, + 'should not have scaled down when greater than below bound' + ); + + result = mu.getScaleInfo({ width: 95, height: 95 }, actual, bounds); + a.equals( + { scale: result.scale, scalePct: result.scalePct }, + { scale: true, scalePct: 95 / 100 }, + 'should have scaled down when equal to below bound' + ); + + result = mu.getScaleInfo( + { width: 94.999999, height: 94.999999 }, + actual, + bounds + ); + a.equals( + { scale: result.scale, scalePct: result.scalePct }, + { scale: true, scalePct: 94.999999 / 100 }, + 'should have scaled down when less than below bound' + ); + + result = mu.getScaleInfo( + { width: 95.0000001, height: 95.0000001 }, + actual, + undefined + ); + a.equals( + { scale: result.scale, scalePct: result.scalePct }, + { scale: true, scalePct: 95.0000001 / 100 }, + 'should have scaled down when no boundary' + ); + }) +); + this.tests.push( iqtest .create('autoresize', 'autoresize feature')