mirror of
https://github.com/konvajs/konva.git
synced 2025-05-04 04:57:59 +08:00
greatly improved sprite animation performance by hooking into the global animation object
This commit is contained in:
parent
a8ab9a2533
commit
30fd5c1fa7
52
dist/kinetic-core.js
vendored
52
dist/kinetic-core.js
vendored
@ -363,12 +363,22 @@ Kinetic.Animation = {
|
|||||||
},
|
},
|
||||||
_runFrames: function() {
|
_runFrames: function() {
|
||||||
var nodes = {};
|
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++) {
|
for(var n = 0; n < this.animations.length; n++) {
|
||||||
var anim = this.animations[n];
|
var anim = this.animations[n];
|
||||||
if(anim.node && anim.node._id !== undefined) {
|
if(anim.node && anim.node._id !== undefined) {
|
||||||
nodes[anim.node._id] = anim.node;
|
nodes[anim.node._id] = anim.node;
|
||||||
}
|
}
|
||||||
anim.func(this.frame);
|
// if animation object has a function, execute it
|
||||||
|
if(anim.func) {
|
||||||
|
anim.func(this.frame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var key in nodes) {
|
for(var key in nodes) {
|
||||||
@ -1012,9 +1022,9 @@ Kinetic.Node = Kinetic.Class.extend({
|
|||||||
* clear transition if one is currently running for this
|
* clear transition if one is currently running for this
|
||||||
* node
|
* node
|
||||||
*/
|
*/
|
||||||
if(this.transAnim !== undefined) {
|
if(this.transAnim) {
|
||||||
a._removeAnimation(this.transAnim);
|
a._removeAnimation(this.transAnim);
|
||||||
this.transAnim = undefined;
|
this.transAnim = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1043,7 +1053,7 @@ Kinetic.Node = Kinetic.Class.extend({
|
|||||||
trans.onFinished = function() {
|
trans.onFinished = function() {
|
||||||
// remove animation
|
// remove animation
|
||||||
a._removeAnimation(anim);
|
a._removeAnimation(anim);
|
||||||
that.transAnim = undefined;
|
that.transAnim = null;
|
||||||
|
|
||||||
// callback
|
// callback
|
||||||
if(config.callback !== undefined) {
|
if(config.callback !== undefined) {
|
||||||
@ -3677,18 +3687,48 @@ Kinetic.Sprite = Kinetic.Shape.extend({
|
|||||||
start: function() {
|
start: function() {
|
||||||
var that = this;
|
var that = this;
|
||||||
var layer = this.getLayer();
|
var layer = this.getLayer();
|
||||||
|
var ka = Kinetic.Animation;
|
||||||
|
|
||||||
|
// if sprite already has an animation, remove it
|
||||||
|
if(this.anim) {
|
||||||
|
ka._removeAnimation(this.anim);
|
||||||
|
this.anim = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* animation object has no executable function because
|
||||||
|
* the updates are done with a fixed FPS with the setInterval
|
||||||
|
* below. The anim object only needs the layer reference for
|
||||||
|
* redraw
|
||||||
|
*/
|
||||||
|
this.anim = {
|
||||||
|
node: layer
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* adding the animation with the addAnimation
|
||||||
|
* method auto generates an id
|
||||||
|
*/
|
||||||
|
ka._addAnimation(this.anim);
|
||||||
|
|
||||||
this.interval = setInterval(function() {
|
this.interval = setInterval(function() {
|
||||||
that._updateIndex();
|
that._updateIndex();
|
||||||
layer.draw();
|
|
||||||
if(that.afterFrameFunc && that.attrs.index === that.afterFrameIndex) {
|
if(that.afterFrameFunc && that.attrs.index === that.afterFrameIndex) {
|
||||||
that.afterFrameFunc();
|
that.afterFrameFunc();
|
||||||
}
|
}
|
||||||
}, 1000 / this.attrs.frameRate)
|
}, 1000 / this.attrs.frameRate);
|
||||||
|
|
||||||
|
ka._handleAnimation();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* stop sprite animation
|
* stop sprite animation
|
||||||
*/
|
*/
|
||||||
stop: function() {
|
stop: function() {
|
||||||
|
var ka = Kinetic.Animation;
|
||||||
|
if(this.anim) {
|
||||||
|
ka._removeAnimation(this.anim);
|
||||||
|
this.anim = null;
|
||||||
|
}
|
||||||
clearInterval(this.interval);
|
clearInterval(this.interval);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
4
dist/kinetic-core.min.js
vendored
4
dist/kinetic-core.min.js
vendored
File diff suppressed because one or more lines are too long
@ -26,12 +26,22 @@ Kinetic.Animation = {
|
|||||||
},
|
},
|
||||||
_runFrames: function() {
|
_runFrames: function() {
|
||||||
var nodes = {};
|
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++) {
|
for(var n = 0; n < this.animations.length; n++) {
|
||||||
var anim = this.animations[n];
|
var anim = this.animations[n];
|
||||||
if(anim.node && anim.node._id !== undefined) {
|
if(anim.node && anim.node._id !== undefined) {
|
||||||
nodes[anim.node._id] = anim.node;
|
nodes[anim.node._id] = anim.node;
|
||||||
}
|
}
|
||||||
anim.func(this.frame);
|
// if animation object has a function, execute it
|
||||||
|
if(anim.func) {
|
||||||
|
anim.func(this.frame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var key in nodes) {
|
for(var key in nodes) {
|
||||||
|
@ -591,9 +591,9 @@ Kinetic.Node = Kinetic.Class.extend({
|
|||||||
* clear transition if one is currently running for this
|
* clear transition if one is currently running for this
|
||||||
* node
|
* node
|
||||||
*/
|
*/
|
||||||
if(this.transAnim !== undefined) {
|
if(this.transAnim) {
|
||||||
a._removeAnimation(this.transAnim);
|
a._removeAnimation(this.transAnim);
|
||||||
this.transAnim = undefined;
|
this.transAnim = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -622,7 +622,7 @@ Kinetic.Node = Kinetic.Class.extend({
|
|||||||
trans.onFinished = function() {
|
trans.onFinished = function() {
|
||||||
// remove animation
|
// remove animation
|
||||||
a._removeAnimation(anim);
|
a._removeAnimation(anim);
|
||||||
that.transAnim = undefined;
|
that.transAnim = null;
|
||||||
|
|
||||||
// callback
|
// callback
|
||||||
if(config.callback !== undefined) {
|
if(config.callback !== undefined) {
|
||||||
|
@ -43,18 +43,48 @@ Kinetic.Sprite = Kinetic.Shape.extend({
|
|||||||
start: function() {
|
start: function() {
|
||||||
var that = this;
|
var that = this;
|
||||||
var layer = this.getLayer();
|
var layer = this.getLayer();
|
||||||
|
var ka = Kinetic.Animation;
|
||||||
|
|
||||||
|
// if sprite already has an animation, remove it
|
||||||
|
if(this.anim) {
|
||||||
|
ka._removeAnimation(this.anim);
|
||||||
|
this.anim = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* animation object has no executable function because
|
||||||
|
* the updates are done with a fixed FPS with the setInterval
|
||||||
|
* below. The anim object only needs the layer reference for
|
||||||
|
* redraw
|
||||||
|
*/
|
||||||
|
this.anim = {
|
||||||
|
node: layer
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* adding the animation with the addAnimation
|
||||||
|
* method auto generates an id
|
||||||
|
*/
|
||||||
|
ka._addAnimation(this.anim);
|
||||||
|
|
||||||
this.interval = setInterval(function() {
|
this.interval = setInterval(function() {
|
||||||
that._updateIndex();
|
that._updateIndex();
|
||||||
layer.draw();
|
|
||||||
if(that.afterFrameFunc && that.attrs.index === that.afterFrameIndex) {
|
if(that.afterFrameFunc && that.attrs.index === that.afterFrameIndex) {
|
||||||
that.afterFrameFunc();
|
that.afterFrameFunc();
|
||||||
}
|
}
|
||||||
}, 1000 / this.attrs.frameRate)
|
}, 1000 / this.attrs.frameRate);
|
||||||
|
|
||||||
|
ka._handleAnimation();
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* stop sprite animation
|
* stop sprite animation
|
||||||
*/
|
*/
|
||||||
stop: function() {
|
stop: function() {
|
||||||
|
var ka = Kinetic.Animation;
|
||||||
|
if(this.anim) {
|
||||||
|
ka._removeAnimation(this.anim);
|
||||||
|
this.anim = null;
|
||||||
|
}
|
||||||
clearInterval(this.interval);
|
clearInterval(this.interval);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
|
@ -2068,13 +2068,13 @@ Test.prototype.tests = {
|
|||||||
animation: 'standing',
|
animation: 'standing',
|
||||||
animations: anims,
|
animations: anims,
|
||||||
index: 0,
|
index: 0,
|
||||||
//frameRate: Math.random() * 6 + 6,
|
frameRate: Math.random() * 6 + 6,
|
||||||
frameRate: 10,
|
frameRate: 10,
|
||||||
draggable: true,
|
draggable: true,
|
||||||
shadow: {
|
shadow: {
|
||||||
color: 'black',
|
color: 'black',
|
||||||
blur: 3,
|
blur: 3,
|
||||||
offset: [10, 10],
|
offset: [3, 1],
|
||||||
alpha: 0.3
|
alpha: 0.3
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -2086,19 +2086,16 @@ Test.prototype.tests = {
|
|||||||
stage.add(layer);
|
stage.add(layer);
|
||||||
|
|
||||||
// kick once
|
// kick once
|
||||||
/*
|
setTimeout(function() {
|
||||||
setTimeout(function() {
|
sprite.setAnimation('kicking');
|
||||||
sprite.setIndex(0);
|
|
||||||
sprite.setAnimation('kicking');
|
|
||||||
|
|
||||||
sprite.afterFrame(0, function() {
|
sprite.afterFrame(0, function() {
|
||||||
sprite.setAnimation('standing');
|
sprite.setAnimation('standing');
|
||||||
});
|
});
|
||||||
}, 2000);
|
}, 2000);
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
//sprite.start();
|
sprite.stop();
|
||||||
}, 3000);
|
}, 3000);
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
imageObj.src = '../scorpion-sprite.png';
|
imageObj.src = '../scorpion-sprite.png';
|
||||||
},
|
},
|
||||||
@ -3203,7 +3200,7 @@ Test.prototype.tests = {
|
|||||||
// make sure private ids are different
|
// make sure private ids are different
|
||||||
test(rect._id !== clone._id, 'rect and clone ids should be different');
|
test(rect._id !== clone._id, 'rect and clone ids should be different');
|
||||||
|
|
||||||
// test user event binding cloning
|
// test user event binding cloning
|
||||||
test(clicks.length === 0, 'no clicks should have been triggered yet');
|
test(clicks.length === 0, 'no clicks should have been triggered yet');
|
||||||
rect.simulate('click');
|
rect.simulate('click');
|
||||||
test(clicks.toString() === 'myRect', 'only myRect should have been clicked on');
|
test(clicks.toString() === 'myRect', 'only myRect should have been clicked on');
|
||||||
@ -4535,6 +4532,11 @@ Test.prototype.tests = {
|
|||||||
// ANIMATION tests
|
// ANIMATION tests
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WARNING: make sure that this is the first unit test that uses
|
||||||
|
* animation because it's accessing the global animation object which could
|
||||||
|
* be modified by other unit tests
|
||||||
|
*/
|
||||||
'ANIMATION - test start and stop': function(containerId) {
|
'ANIMATION - test start and stop': function(containerId) {
|
||||||
var stage = new Kinetic.Stage({
|
var stage = new Kinetic.Stage({
|
||||||
container: containerId,
|
container: containerId,
|
||||||
|
Loading…
Reference in New Issue
Block a user