diff --git a/src/ol/centerconstraint.js b/src/ol/centerconstraint.js index 3eed6c6216..1bf5480c6f 100644 --- a/src/ol/centerconstraint.js +++ b/src/ol/centerconstraint.js @@ -29,12 +29,22 @@ export function createExtent(extent, onlyCenter, smooth) { if (center) { const viewWidth = onlyCenter ? 0 : size[0] * resolution; const viewHeight = onlyCenter ? 0 : size[1] * resolution; - const minX = extent[0] + viewWidth / 2; - const maxX = extent[2] - viewWidth / 2; - const minY = extent[1] + viewHeight / 2; - const maxY = extent[3] - viewHeight / 2; - let x = minX > maxX ? (maxX + minX) / 2 : clamp(center[0], minX, maxX); - let y = minY > maxY ? (maxY + minY) / 2 : clamp(center[1], minY, maxY); + let minX = extent[0] + viewWidth / 2; + let maxX = extent[2] - viewWidth / 2; + let minY = extent[1] + viewHeight / 2; + let maxY = extent[3] - viewHeight / 2; + + // note: when zooming out of bounds, min and max values for x and y may + // end up inverted (min > max); this has to be accounted for + if (minX > maxX) { + minX = maxX = (maxX + minX) / 2; + } + if (minY > maxY) { + minY = maxY = (maxY + minY) / 2; + } + + let x = clamp(center[0], minX, maxX); + let y = clamp(center[1], minY, maxY); const ratio = 30 * resolution; // during an interaction, allow some overscroll diff --git a/src/ol/resolutionconstraint.js b/src/ol/resolutionconstraint.js index 9b053da031..2e12a1a69d 100644 --- a/src/ol/resolutionconstraint.js +++ b/src/ol/resolutionconstraint.js @@ -27,6 +27,10 @@ function getViewportClampedResolution(resolution, maxExtent, viewportSize) { /** * Returns a modified resolution to be between maxResolution and minResolution while * still allowing the value to be slightly out of bounds. + * Note: the computation is based on the logarithm function (ln): + * - at 1, ln(x) is 0 + * - above 1, ln(x) keeps increasing but at a much slower pace than x + * The final result is clamped to prevent getting too far away from bounds. * @param {number} resolution Resolution. * @param {number} maxResolution Max resolution. * @param {number} minResolution Min resolution. @@ -34,13 +38,14 @@ function getViewportClampedResolution(resolution, maxExtent, viewportSize) { */ function getSmoothClampedResolution(resolution, maxResolution, minResolution) { let result = Math.min(resolution, maxResolution); + const ratio = 50; - result *= Math.log(Math.max(1, resolution / maxResolution)) * 0.1 + 1; + result *= Math.log(1 + ratio * Math.max(0, resolution / maxResolution - 1)) / ratio + 1; if (minResolution) { result = Math.max(result, minResolution); - result /= Math.log(Math.max(1, minResolution / resolution)) * 0.1 + 1; + result /= Math.log(1 + ratio * Math.max(0, minResolution / resolution - 1)) / ratio + 1; } - return result; + return clamp(result, minResolution / 2, maxResolution * 2); } /**