153 lines
3.5 KiB
JavaScript
153 lines
3.5 KiB
JavaScript
var Class = require('../core/class');
|
|
var Path = require('../core/path');
|
|
|
|
var MOVE = 0, CURVE = 1;
|
|
|
|
var MorphablePath = Class(Path, {
|
|
|
|
initialize: function(path){
|
|
this.reset();
|
|
if (path instanceof MorphablePath){
|
|
this.path = path.path.slice(0);
|
|
} else if (path){
|
|
this.push(path);
|
|
}
|
|
},
|
|
|
|
onReset: function(){
|
|
this.path = [];
|
|
},
|
|
|
|
onMove: function(sx, sy, x, y){
|
|
this.path.push(MOVE, x, y);
|
|
},
|
|
|
|
onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
|
|
this.path.push(CURVE, p1x, p1y, p2x, p2y, x, y);
|
|
}
|
|
|
|
});
|
|
|
|
var Tween = Class({
|
|
|
|
initialize: function(from, to){
|
|
if (!(from instanceof MorphablePath)) from = new MorphablePath(from);
|
|
if (!(to instanceof MorphablePath)) to = new MorphablePath(to);
|
|
this.from = from.path;
|
|
this.to = to.path;
|
|
this.delta = 0;
|
|
},
|
|
|
|
tween: function(delta){
|
|
this.delta = delta;
|
|
},
|
|
|
|
applyToPath: function(path){
|
|
var f = this.from, t = this.to, r = path,
|
|
fi = 0, ti = 0, x, y, delta = this.delta;
|
|
|
|
r.reset();
|
|
|
|
// Unrolled and inlined for performance
|
|
while (fi < f.length || ti < t.length){
|
|
if (fi >= f.length){
|
|
// FROM is over limit but TO is not
|
|
x = f[fi - 2];
|
|
y = f[fi - 1];
|
|
if (t[ti] === MOVE){
|
|
r.moveTo(
|
|
(t[ti + 1] - x) * delta + x,
|
|
(t[ti + 2] - y) * delta + y
|
|
);
|
|
ti += 3;
|
|
} else {
|
|
r.curveTo(
|
|
(t[ti + 1] - x) * delta + x,
|
|
(t[ti + 2] - y) * delta + y,
|
|
(t[ti + 3] - x) * delta + x,
|
|
(t[ti + 4] - y) * delta + y,
|
|
(t[ti + 5] - x) * delta + x,
|
|
(t[ti + 6] - y) * delta + y
|
|
);
|
|
ti += 7;
|
|
}
|
|
} else if (ti >= t.length){
|
|
// TO is over limit but FROM is not
|
|
x = t[ti - 2];
|
|
y = t[ti - 1];
|
|
if (f[fi] === MOVE){
|
|
r.moveTo(
|
|
(x - f[fi + 1]) * delta + f[fi + 1],
|
|
(y - f[fi + 2]) * delta + f[fi + 2]
|
|
);
|
|
fi += 3;
|
|
} else {
|
|
r.curveTo(
|
|
(x - f[fi + 1]) * delta + f[fi + 1],
|
|
(y - f[fi + 2]) * delta + f[fi + 2],
|
|
(x - f[fi + 3]) * delta + f[fi + 3],
|
|
(y - f[fi + 4]) * delta + f[fi + 4],
|
|
(x - f[fi + 5]) * delta + f[fi + 5],
|
|
(y - f[fi + 6]) * delta + f[fi + 6]
|
|
);
|
|
fi += 7;
|
|
}
|
|
} else if (f[fi] === MOVE){
|
|
if (t[ti] === MOVE){
|
|
// Both are moving
|
|
r.moveTo(
|
|
(t[ti + 1] - f[fi + 1]) * delta + f[fi + 1],
|
|
(t[ti + 2] - f[fi + 2]) * delta + f[fi + 2]
|
|
);
|
|
fi += 3;
|
|
ti += 3;
|
|
} else {
|
|
// FROM is moving but TO has a curve
|
|
x = f[fi - 2];
|
|
y = f[fi - 1];
|
|
r.curveTo(
|
|
(t[ti + 1] - x) * delta + x,
|
|
(t[ti + 2] - y) * delta + y,
|
|
(t[ti + 3] - x) * delta + x,
|
|
(t[ti + 4] - y) * delta + y,
|
|
(t[ti + 5] - x) * delta + x,
|
|
(t[ti + 6] - y) * delta + y
|
|
);
|
|
ti += 7;
|
|
}
|
|
} else {
|
|
if (t[ti] === MOVE){
|
|
// TO is moving but FROM has a curve
|
|
x = t[ti - 2];
|
|
y = t[ti - 1];
|
|
r.curveTo(
|
|
(x - f[fi + 1]) * delta + f[fi + 1],
|
|
(y - f[fi + 2]) * delta + f[fi + 2],
|
|
(x - f[fi + 3]) * delta + f[fi + 3],
|
|
(y - f[fi + 4]) * delta + f[fi + 4],
|
|
(x - f[fi + 5]) * delta + f[fi + 5],
|
|
(y - f[fi + 6]) * delta + f[fi + 6]
|
|
);
|
|
fi += 7;
|
|
} else {
|
|
// Both have a curve
|
|
r.curveTo(
|
|
(t[ti + 1] - f[fi + 1]) * delta + f[fi + 1],
|
|
(t[ti + 2] - f[fi + 2]) * delta + f[fi + 2],
|
|
(t[ti + 3] - f[fi + 3]) * delta + f[fi + 3],
|
|
(t[ti + 4] - f[fi + 4]) * delta + f[fi + 4],
|
|
(t[ti + 5] - f[fi + 5]) * delta + f[fi + 5],
|
|
(t[ti + 6] - f[fi + 6]) * delta + f[fi + 6]
|
|
);
|
|
fi += 7;
|
|
ti += 7;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
exports.Path = MorphablePath;
|
|
exports.Tween = Tween;
|