TweenMax doesn't allow you to tween 2 or more properties at once in Three.js on the same tween. For example you can't tween rotation
and position
at once. You can only tween the rotation
in one tween or the position
but not both.
I've managed to do it by pushing 2 tweens in an array and calling tl.insertMultiple(array)
.
Unfortunately, for some unknown to me reason, it only plays fine the first time. After restart()
, the tween/timeline is broken/stutters/skips.
Notice when the color changes to red it's no longer smooth animation.
/* TWEENMAX ANIMATION STARTS HERE
p = position
r = rotation
t = time
*/
var miroKeyframes = JSON.parse(`[
{"t":"0"},
{"p":{"x":"0.050","y":"0.220"},"r":{"x":"0.246","y":"-0.444","z":"0.014"},"t":"0.29"},
{"p":{"x":"0.010","y":"0.060"},"r":{"x":"0.109","y":"-0.150","z":"0.150"},"t":"1.01"},
{"p":{"x":"0.746","y":"0.738"},"r":{"x":"0.109","y":"-0.050","z":"0.013"},"t":"1.67"},
{"p":{"x":"-0.495","y":"0.804"},"r":{"x":"0.097","y":"-0.040","z":"0.105"},"t":"2.63"},
...
]`);
// Setup a timeline object. Restart on complete.
var tl = new TimelineMax({ onComplete:restart }),
tweens = [];
for (var i = 1; i < miroKeyframes.length ; i++) {
var keyframe = miroKeyframes[i]; //current keyframe
var dur = keyframe.t - miroKeyframes[i-1].t ; //auto-duration
tweens.push( TweenMax.to( obj.rotation, dur, { x:keyframe.r.x, y:keyframe.r.y, z:keyframe.r.z, delay:keyframe.t, ease:Sine.easeIn} ));
tweens.push( TweenMax.to( obj.position, dur, { x:keyframe.p.x*20, y:keyframe.p.y*20, delay:keyframe.t, ease:Sine.easeIn} ));
//Works with either one of these but not both. It will execute each consequently. I need both at the same time.
//tl.add( TweenMax.to( obj.position, dur, { x:keyframe.p.x, y:keyframe.p.y, ease:Sine.easeIn } ));
//tl.add( TweenMax.to( obj.rotation, dur, { x:keyframe.p.x, y:keyframe.p.y, ease:Sine.easeIn } ));
}
tl.insertMultiple(tweens);
Please let me know how to fix this and what's going on. I don't want to use 2 objects - 1 for rotation and 1 for position.
The solution came from the GSAP forums by PointC and Dipscom. Special thanks!
The first and easier solution is to use labels or position parameters
. Check the video tutorial.
tl.to( obj.position, dur, { x:keyframe.p.x*10, y:keyframe.p.y*10, ease:Sine.easeIn }, "label" + i );
tl.to( obj.rotation, dur, { x:keyframe.r.x, y:keyframe.r.y, ease:Sine.easeIn }, "label" + i );
The second solution is to use 2 timelines - 1 main time line and 1 mini-timeline to add both properties at the same time:
tl2.to( obj.rotation, dur, { x:keyframe.r.x, y:keyframe.r.y, z:keyframe.r.z, ease:Sine.easeIn}, 0 );
tl2.to( obj.position, dur, { x:keyframe.p.x*20, y:keyframe.p.y*20, ease:Sine.easeIn}, 0);
tl.add(tl2);
Hope this helps.