konva/src/Animation.js

124 lines
4.1 KiB
JavaScript
Raw Normal View History

(function() {
/**
* Stage constructor. A stage is used to contain multiple layers and handle
* animations
* @constructor
* @param {Function} func function executed on each animation frame
* @param {Kinetic.Node} [node] node to be redrawn.  Specifying a node will improve
* draw performance.  This can be a shape, a group, a layer, or the stage.
*/
Kinetic.Animation = function(func, node) {
this.func = func;
this.node = node;
this.id = Kinetic.Animation.animIdCounter++;
this.frame = {
time: 0,
timeDiff: 0,
lastTime: new Date().getTime()
};
};
/*
* Animation methods
*/
Kinetic.Animation.prototype = {
/**
* start animation
* @name start
* @methodOf Kinetic.Animation.prototype
*/
start: function() {
this.stop();
this.frame.timeDiff = 0;
this.frame.lastTime = new Date().getTime();
Kinetic.Animation._addAnimation(this);
Kinetic.Animation._handleAnimation();
},
/**
* stop animation
* @name stop
* @methodOf Kinetic.Animation.prototype
*/
stop: function() {
Kinetic.Animation._removeAnimation(this);
},
_updateFrameObject: function() {
var time = new Date().getTime();
this.frame.timeDiff = time - this.frame.lastTime;
this.frame.lastTime = time;
this.frame.time += this.frame.timeDiff;
this.frame.frameRate = 1000 / this.frame.timeDiff;
}
};
Kinetic.Animation.animations = [];
Kinetic.Animation.animIdCounter = 0;
Kinetic.Animation.animRunning = false;
Kinetic.Animation.fixedRequestAnimFrame = function(callback) {
window.setTimeout(callback, 1000 / 60);
};
Kinetic.Animation._addAnimation = function(anim) {
this.animations.push(anim);
};
Kinetic.Animation._removeAnimation = function(anim) {
var id = anim.id;
var animations = this.animations;
for(var n = 0; n < animations.length; n++) {
if(animations[n].id === id) {
this.animations.splice(n, 1);
break;
}
}
};
Kinetic.Animation._runFrames = function() {
var nodes = {};
/*
* loop through all animations and execute animation
* function. if the animation object has specified node,
* we can add the node to the nodes hash to eliminate
* drawing the same node multiple times. The node property
* can be the stage itself or a layer
*/
for(var n = 0; n < this.animations.length; n++) {
var anim = this.animations[n];
anim._updateFrameObject();
if(anim.node && anim.node._id !== undefined) {
nodes[anim.node._id] = anim.node;
}
// if animation object has a function, execute it
if(anim.func) {
anim.func(anim.frame);
}
}
for(var key in nodes) {
nodes[key].draw();
}
};
Kinetic.Animation._animationLoop = function() {
if(this.animations.length > 0) {
this._runFrames();
var that = this;
Kinetic.Animation.requestAnimFrame(function() {
that._animationLoop();
});
}
else {
this.animRunning = false;
}
};
Kinetic.Animation._handleAnimation = function() {
var that = this;
if(!this.animRunning) {
this.animRunning = true;
that._animationLoop();
}
};
Kinetic.Animation.requestAnimFrame = function(callback) {
var raf = Kinetic.DD && Kinetic.DD.moving ? this.fixedRequestAnimFrame : window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || Kinetic.Animation.fixedRequestAnimFrame;
raf(callback);
};
})();