-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tweening arrays and objects? #78
Comments
WOW. Now that is massive! 😱 The reason tween.js is fast is because it's simple at its core. If we add all these checks to be executed per frame, it will slow down. I think a solution for tweening complicated objects could be to "flatten" the properties you want to tween, and create a similarly flat object for the "to" values. The onUpdate function should take care of updating the original object with the values from the tween, and that way you'd have only ONE tween which means only ONE easing function would be calculated, not one per nested / complicated property. I know this is something that needs to be done somehow often when you try to animate complex objects, so I wouldn't be against it per se, but definitely would try to go the external function that preprocesses and creates an onUpdate function route rather than modifying the tween.js core. |
Also, there is support for tweening array values already: http://sole.github.io/tween.js/examples/06_array_interpolation.html |
I agree. If anything something like |
I've rewritten the code using the "flatten" method and a single tween instead of multiple, and it's got support for nesting! Aswell as colors (depends on tinycolors), which is a bit convoluted though to make sure it doesn't change hsv to hex, just hex to hsv and back to hex: http://jsfiddle.net/gautamadude/engDj/ var from = {x: 0, y: {a: 0, b: [{a: 0},0]}, z:[[0,0], 0], color: ["#000000", "#ffffff"], color2: "#dddddd"};
var to = {x: 10, y: {a: 20, b: [{a: 30},40]}, z:[[50,60], 70], color: ["#ffffff", "#000000"], color2: "#cccccc"};
//Flatten/Deflate an object
var flatten = function(source,pathArray,result){
pathArray = (typeof pathArray === 'undefined') ? [] : pathArray;
result = (typeof result === 'undefined') ? {} : result;
var key, value, newKey;
for (var i in source) {
if (source.hasOwnProperty(i)) {
key = i;
value = source[i];
pathArray.push(key);
if (typeof value === 'object' && value !== null){
result = flatten(value,pathArray,result);
} else {
newKey = pathArray.join('.');
result[newKey] = value;
}
pathArray.pop();
}
}
return result;
};
function ref(obj, str) {
return str.split(".").reduce(function(o, x) { return o[x] }, obj);
}
//Move values from a flatten object to its original object
function returnValue(obj, flattened, key) {
parts = key.split(/\.(?=[^.]+$)/) // Split "foo.bar.baz" into ["foo.bar", "baz"]
if (parts.length == 1) {
obj[parts[0]] = flattened[key];
} else {
ref(obj, parts[0])[parts[1]] = flattened[key];
}
}
//Convert hex to ahsv and save the keys or places
//where the original hex was
function toAhsv(obj, key, color_keys) {
if (typeof obj[key] == "string") {
if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(obj[key])) {
var t = tinycolor(obj[key])
var hsv = t.toHsv();
delete obj[key];
obj[key+".a"] = hsv.a;
obj[key+".h"] = hsv.h;
obj[key+".s"] = hsv.s;
obj[key+".v"] = hsv.v;
if (color_keys != undefined) color_keys[key] = {};
}
}
}
var flattened_from = flatten(from);
var flattened_to = flatten(to);
var color_keys = {};
for (key in flattened_from) {
toAhsv(flattened_from, key, color_keys);
}
for (key in flattened_to) {
toAhsv(flattened_to, key);
}
new TWEEN.Tween( flattened_from )
.to( flattened_to, 2000 )
.easing( TWEEN.Easing.Linear.None )
.onUpdate( function() {
//Convert ahsv to hex and set it in the this
//object under a key that refers to the colors
//place in the original object.
for (key in color_keys) {
var ahsv = {};
ahsv.a = this[key+".a"];
ahsv.h = this[key+".h"];
ahsv.s = this[key+".s"];
ahsv.v = this[key+".v"];
this[key] = tinycolor(ahsv).toHexString();
}
//Move the values from the flattened and tweening object
//to the original object
for (key in this) {
returnValue(from, this, key);
}
})
.onComplete( function () {
console.log(from) // Everything tweened correctly!
}).start();
function r(frame) {
requestAnimationFrame( r );
TWEEN.update();
}
r(); Uses code snippets from: |
@gautamadude do you have a working example of tweening colors? Would you please share it with us? |
So I have these "from" and "to" objects that I need to tween:
Tween.js doesn't handle the "y", "z" or "color" values out of the box, but would it make sense to do so? Maybe not colors, but what about objects and arrays? And perhaps even nested objects and arrays like so:
So far to deal with this I came up with the following in a hurry, and I still need to implement support for nested arrays and objects (also if you know of a better way I'd be interested):
http://jsfiddle.net/gautamadude/YRbQ3/
The reason I need this is to tween KineticJS, Two.js and Pixi.js shape attributes.
So basically, would it make sense to implement support for tweening array and object values (nested or not) in Tween.js?
The text was updated successfully, but these errors were encountered: