Add duration and easing options to view.fit() for animations

This commit is contained in:
Thomas Chandelle
2016-11-28 11:48:21 +01:00
parent d47e5aed10
commit 5b04771d3f
3 changed files with 78 additions and 4 deletions

View File

@@ -7562,7 +7562,10 @@ olx.view;
* constrainResolution: (boolean|undefined), * constrainResolution: (boolean|undefined),
* nearest: (boolean|undefined), * nearest: (boolean|undefined),
* maxZoom: (number|undefined), * maxZoom: (number|undefined),
* minResolution: (number|undefined)}} * minResolution: (number|undefined),
* duration: (number|undefined),
* easing: (undefined|function(number):number)
* }}
*/ */
olx.view.FitOptions; olx.view.FitOptions;
@@ -7609,6 +7612,26 @@ olx.view.FitOptions.prototype.minResolution;
olx.view.FitOptions.prototype.maxZoom; olx.view.FitOptions.prototype.maxZoom;
/**
* The duration of the animation in milliseconds. By default, there is no
* animations.
* @type {number|undefined}
* @api
*/
olx.view.FitOptions.prototype.duration;
/**
* The easing function used during the animation (defaults to {@link ol.easing.inAndOut}).
* The function will be called for each frame with a number representing a
* fraction of the animation's duration. The function should return a number
* between 0 and 1 representing the progress toward the destination state.
* @type {undefined|function(number):number}
* @api
*/
olx.view.FitOptions.prototype.easing;
/* typedefs for object literals exposed by the library */ /* typedefs for object literals exposed by the library */

View File

@@ -735,7 +735,6 @@ ol.View.prototype.fit = function(geometry, size, opt_options) {
} }
resolution = constrainedResolution; resolution = constrainedResolution;
} }
this.setResolution(resolution);
// calculate center // calculate center
sinAngle = -sinAngle; // go back to original rotation sinAngle = -sinAngle; // go back to original rotation
@@ -745,8 +744,19 @@ ol.View.prototype.fit = function(geometry, size, opt_options) {
centerRotY += (padding[0] - padding[2]) / 2 * resolution; centerRotY += (padding[0] - padding[2]) / 2 * resolution;
var centerX = centerRotX * cosAngle - centerRotY * sinAngle; var centerX = centerRotX * cosAngle - centerRotY * sinAngle;
var centerY = centerRotY * cosAngle + centerRotX * sinAngle; var centerY = centerRotY * cosAngle + centerRotX * sinAngle;
var center = [centerX, centerY];
this.setCenter([centerX, centerY]); if (options.duration !== undefined) {
this.animate({
resolution: resolution,
center: center,
duration: options.duration,
easing: options.easing
});
} else {
this.setResolution(resolution);
this.setCenter(center);
}
}; };

View File

@@ -813,10 +813,30 @@ describe('ol.View', function() {
}); });
describe('fit', function() { describe('fit', function() {
var originalRequestAnimationFrame = window.requestAnimationFrame;
var originalCancelAnimationFrame = window.cancelAnimationFrame;
beforeEach(function() {
window.requestAnimationFrame = function(callback) {
return setTimeout(callback, 1);
};
window.cancelAnimationFrame = function(key) {
return clearTimeout(key);
};
});
afterEach(function() {
window.requestAnimationFrame = originalRequestAnimationFrame;
window.cancelAnimationFrame = originalCancelAnimationFrame;
});
var view; var view;
beforeEach(function() { beforeEach(function() {
view = new ol.View({ view = new ol.View({
resolutions: [200, 100, 50, 20, 10, 5, 2, 1] center: [0, 0],
resolutions: [200, 100, 50, 20, 10, 5, 2, 1],
zoom: 5
}); });
}); });
it('fits correctly to the geometry', function() { it('fits correctly to the geometry', function() {
@@ -886,6 +906,27 @@ describe('ol.View', function() {
view.fit(ol.extent.createEmpty(), [200, 200]); view.fit(ol.extent.createEmpty(), [200, 200]);
}).to.throwException(); }).to.throwException();
}); });
it('animates when duration is defined', function(done) {
view.fit(
new ol.geom.LineString([[6000, 46000], [6000, 47100], [7000, 46000]]),
[200, 200],
{
padding: [100, 0, 0, 100],
constrainResolution: false,
duration: 25
});
expect(view.getAnimating()).to.eql(true);
setTimeout(function() {
expect(view.getResolution()).to.be(11);
expect(view.getCenter()[0]).to.be(5950);
expect(view.getCenter()[1]).to.be(47100);
expect(view.getAnimating()).to.eql(false);
done();
}, 50);
});
}); });
describe('centerOn', function() { describe('centerOn', function() {