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.
This commit is contained in:
@@ -1325,10 +1325,14 @@ class View extends BaseObject {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the View that an interaction has started.
|
* 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
|
* @api
|
||||||
*/
|
*/
|
||||||
beginInteraction() {
|
beginInteraction() {
|
||||||
this.setHint(ViewHint.INTERACTING, 1);
|
this.setHint(ViewHint.INTERACTING, 1);
|
||||||
|
|
||||||
|
this.resolveConstraints(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ class Zoom extends Control {
|
|||||||
// upon it
|
// upon it
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
view.resolveConstraints(0);
|
||||||
const currentZoom = view.getZoom();
|
const currentZoom = view.getZoom();
|
||||||
if (currentZoom !== undefined) {
|
if (currentZoom !== undefined) {
|
||||||
const newZoom = view.getConstrainedZoom(currentZoom + delta);
|
const newZoom = view.getConstrainedZoom(currentZoom + delta);
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ export function zoomByDelta(view, delta, opt_anchor, opt_duration) {
|
|||||||
const newZoom = view.getConstrainedZoom(currentZoom + delta);
|
const newZoom = view.getConstrainedZoom(currentZoom + delta);
|
||||||
const newResolution = view.getResolutionForZoom(newZoom);
|
const newResolution = view.getResolutionForZoom(newZoom);
|
||||||
|
|
||||||
|
view.resolveConstraints(0);
|
||||||
if (view.getAnimating()) {
|
if (view.getAnimating()) {
|
||||||
view.cancelAnimations();
|
view.cancelAnimations();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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() {
|
describe('ol.View.isNoopAnimation()', function() {
|
||||||
|
|
||||||
const cases = [{
|
const cases = [{
|
||||||
|
|||||||
Reference in New Issue
Block a user