From 0f73f16cfaa87f3dee4af0dac14db53e8fac39ae Mon Sep 17 00:00:00 2001 From: Olivier Guyot Date: Fri, 5 Apr 2019 10:26:23 +0200 Subject: [PATCH] View / apply constraints when an interaction starts Previously, an interaction could begin while target values (center/resolution) were out of the allowed range, causing a glitch where the view zoom/position would jump suddenly. --- src/ol/View.js | 4 +++ src/ol/control/Zoom.js | 1 + src/ol/interaction/Interaction.js | 1 + test/spec/ol/view.test.js | 46 +++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+) diff --git a/src/ol/View.js b/src/ol/View.js index 3dee0cefbd..8bcc32c21b 100644 --- a/src/ol/View.js +++ b/src/ol/View.js @@ -1325,10 +1325,14 @@ class View extends BaseObject { /** * Notify the View that an interaction has started. + * The view state will be resolved to a stable one if needed + * (depending on its constraints). * @api */ beginInteraction() { this.setHint(ViewHint.INTERACTING, 1); + + this.resolveConstraints(0); } /** diff --git a/src/ol/control/Zoom.js b/src/ol/control/Zoom.js index 379e703fc4..851c557c2e 100644 --- a/src/ol/control/Zoom.js +++ b/src/ol/control/Zoom.js @@ -114,6 +114,7 @@ class Zoom extends Control { // upon it return; } + view.resolveConstraints(0); const currentZoom = view.getZoom(); if (currentZoom !== undefined) { const newZoom = view.getConstrainedZoom(currentZoom + delta); diff --git a/src/ol/interaction/Interaction.js b/src/ol/interaction/Interaction.js index 80a9644758..13c2c3758b 100644 --- a/src/ol/interaction/Interaction.js +++ b/src/ol/interaction/Interaction.js @@ -135,6 +135,7 @@ export function zoomByDelta(view, delta, opt_anchor, opt_duration) { const newZoom = view.getConstrainedZoom(currentZoom + delta); const newResolution = view.getResolutionForZoom(newZoom); + view.resolveConstraints(0); if (view.getAnimating()) { view.cancelAnimations(); } diff --git a/test/spec/ol/view.test.js b/test/spec/ol/view.test.js index 8512e3339e..054fc0e4bc 100644 --- a/test/spec/ol/view.test.js +++ b/test/spec/ol/view.test.js @@ -1801,6 +1801,52 @@ describe('ol.View', function() { }); }); +describe('does not start unexpected animations during interaction', function() { + let map; + beforeEach(function() { + map = new Map({ + target: createMapDiv(512, 256) + }); + }); + afterEach(function() { + disposeMap(map); + }); + + it('works when initialized with #setCenter() and #setZoom()', function(done) { + const view = map.getView(); + let callCount = 0; + view.on('change:resolution', function() { + ++callCount; + }); + view.setCenter([0, 0]); + view.setZoom(0); + view.beginInteraction(); + view.endInteraction(); + setTimeout(function() { + expect(callCount).to.be(1); + done(); + }, 500); + }); + + it('works when initialized with #animate()', function(done) { + const view = map.getView(); + let callCount = 0; + view.on('change:resolution', function() { + ++callCount; + }); + view.animate({ + center: [0, 0], + zoom: 0 + }); + view.beginInteraction(); + view.endInteraction(); + setTimeout(function() { + expect(callCount).to.be(1); + done(); + }, 500); + }); +}); + describe('ol.View.isNoopAnimation()', function() { const cases = [{