Immediately complete no-op animations

This commit is contained in:
Tim Schaub
2017-08-14 08:47:29 -04:00
parent 1249b46e5d
commit 48178f0e31
2 changed files with 134 additions and 3 deletions

View File

@@ -302,7 +302,14 @@ ol.View.prototype.animate = function(var_args) {
} }
animation.callback = callback; animation.callback = callback;
start += animation.duration;
// check if animation is a no-op
if (ol.View.isNoopAnimation(animation)) {
animation.complete = true;
// we still push it onto the series for callback handling
} else {
start += animation.duration;
}
series.push(animation); series.push(animation);
} }
this.animations_.push(series); this.animations_.push(series);
@@ -1158,3 +1165,27 @@ ol.View.createRotationConstraint_ = function(options) {
return ol.RotationConstraint.disable; return ol.RotationConstraint.disable;
} }
}; };
/**
* Determine if an animation involves no view change.
* @param {ol.ViewAnimation} animation The animation.
* @return {boolean} The animation involves no view change.
*/
ol.View.isNoopAnimation = function(animation) {
if (animation.sourceCenter) {
if (animation.sourceCenter[0] !== animation.targetCenter[0]) {
return false;
}
if (animation.sourceCenter[1] !== animation.targetCenter[1]) {
return false;
}
}
if (animation.sourceResolution !== animation.targetResolution) {
return false;
}
if (animation.sourceRotation !== animation.targetRotation) {
return false;
}
return true;
};

View File

@@ -457,6 +457,20 @@ describe('ol.View', function() {
}, 10); }, 10);
}); });
it('immediately completes for no-op animations', function() {
var view = new ol.View({
center: [0, 0],
zoom: 5
});
view.animate({
zoom: 5,
center: [0, 0],
duration: 25
});
expect(view.getAnimating()).to.eql(false);
});
it('prefers zoom over resolution', function(done) { it('prefers zoom over resolution', function(done) {
var view = new ol.View({ var view = new ol.View({
center: [0, 0], center: [0, 0],
@@ -556,6 +570,21 @@ describe('ol.View', function() {
view.setCenter([1, 2]); // interrupt the animation view.setCenter([1, 2]); // interrupt the animation
}); });
it('calls a callback even if animation is a no-op', function(done) {
var view = new ol.View({
center: [0, 0],
zoom: 0
});
view.animate({
zoom: 0,
duration: 25
}, function(complete) {
expect(complete).to.be(true);
done();
});
});
it('can run multiple animations in series', function(done) { it('can run multiple animations in series', function(done) {
var view = new ol.View({ var view = new ol.View({
center: [0, 0], center: [0, 0],
@@ -613,7 +642,7 @@ describe('ol.View', function() {
expect(view.getHints()[ol.ViewHint.ANIMATING]).to.be(2); expect(view.getHints()[ol.ViewHint.ANIMATING]).to.be(2);
view.animate({ view.animate({
rotate: Math.PI, rotation: Math.PI,
duration: 25 duration: 25
}, decrement); }, decrement);
expect(view.getHints()[ol.ViewHint.ANIMATING]).to.be(3); expect(view.getHints()[ol.ViewHint.ANIMATING]).to.be(3);
@@ -640,7 +669,7 @@ describe('ol.View', function() {
expect(view.getHints()[ol.ViewHint.ANIMATING]).to.be(2); expect(view.getHints()[ol.ViewHint.ANIMATING]).to.be(2);
view.animate({ view.animate({
rotate: Math.PI, rotation: Math.PI,
duration: 25 duration: 25
}); });
expect(view.getHints()[ol.ViewHint.ANIMATING]).to.be(3); expect(view.getHints()[ol.ViewHint.ANIMATING]).to.be(3);
@@ -1282,3 +1311,74 @@ describe('ol.View', function() {
}); });
}); });
}); });
describe('ol.View.isNoopAnimation()', function() {
var cases = [{
animation: {
sourceCenter: [0, 0], targetCenter: [0, 0],
sourceResolution: 1, targetResolution: 1,
sourceRotation: 0, targetRotation: 0
},
noop: true
}, {
animation: {
sourceCenter: [0, 0], targetCenter: [0, 1],
sourceResolution: 1, targetResolution: 1,
sourceRotation: 0, targetRotation: 0
},
noop: false
}, {
animation: {
sourceCenter: [0, 0], targetCenter: [0, 0],
sourceResolution: 1, targetResolution: 0,
sourceRotation: 0, targetRotation: 0
},
noop: false
}, {
animation: {
sourceCenter: [0, 0], targetCenter: [0, 0],
sourceResolution: 1, targetResolution: 1,
sourceRotation: 0, targetRotation: 1
},
noop: false
}, {
animation: {
sourceCenter: [0, 0], targetCenter: [0, 0]
},
noop: true
}, {
animation: {
sourceCenter: [1, 0], targetCenter: [0, 0]
},
noop: false
}, {
animation: {
sourceResolution: 1, targetResolution: 1
},
noop: true
}, {
animation: {
sourceResolution: 0, targetResolution: 1
},
noop: false
}, {
animation: {
sourceRotation: 10, targetRotation: 10
},
noop: true
}, {
animation: {
sourceRotation: 0, targetRotation: 10
},
noop: false
}];
cases.forEach(function(c, i) {
it('works for case ' + i, function() {
var noop = ol.View.isNoopAnimation(c.animation);
expect(noop).to.equal(c.noop);
});
});
});