finished new animation, transitions, and tweens functionality

This commit is contained in:
Eric Rowell 2012-04-03 23:00:35 -07:00
parent f953e4694f
commit 602220bdce
6 changed files with 234 additions and 48 deletions

92
dist/kinetic-core.js vendored
View File

@ -77,17 +77,17 @@ Kinetic.GlobalObject = {
} }
}, },
_runFrames: function() { _runFrames: function() {
var draws = {}; var nodes = {};
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.drawId) { if(anim.node && anim.node.id !== undefined) {
draws[anim.drawId] = anim.draw; nodes[anim.node.id] = anim.node;
} }
anim.func(this.frame); anim.func(this.frame);
} }
for(var key in draws) { for(var key in nodes) {
draws[key].draw(); nodes[key].draw();
} }
}, },
_updateFrameObject: function() { _updateFrameObject: function() {
@ -609,29 +609,46 @@ Kinetic.Node.prototype = {
* radius, scale.x, scale.y, centerOffset.x, centerOffset.y, etc. * radius, scale.x, scale.y, centerOffset.x, centerOffset.y, etc.
* @param {Object} config * @param {Object} config
* @config {Number} [duration] duration that the transition runs in seconds * @config {Number} [duration] duration that the transition runs in seconds
* @config {String} [easing] easing function. can be linear, ease-in, ease-out, or ease-in-out. * @config {String} [easing] easing function. can be linear, ease-in, ease-out, ease-in-out,
* back-ease-in, back-ease-out, back-ease-in-out, elastic-ease-in, elastic-ease-out,
* elastic-ease-in-out, bounce-ease-out, bounce-ease-in, bounce-ease-in-out,
* strong-ease-in, strong-ease-out, or strong-ease-in-out
* linear is the default * linear is the default
* @config {Function} [callback] callback function to be executed when * @config {Function} [callback] callback function to be executed when
* transition completes * transition completes
*/ */
transitionTo: function(config) { transitionTo: function(config) {
var layer = this.getLayer(); var node = this.className === 'Stage' ? this : this.getLayer();
var that = this; var that = this;
var go = Kinetic.GlobalObject; var go = Kinetic.GlobalObject;
var trans = new Kinetic.Transition(this, config); var trans = new Kinetic.Transition(this, config);
var anim = {
go.addAnimation({
func: function() { func: function() {
trans.run(); trans.onEnterFrame();
}, },
drawId: layer.id, node: node
draw: layer };
});
/*
* adding the animation with the addAnimation
* method auto generates an id
*/
go.addAnimation(anim);
// subscribe to onFinished for first tween
trans.tweens[0].onFinished = function() {
go.removeAnimation(anim.id);
if(config.callback !== undefined) {
config.callback();
}
};
// auto start
trans.start(); trans.start();
go._handleAnimation(); go._handleAnimation();
return trans;
}, },
/** /**
* set drag constraint * set drag constraint
@ -2791,7 +2808,7 @@ Kinetic.Transform.prototype = {
}; };
/* /*
* The Tween class was ported from a Adobe Flash Tween library * The Tween class was ported from an Adobe Flash Tween library
* to JavaScript by Xaric. In the context of KineticJS, a Tween is * to JavaScript by Xaric. In the context of KineticJS, a Tween is
* an animation of a single Node property. A Transition is a set of * an animation of a single Node property. A Transition is a set of
* multiple tweens * multiple tweens
@ -2800,6 +2817,9 @@ Kinetic.Transform.prototype = {
/** /**
* Transition constructor. KineticJS transitions contain * Transition constructor. KineticJS transitions contain
* multiple Tweens * multiple Tweens
* @constructor
* @param {Kinetic.Node} node
* @param {Object} config
*/ */
Kinetic.Transition = function(node, config) { Kinetic.Transition = function(node, config) {
this.node = node; this.node = node;
@ -2809,15 +2829,15 @@ Kinetic.Transition = function(node, config) {
// add tween for each property // add tween for each property
for(var key in config) { for(var key in config) {
if(key !== 'duration' && key !== 'easing' && key !== 'callback') { if(key !== 'duration' && key !== 'easing' && key !== 'callback') {
if(config[key].x !== undefined) { if(config[key].x === undefined && config[key].y === undefined) {
this.add(that._getComponentTween(key, 'x', config));
}
else if(config[key].y !== undefined) {
this.add(that._getComponentTween(key, 'y', config));
}
else {
this.add(this._getTween(key, config)); this.add(this._getTween(key, config));
} }
if(config[key].x !== undefined) {
this.add(this._getComponentTween(key, 'x', config));
}
if(config[key].y !== undefined) {
this.add(this._getComponentTween(key, 'y', config));
}
} }
} }
}; };
@ -2825,19 +2845,45 @@ Kinetic.Transition = function(node, config) {
* Transition methods * Transition methods
*/ */
Kinetic.Transition.prototype = { Kinetic.Transition.prototype = {
/**
* add tween to tweens array
* @param {Kinetic.Tween} tween
*/
add: function(tween) { add: function(tween) {
this.tweens.push(tween); this.tweens.push(tween);
}, },
/**
* start transition
*/
start: function() { start: function() {
for(var n = 0; n < this.tweens.length; n++) { for(var n = 0; n < this.tweens.length; n++) {
this.tweens[n].start(); this.tweens[n].start();
} }
}, },
run: function() { /**
* onEnterFrame
*/
onEnterFrame: function() {
for(var n = 0; n < this.tweens.length; n++) { for(var n = 0; n < this.tweens.length; n++) {
this.tweens[n].onEnterFrame(); this.tweens[n].onEnterFrame();
} }
}, },
/**
* stop transition
*/
stop: function() {
for(var n = 0; n < this.tweens.length; n++) {
this.tweens[n].stop();
}
},
/**
* resume transition
*/
resume: function() {
for(var n = 0; n < this.tweens.length; n++) {
this.tweens[n].resume();
}
},
_getTween: function(key) { _getTween: function(key) {
var config = this.config; var config = this.config;
var node = this.node; var node = this.node;

File diff suppressed because one or more lines are too long

View File

@ -49,17 +49,17 @@ Kinetic.GlobalObject = {
} }
}, },
_runFrames: function() { _runFrames: function() {
var draws = {}; var nodes = {};
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.drawId) { if(anim.node && anim.node.id !== undefined) {
draws[anim.drawId] = anim.draw; nodes[anim.node.id] = anim.node;
} }
anim.func(this.frame); anim.func(this.frame);
} }
for(var key in draws) { for(var key in nodes) {
draws[key].draw(); nodes[key].draw();
} }
}, },
_updateFrameObject: function() { _updateFrameObject: function() {

View File

@ -474,29 +474,46 @@ Kinetic.Node.prototype = {
* radius, scale.x, scale.y, centerOffset.x, centerOffset.y, etc. * radius, scale.x, scale.y, centerOffset.x, centerOffset.y, etc.
* @param {Object} config * @param {Object} config
* @config {Number} [duration] duration that the transition runs in seconds * @config {Number} [duration] duration that the transition runs in seconds
* @config {String} [easing] easing function. can be linear, ease-in, ease-out, or ease-in-out. * @config {String} [easing] easing function. can be linear, ease-in, ease-out, ease-in-out,
* back-ease-in, back-ease-out, back-ease-in-out, elastic-ease-in, elastic-ease-out,
* elastic-ease-in-out, bounce-ease-out, bounce-ease-in, bounce-ease-in-out,
* strong-ease-in, strong-ease-out, or strong-ease-in-out
* linear is the default * linear is the default
* @config {Function} [callback] callback function to be executed when * @config {Function} [callback] callback function to be executed when
* transition completes * transition completes
*/ */
transitionTo: function(config) { transitionTo: function(config) {
var layer = this.getLayer(); var node = this.className === 'Stage' ? this : this.getLayer();
var that = this; var that = this;
var go = Kinetic.GlobalObject; var go = Kinetic.GlobalObject;
var trans = new Kinetic.Transition(this, config); var trans = new Kinetic.Transition(this, config);
var anim = {
go.addAnimation({
func: function() { func: function() {
trans.run(); trans.onEnterFrame();
}, },
drawId: layer.id, node: node
draw: layer };
});
/*
* adding the animation with the addAnimation
* method auto generates an id
*/
go.addAnimation(anim);
// subscribe to onFinished for first tween
trans.tweens[0].onFinished = function() {
go.removeAnimation(anim.id);
if(config.callback !== undefined) {
config.callback();
}
};
// auto start
trans.start(); trans.start();
go._handleAnimation(); go._handleAnimation();
return trans;
}, },
/** /**
* set drag constraint * set drag constraint

View File

@ -1,5 +1,5 @@
/* /*
* The Tween class was ported from a Adobe Flash Tween library * The Tween class was ported from an Adobe Flash Tween library
* to JavaScript by Xaric. In the context of KineticJS, a Tween is * to JavaScript by Xaric. In the context of KineticJS, a Tween is
* an animation of a single Node property. A Transition is a set of * an animation of a single Node property. A Transition is a set of
* multiple tweens * multiple tweens
@ -8,6 +8,9 @@
/** /**
* Transition constructor. KineticJS transitions contain * Transition constructor. KineticJS transitions contain
* multiple Tweens * multiple Tweens
* @constructor
* @param {Kinetic.Node} node
* @param {Object} config
*/ */
Kinetic.Transition = function(node, config) { Kinetic.Transition = function(node, config) {
this.node = node; this.node = node;
@ -17,15 +20,15 @@ Kinetic.Transition = function(node, config) {
// add tween for each property // add tween for each property
for(var key in config) { for(var key in config) {
if(key !== 'duration' && key !== 'easing' && key !== 'callback') { if(key !== 'duration' && key !== 'easing' && key !== 'callback') {
if(config[key].x !== undefined) { if(config[key].x === undefined && config[key].y === undefined) {
this.add(that._getComponentTween(key, 'x', config));
}
else if(config[key].y !== undefined) {
this.add(that._getComponentTween(key, 'y', config));
}
else {
this.add(this._getTween(key, config)); this.add(this._getTween(key, config));
} }
if(config[key].x !== undefined) {
this.add(this._getComponentTween(key, 'x', config));
}
if(config[key].y !== undefined) {
this.add(this._getComponentTween(key, 'y', config));
}
} }
} }
}; };
@ -33,19 +36,45 @@ Kinetic.Transition = function(node, config) {
* Transition methods * Transition methods
*/ */
Kinetic.Transition.prototype = { Kinetic.Transition.prototype = {
/**
* add tween to tweens array
* @param {Kinetic.Tween} tween
*/
add: function(tween) { add: function(tween) {
this.tweens.push(tween); this.tweens.push(tween);
}, },
/**
* start transition
*/
start: function() { start: function() {
for(var n = 0; n < this.tweens.length; n++) { for(var n = 0; n < this.tweens.length; n++) {
this.tweens[n].start(); this.tweens[n].start();
} }
}, },
run: function() { /**
* onEnterFrame
*/
onEnterFrame: function() {
for(var n = 0; n < this.tweens.length; n++) { for(var n = 0; n < this.tweens.length; n++) {
this.tweens[n].onEnterFrame(); this.tweens[n].onEnterFrame();
} }
}, },
/**
* stop transition
*/
stop: function() {
for(var n = 0; n < this.tweens.length; n++) {
this.tweens[n].stop();
}
},
/**
* resume transition
*/
resume: function() {
for(var n = 0; n < this.tweens.length; n++) {
this.tweens[n].resume();
}
},
_getTween: function(key) { _getTween: function(key) {
var config = this.config; var config = this.config;
var node = this.node; var node = this.node;

View File

@ -27,6 +27,100 @@ Test.prototype.tests = {
easing: 'bounce-ease-out' easing: 'bounce-ease-out'
}); });
}, },
'TRANSITION - transition callback': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var rect = new Kinetic.Rect({
x: 100,
y: 100,
width: 100,
height: 50,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
layer.add(rect);
stage.add(layer);
rect.transitionTo({
duration: 2,
x: 400,
y: 30,
rotation: Math.PI * 2,
easing: 'bounce-ease-out',
callback: function() {
console.log('transition done!');
}
});
},
'TRANSITION - stop and resume transition': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var rect = new Kinetic.Rect({
x: 100,
y: 100,
width: 100,
height: 50,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
layer.add(rect);
stage.add(layer);
var trans = rect.transitionTo({
duration: 2,
x: 400,
y: 30,
rotation: Math.PI * 2,
easing: 'bounce-ease-out'
});
setTimeout(function() {
trans.stop();
}, 1000);
setTimeout(function() {
trans.resume();
}, 2000);
},
'TRANSITION - transition stage': function(containerId) {
var stage = new Kinetic.Stage({
container: containerId,
width: 578,
height: 200
});
var layer = new Kinetic.Layer();
var rect = new Kinetic.Rect({
x: 100,
y: 100,
width: 100,
height: 50,
fill: 'green',
stroke: 'black',
strokeWidth: 4
});
layer.add(rect);
stage.add(layer);
var trans = stage.transitionTo({
duration: 2,
x: 400,
y: 30,
rotation: Math.PI * 2,
easing: 'bounce-ease-out'
});
},
'TRANSITION - transition position and rotation with two transitions': function(containerId) { 'TRANSITION - transition position and rotation with two transitions': function(containerId) {
var stage = new Kinetic.Stage({ var stage = new Kinetic.Stage({
container: containerId, container: containerId,