});
Chart.animationService = {
+ frameDuration: 17,
animations: [],
- addAnimation: function(chart, animationObject) {
+ dropFrames: 0,
+ addAnimation: function(chartInstance, animationObject) {
for (var index = 0; index < this.animations.length; ++ index){
- if (this.animations[index].chart === chart){
+ if (this.animations[index].chartInstance === chartInstance){
// replacing an in progress animation
this.animations[index].lastTimeRun = null;
this.animations[index].animationObject = animationObject;
});
// If there are no animations queued, manually kickstart a digest, for lack of a better word
- if(!this.animations.length){
- helpers.requestAnimFrame(this.startDigest);
+ if (this.animations.length) {
+ helpers.requestAnimFrame.call(window, this.digestWrapper);
}
},
+ // Cancel the animation for a given chart instance
+ cancelAnimation: function(chartInstance) {
+ var index = helpers.findNextWhere(this.animations, function(animationWrapper) {
+ return animationWrapper.chartInstance === chartInstance;
+ });
+
+ if (index != -1)
+ {
+ this.animations.splice(index, 1);
+ }
+ },
+ // calls startDigest with the proper context
+ digestWrapper: function() {
+ Chart.animationService.startDigest.call(Chart.animationService);
+ },
startDigest: function() {
+ var startTime = Date.now();
+ var framesToDrop = 0;
+
+ if(this.dropFrames > 1){
+ framesToDrop = Math.floor(this.dropFrames);
+ this.dropFrames -= framesToDrop;
+ }
+
for (var i = 0; i < this.animations.length; i++) {
var currentAnimation = this.animations[i];
if (currentAnimation.animationObject.currentStep === null){
currentAnimation.animationObject.currentStep = 0;
} else {
- currentAnimation.animationObject.currentStep++;
+ currentAnimation.animationObject.currentStep += 1 + framesToDrop;
}
- currentAnimation.animationObject.render(currentAnimation.animationObject);
+ currentAnimation.animationObject.render(currentAnimation.chartInstance, currentAnimation.animationObject);
if (currentAnimation.animationObject.currentStep == currentAnimation.animationObject.numSteps){
// executed the last frame. Remove the animation.
}
}
+ var endTime = Date.now();
+ var delay = endTime - startTime - this.frameDuration;
+ var frameDelay = delay / this.frameDuration;
+
+ if(frameDelay > 1){
+ this.dropFrames += frameDelay;
+ }
+
// Do we have more stuff to animate?
if (this.animations.length > 0){
- requestAnimationFrame(this.startDigest);
+ helpers.requestAnimFrame.call(window, this.digestWrapper);
}
}
};