Merge pull request #6968 from ahocevar/spin-animation
Shortest arc rotation animation improvements and upgrade notes
This commit is contained in:
@@ -2,6 +2,26 @@
|
||||
|
||||
### Next release
|
||||
|
||||
#### `ol.animate` now takes the shortest arc for rotation animation
|
||||
|
||||
Usually rotation animations should animate along the shortest arc. There are rare occasions where a spinning animation effect is desired. So if you previously had something like
|
||||
```js
|
||||
map.getView().animate({
|
||||
rotation: 2 * Math.PI,
|
||||
duration: 2000
|
||||
});
|
||||
```
|
||||
we recommend to split the animation into two parts and use different easing functions. The code below results in the same effect as the snippet above did with previous versions:
|
||||
```js
|
||||
map.getView().animate({
|
||||
rotation: Math.PI,
|
||||
easing: ol.easing.easeIn
|
||||
}, {
|
||||
rotation: 2 * Math.PI,
|
||||
easing: ol.easing.easeOut
|
||||
});
|
||||
```
|
||||
|
||||
### v4.2.0
|
||||
|
||||
#### Return values of two `ol.style.RegularShape` getters have changed
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
goog.require('ol.Map');
|
||||
goog.require('ol.View');
|
||||
goog.require('ol.easing');
|
||||
goog.require('ol.layer.Tile');
|
||||
goog.require('ol.proj');
|
||||
goog.require('ol.source.OSM');
|
||||
@@ -73,9 +74,16 @@ onClick('rotate-right', function() {
|
||||
});
|
||||
|
||||
onClick('rotate-around-rome', function() {
|
||||
// Rotation animation takes the shortest arc, so animate in two parts
|
||||
var rotation = view.getRotation();
|
||||
view.animate({
|
||||
rotation: view.getRotation() + 2 * Math.PI,
|
||||
anchor: rome
|
||||
rotation: rotation + Math.PI,
|
||||
anchor: rome,
|
||||
easing: ol.easing.easeIn
|
||||
}, {
|
||||
rotation: rotation + 2 * Math.PI,
|
||||
anchor: rome,
|
||||
easing: ol.easing.easeOut
|
||||
});
|
||||
});
|
||||
|
||||
@@ -103,10 +111,19 @@ onClick('bounce-to-istanbul', function() {
|
||||
});
|
||||
|
||||
onClick('spin-to-rome', function() {
|
||||
// Rotation animation takes the shortest arc, so animate in two parts
|
||||
var center = view.getCenter();
|
||||
view.animate({
|
||||
center: [
|
||||
center[0] + (rome[0] - center[0]) / 2,
|
||||
center[1] + (rome[1] - center[1]) / 2
|
||||
],
|
||||
rotation: Math.PI,
|
||||
easing: ol.easing.easeIn
|
||||
}, {
|
||||
center: rome,
|
||||
rotation: 2 * Math.PI,
|
||||
duration: 2000
|
||||
easing: ol.easing.easeOut
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -296,9 +296,7 @@ ol.View.prototype.animate = function(var_args) {
|
||||
|
||||
if (options.rotation !== undefined) {
|
||||
animation.sourceRotation = rotation;
|
||||
var delta =
|
||||
ol.math.modulo(options.rotation - rotation + Math.PI, 2 * Math.PI) -
|
||||
Math.PI;
|
||||
var delta = ol.math.modulo(options.rotation - rotation + Math.PI, 2 * Math.PI) - Math.PI;
|
||||
animation.targetRotation = rotation + delta;
|
||||
rotation = animation.targetRotation;
|
||||
}
|
||||
@@ -399,7 +397,7 @@ ol.View.prototype.updateAnimations_ = function() {
|
||||
}
|
||||
if (animation.sourceRotation !== undefined && animation.targetRotation !== undefined) {
|
||||
var rotation = progress === 1 ?
|
||||
animation.targetRotation :
|
||||
ol.math.modulo(animation.targetRotation + Math.PI, 2 * Math.PI) - Math.PI :
|
||||
animation.sourceRotation + progress * (animation.targetRotation - animation.sourceRotation);
|
||||
if (animation.anchor) {
|
||||
this.set(ol.ViewProperty.CENTER,
|
||||
|
||||
@@ -494,7 +494,7 @@ describe('ol.View', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('takes the shortest angle to the target rotation', function(done) {
|
||||
it('takes the shortest arc to the target rotation', function(done) {
|
||||
var view = new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 0,
|
||||
@@ -509,6 +509,21 @@ describe('ol.View', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it('normalizes rotation to angles between -180 and 180 degrees after the anmiation', function(done) {
|
||||
var view = new ol.View({
|
||||
center: [0, 0],
|
||||
zoom: 0,
|
||||
rotation: Math.PI / 180 * 1
|
||||
});
|
||||
view.animate({
|
||||
rotation: Math.PI / 180 * -181,
|
||||
duration: 0
|
||||
}, function() {
|
||||
expect(view.getRotation()).to.roughlyEqual(Math.PI / 180 * 179, 1e-12);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls a callback when animation completes', function(done) {
|
||||
var view = new ol.View({
|
||||
center: [0, 0],
|
||||
|
||||
Reference in New Issue
Block a user