2012-04-03 14:38:14 +08:00
|
|
|
/*
|
2012-04-04 13:23:13 +08:00
|
|
|
* The Tween class was ported from a Adobe Flash Tween library
|
|
|
|
* 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
|
|
|
|
* multiple tweens
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Transition constructor. KineticJS transitions contain
|
|
|
|
* multiple Tweens
|
|
|
|
*/
|
|
|
|
Kinetic.Transition = function(node, config) {
|
|
|
|
this.node = node;
|
|
|
|
this.config = config;
|
|
|
|
this.tweens = [];
|
|
|
|
|
|
|
|
// add tween for each property
|
|
|
|
for(var key in config) {
|
|
|
|
if(key !== 'duration' && key !== 'easing' && key !== 'callback') {
|
|
|
|
if(config[key].x !== 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));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
/*
|
|
|
|
* Transition methods
|
|
|
|
*/
|
|
|
|
Kinetic.Transition.prototype = {
|
|
|
|
add: function(tween) {
|
|
|
|
this.tweens.push(tween);
|
|
|
|
},
|
|
|
|
start: function() {
|
|
|
|
for(var n = 0; n < this.tweens.length; n++) {
|
|
|
|
this.tweens[n].start();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
run: function() {
|
|
|
|
for(var n = 0; n < this.tweens.length; n++) {
|
|
|
|
this.tweens[n].onEnterFrame();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_getTween: function(key) {
|
|
|
|
var config = this.config;
|
|
|
|
var node = this.node;
|
|
|
|
var easing = config.easing;
|
|
|
|
if(easing === undefined) {
|
|
|
|
easing = 'linear';
|
|
|
|
}
|
|
|
|
|
|
|
|
var tween = new Kinetic.Tween(node, function(i) {
|
|
|
|
node[key] = i;
|
|
|
|
}, Kinetic.Tweens[easing], node[key], config[key], config.duration);
|
|
|
|
|
|
|
|
return tween;
|
|
|
|
},
|
|
|
|
_getComponentTween: function(key, prop) {
|
|
|
|
var config = this.config;
|
|
|
|
var node = this.node;
|
|
|
|
var easing = config.easing;
|
|
|
|
if(easing === undefined) {
|
|
|
|
easing = 'linear';
|
|
|
|
}
|
|
|
|
|
|
|
|
var tween = new Kinetic.Tween(node, function(i) {
|
|
|
|
node[key][prop] = i;
|
|
|
|
}, Kinetic.Tweens[easing], node[key][prop], config[key][prop], config.duration);
|
|
|
|
|
|
|
|
return tween;
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tween constructor
|
2012-04-03 14:38:14 +08:00
|
|
|
*/
|
2012-04-04 13:23:13 +08:00
|
|
|
Kinetic.Tween = function(obj, propFunc, func, begin, finish, duration) {
|
2012-04-03 12:03:59 +08:00
|
|
|
this._listeners = [];
|
|
|
|
this.addListener(this);
|
|
|
|
this.obj = obj;
|
|
|
|
this.propFunc = propFunc;
|
|
|
|
this.begin = begin;
|
|
|
|
this._pos = begin;
|
|
|
|
this.setDuration(duration);
|
|
|
|
this.isPlaying = false;
|
|
|
|
this._change = 0;
|
|
|
|
this.prevTime = 0;
|
|
|
|
this.prevPos = 0;
|
|
|
|
this.looping = false;
|
|
|
|
this._time = 0;
|
|
|
|
this._position = 0;
|
|
|
|
this._startTime = 0;
|
|
|
|
this._finish = 0;
|
|
|
|
this.name = '';
|
2012-04-03 14:38:14 +08:00
|
|
|
this.func = func;
|
2012-04-03 12:03:59 +08:00
|
|
|
this.setFinish(finish);
|
|
|
|
};
|
2012-04-04 13:23:13 +08:00
|
|
|
/*
|
|
|
|
* Tween methods
|
|
|
|
*/
|
|
|
|
Kinetic.Tween.prototype = {
|
2012-04-03 12:03:59 +08:00
|
|
|
setTime: function(t) {
|
|
|
|
this.prevTime = this._time;
|
|
|
|
if(t > this.getDuration()) {
|
|
|
|
if(this.looping) {
|
|
|
|
this.rewind(t - this._duration);
|
|
|
|
this.update();
|
2012-04-04 05:08:06 +08:00
|
|
|
this.broadcastMessage('onLooped', {
|
2012-04-03 12:03:59 +08:00
|
|
|
target: this,
|
2012-04-04 05:08:06 +08:00
|
|
|
type: 'onLooped'
|
2012-04-03 12:03:59 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this._time = this._duration;
|
|
|
|
this.update();
|
|
|
|
this.stop();
|
2012-04-04 05:08:06 +08:00
|
|
|
this.broadcastMessage('onFinished', {
|
2012-04-03 12:03:59 +08:00
|
|
|
target: this,
|
2012-04-04 05:08:06 +08:00
|
|
|
type: 'onFinished'
|
2012-04-03 12:03:59 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(t < 0) {
|
|
|
|
this.rewind();
|
|
|
|
this.update();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
this._time = t;
|
|
|
|
this.update();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
getTime: function() {
|
|
|
|
return this._time;
|
|
|
|
},
|
|
|
|
setDuration: function(d) {
|
2012-04-03 13:54:05 +08:00
|
|
|
this._duration = (d === null || d <= 0) ? 100000 : d;
|
2012-04-03 12:03:59 +08:00
|
|
|
},
|
|
|
|
getDuration: function() {
|
|
|
|
return this._duration;
|
|
|
|
},
|
|
|
|
setPosition: function(p) {
|
|
|
|
this.prevPos = this._pos;
|
|
|
|
//var a = this.suffixe != '' ? this.suffixe : '';
|
|
|
|
this.propFunc(p);
|
|
|
|
//+ a;
|
|
|
|
//this.obj(Math.round(p));
|
|
|
|
this._pos = p;
|
2012-04-04 05:08:06 +08:00
|
|
|
this.broadcastMessage('onChanged', {
|
2012-04-03 12:03:59 +08:00
|
|
|
target: this,
|
2012-04-04 05:08:06 +08:00
|
|
|
type: 'onChanged'
|
2012-04-03 12:03:59 +08:00
|
|
|
});
|
|
|
|
},
|
|
|
|
getPosition: function(t) {
|
2012-04-03 13:54:05 +08:00
|
|
|
if(t === undefined) {
|
2012-04-03 12:03:59 +08:00
|
|
|
t = this._time;
|
2012-04-03 13:54:05 +08:00
|
|
|
}
|
2012-04-03 12:03:59 +08:00
|
|
|
return this.func(t, this.begin, this._change, this._duration);
|
|
|
|
},
|
|
|
|
setFinish: function(f) {
|
|
|
|
this._change = f - this.begin;
|
|
|
|
},
|
|
|
|
getFinish: function() {
|
|
|
|
return this.begin + this._change;
|
|
|
|
},
|
|
|
|
start: function() {
|
|
|
|
this.rewind();
|
|
|
|
this.startEnterFrame();
|
2012-04-04 05:08:06 +08:00
|
|
|
this.broadcastMessage('onStarted', {
|
2012-04-03 12:03:59 +08:00
|
|
|
target: this,
|
2012-04-04 05:08:06 +08:00
|
|
|
type: 'onStarted'
|
2012-04-03 12:03:59 +08:00
|
|
|
});
|
|
|
|
},
|
|
|
|
rewind: function(t) {
|
|
|
|
this.stop();
|
2012-04-03 13:54:05 +08:00
|
|
|
this._time = (t === undefined) ? 0 : t;
|
2012-04-03 12:03:59 +08:00
|
|
|
this.fixTime();
|
|
|
|
this.update();
|
|
|
|
},
|
|
|
|
fforward: function() {
|
|
|
|
this._time = this._duration;
|
|
|
|
this.fixTime();
|
|
|
|
this.update();
|
|
|
|
},
|
|
|
|
update: function() {
|
|
|
|
this.setPosition(this.getPosition(this._time));
|
|
|
|
},
|
|
|
|
startEnterFrame: function() {
|
|
|
|
this.stopEnterFrame();
|
|
|
|
this.isPlaying = true;
|
|
|
|
this.onEnterFrame();
|
|
|
|
},
|
|
|
|
onEnterFrame: function() {
|
2012-04-03 13:54:05 +08:00
|
|
|
if(this.isPlaying) {
|
2012-04-03 12:03:59 +08:00
|
|
|
this.nextFrame();
|
2012-04-03 13:54:05 +08:00
|
|
|
}
|
2012-04-03 12:03:59 +08:00
|
|
|
},
|
|
|
|
nextFrame: function() {
|
|
|
|
this.setTime((this.getTimer() - this._startTime) / 1000);
|
|
|
|
},
|
|
|
|
stop: function() {
|
|
|
|
this.stopEnterFrame();
|
2012-04-04 05:08:06 +08:00
|
|
|
this.broadcastMessage('onStopped', {
|
2012-04-03 12:03:59 +08:00
|
|
|
target: this,
|
2012-04-04 05:08:06 +08:00
|
|
|
type: 'onStopped'
|
2012-04-03 12:03:59 +08:00
|
|
|
});
|
|
|
|
},
|
|
|
|
stopEnterFrame: function() {
|
|
|
|
this.isPlaying = false;
|
|
|
|
},
|
|
|
|
continueTo: function(finish, duration) {
|
|
|
|
this.begin = this._pos;
|
|
|
|
this.setFinish(finish);
|
|
|
|
if(this._duration != undefined)
|
|
|
|
this.setDuration(duration);
|
|
|
|
this.start();
|
|
|
|
},
|
|
|
|
resume: function() {
|
|
|
|
this.fixTime();
|
|
|
|
this.startEnterFrame();
|
2012-04-04 05:08:06 +08:00
|
|
|
this.broadcastMessage('onResumed', {
|
2012-04-03 12:03:59 +08:00
|
|
|
target: this,
|
2012-04-04 05:08:06 +08:00
|
|
|
type: 'onResumed'
|
2012-04-03 12:03:59 +08:00
|
|
|
});
|
|
|
|
},
|
|
|
|
yoyo: function() {
|
|
|
|
this.continueTo(this.begin, this._time);
|
|
|
|
},
|
|
|
|
addListener: function(o) {
|
|
|
|
this.removeListener(o);
|
|
|
|
return this._listeners.push(o);
|
|
|
|
},
|
|
|
|
removeListener: function(o) {
|
|
|
|
var a = this._listeners;
|
|
|
|
var i = a.length;
|
|
|
|
while(i--) {
|
|
|
|
if(a[i] == o) {
|
|
|
|
a.splice(i, 1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
broadcastMessage: function() {
|
2012-04-03 13:54:05 +08:00
|
|
|
var arr = [];
|
2012-04-03 12:03:59 +08:00
|
|
|
for(var i = 0; i < arguments.length; i++) {
|
2012-04-03 13:54:05 +08:00
|
|
|
arr.push(arguments[i]);
|
2012-04-03 12:03:59 +08:00
|
|
|
}
|
|
|
|
var e = arr.shift();
|
|
|
|
var a = this._listeners;
|
|
|
|
var l = a.length;
|
|
|
|
for(var i = 0; i < l; i++) {
|
2012-04-03 13:54:05 +08:00
|
|
|
if(a[i][e]) {
|
2012-04-03 12:03:59 +08:00
|
|
|
a[i][e].apply(a[i], arr);
|
2012-04-03 13:54:05 +08:00
|
|
|
}
|
2012-04-03 12:03:59 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
fixTime: function() {
|
|
|
|
this._startTime = this.getTimer() - this._time * 1000;
|
|
|
|
},
|
|
|
|
getTimer: function() {
|
|
|
|
return new Date().getTime() - this._time;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-04-04 13:23:13 +08:00
|
|
|
Kinetic.Tweens = {
|
2012-04-03 13:54:05 +08:00
|
|
|
'back-ease-in': function(t, b, c, d, a, p) {
|
2012-04-03 12:03:59 +08:00
|
|
|
var s = 1.70158;
|
|
|
|
return c * (t /= d) * t * ((s + 1) * t - s) + b;
|
|
|
|
},
|
2012-04-03 13:54:05 +08:00
|
|
|
'back-ease-out': function(t, b, c, d, a, p) {
|
2012-04-03 12:03:59 +08:00
|
|
|
var s = 1.70158;
|
|
|
|
return c * (( t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
|
|
|
|
},
|
2012-04-03 13:54:05 +08:00
|
|
|
'back-ease-in-out': function(t, b, c, d, a, p) {
|
2012-04-03 12:03:59 +08:00
|
|
|
var s = 1.70158;
|
|
|
|
if((t /= d / 2) < 1) {
|
|
|
|
return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
|
|
|
|
}
|
|
|
|
return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
|
|
|
|
},
|
2012-04-03 13:54:05 +08:00
|
|
|
'elastic-ease-in': function(t, b, c, d, a, p) {
|
2012-04-03 12:03:59 +08:00
|
|
|
// added s = 0
|
|
|
|
var s = 0;
|
|
|
|
if(t === 0) {
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
if((t /= d) == 1) {
|
|
|
|
return b + c;
|
|
|
|
}
|
|
|
|
if(!p) {
|
|
|
|
p = d * 0.3;
|
|
|
|
}
|
|
|
|
if(!a || a < Math.abs(c)) {
|
|
|
|
a = c;
|
|
|
|
s = p / 4;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
s = p / (2 * Math.PI) * Math.asin(c / a);
|
|
|
|
}
|
|
|
|
return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
|
|
|
|
},
|
2012-04-03 13:54:05 +08:00
|
|
|
'elastic-ease-out': function(t, b, c, d, a, p) {
|
2012-04-03 12:03:59 +08:00
|
|
|
// added s = 0
|
|
|
|
var s = 0;
|
|
|
|
if(t === 0) {
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
if((t /= d) == 1) {
|
|
|
|
return b + c;
|
|
|
|
}
|
|
|
|
if(!p) {
|
|
|
|
p = d * 0.3;
|
|
|
|
}
|
|
|
|
if(!a || a < Math.abs(c)) {
|
|
|
|
a = c;
|
|
|
|
s = p / 4;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
s = p / (2 * Math.PI) * Math.asin(c / a);
|
|
|
|
}
|
|
|
|
return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b);
|
|
|
|
},
|
2012-04-03 13:54:05 +08:00
|
|
|
'elastic-ease-in-out': function(t, b, c, d, a, p) {
|
2012-04-03 12:03:59 +08:00
|
|
|
var s = 0;
|
|
|
|
if(t === 0) {
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
if((t /= d / 2) == 2) {
|
|
|
|
return b + c;
|
|
|
|
}
|
|
|
|
if(!p) {
|
|
|
|
p = d * (0.3 * 1.5);
|
|
|
|
}
|
|
|
|
if(!a || a < Math.abs(c)) {
|
|
|
|
a = c;
|
|
|
|
s = p / 4;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
s = p / (2 * Math.PI) * Math.asin(c / a);
|
|
|
|
}
|
|
|
|
if(t < 1) {
|
|
|
|
return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
|
|
|
|
}
|
|
|
|
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * 0.5 + c + b;
|
|
|
|
},
|
2012-04-03 13:54:05 +08:00
|
|
|
'bounce-ease-out': function(t, b, c, d) {
|
2012-04-03 12:03:59 +08:00
|
|
|
if((t /= d) < (1 / 2.75)) {
|
|
|
|
return c * (7.5625 * t * t) + b;
|
|
|
|
}
|
|
|
|
else if(t < (2 / 2.75)) {
|
|
|
|
return c * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75) + b;
|
|
|
|
}
|
|
|
|
else if(t < (2.5 / 2.75)) {
|
|
|
|
return c * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375) + b;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return c * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375) + b;
|
|
|
|
}
|
|
|
|
},
|
2012-04-03 13:54:05 +08:00
|
|
|
'bounce-ease-in': function(t, b, c, d) {
|
2012-04-04 13:23:13 +08:00
|
|
|
return c - Kinetic.Tweens.bounceEaseOut(d - t, 0, c, d) + b;
|
2012-04-03 12:03:59 +08:00
|
|
|
},
|
2012-04-03 13:54:05 +08:00
|
|
|
'bounce-ease-in-out': function(t, b, c, d) {
|
2012-04-03 12:03:59 +08:00
|
|
|
if(t < d / 2) {
|
2012-04-04 13:23:13 +08:00
|
|
|
return Kinetic.Tweens.bounceEaseIn(t * 2, 0, c, d) * 0.5 + b;
|
2012-04-03 12:03:59 +08:00
|
|
|
}
|
|
|
|
else {
|
2012-04-04 13:23:13 +08:00
|
|
|
return Kinetic.Tweens.bounceEaseOut(t * 2 - d, 0, c, d) * 0.5 + c * 0.5 + b;
|
2012-04-03 12:03:59 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
// duplicate
|
|
|
|
/*
|
|
|
|
strongEaseInOut: function(t, b, c, d) {
|
|
|
|
return c * (t /= d) * t * t * t * t + b;
|
|
|
|
},
|
|
|
|
*/
|
2012-04-03 13:54:05 +08:00
|
|
|
'ease-in': function(t, b, c, d) {
|
2012-04-03 12:03:59 +08:00
|
|
|
return c * (t /= d) * t + b;
|
|
|
|
},
|
2012-04-03 13:54:05 +08:00
|
|
|
'ease-out': function(t, b, c, d) {
|
2012-04-03 12:03:59 +08:00
|
|
|
return -c * (t /= d) * (t - 2) + b;
|
|
|
|
},
|
2012-04-03 13:54:05 +08:00
|
|
|
'ease-in-out': function(t, b, c, d) {
|
2012-04-03 12:03:59 +08:00
|
|
|
if((t /= d / 2) < 1) {
|
|
|
|
return c / 2 * t * t + b;
|
|
|
|
}
|
|
|
|
return -c / 2 * ((--t) * (t - 2) - 1) + b;
|
|
|
|
},
|
2012-04-03 13:54:05 +08:00
|
|
|
'strong-ease-in': function(t, b, c, d) {
|
2012-04-03 12:03:59 +08:00
|
|
|
return c * (t /= d) * t * t * t * t + b;
|
|
|
|
},
|
2012-04-03 13:54:05 +08:00
|
|
|
'strong-ease-out': function(t, b, c, d) {
|
2012-04-03 12:03:59 +08:00
|
|
|
return c * (( t = t / d - 1) * t * t * t * t + 1) + b;
|
|
|
|
},
|
2012-04-03 13:54:05 +08:00
|
|
|
'strong-ease-in-out': function(t, b, c, d) {
|
2012-04-03 12:03:59 +08:00
|
|
|
if((t /= d / 2) < 1) {
|
|
|
|
return c / 2 * t * t * t * t * t + b;
|
|
|
|
}
|
|
|
|
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
|
2012-04-03 14:38:14 +08:00
|
|
|
},
|
|
|
|
'linear': function(t, b, c, d) {
|
|
|
|
return c * t / d + b;
|
|
|
|
},
|
2012-04-03 12:03:59 +08:00
|
|
|
};
|