improve state reset when stopping and starting a tween (fixes #512 where yoyo wouldn't restart properly)

This commit is contained in:
Joe Pea 2020-05-30 18:50:54 -07:00
parent 2d34aafa98
commit f82ee2598e
3 changed files with 122 additions and 13 deletions

View File

@ -10,6 +10,11 @@
<h1><a href="http://github.com/tweenjs/tween.js">tween.js</a></h1>
<h2>10 _ yoyo</h2>
<p>Demonstrating the yoyo() feature.</p>
<button onclick="restart()">restart</button>
<button onclick="stop()">stop</button>
<button onclick="start()">start</button>
<button onclick="pause()">pause</button>
<button onclick="resume()">resume</button>
</div>
<div style="position: absolute; top: 100px; left: 400px; ">
<div id="target1" data-rotation="0" data-y="0" class="box" style="left: 0px; top: 0px">
@ -33,6 +38,8 @@
init();
animate();
var restart, stop, start, pause, resume
function init() {
var target1 = document.getElementById( 'target1' ),
tween1 = new TWEEN.Tween( target1.dataset )
@ -78,6 +85,41 @@
updateBox( target4, object );
})
.start();
restart = function() {
tween1.stop().start()
tween2.stop().start()
tween3.stop().start()
tween4.stop().start()
}
stop = function() {
tween1.stop()
tween2.stop()
tween3.stop()
tween4.stop()
}
start = function() {
tween1.start()
tween2.start()
tween3.start()
tween4.start()
}
pause = function() {
tween1.pause()
tween2.pause()
tween3.pause()
tween4.pause()
}
resume = function() {
tween1.resume()
tween2.resume()
tween3.resume()
tween4.resume()
}
}
function animate( time ) {
@ -123,10 +165,10 @@
background: #cfc;
}
#target3 {
background: deeppink;
background: orange;
}
#target4 {
background: cyan;
background: skyblue;
}
</style>
</body>

View File

@ -124,6 +124,7 @@ TWEEN.Tween = function (object, group) {
this._valuesEnd = {};
this._valuesStartRepeat = {};
this._duration = 1000;
this._initialRepeat = 0;
this._repeat = 0;
this._repeatDelayTime = undefined;
this._yoyo = false;
@ -161,7 +162,9 @@ TWEEN.Tween.prototype = {
to: function (properties, duration) {
this._valuesEnd = Object.create(properties);
for (var prop in properties) {
this._valuesEnd[prop] = properties[prop];
}
if (duration !== undefined) {
this._duration = duration;
@ -183,6 +186,22 @@ TWEEN.Tween.prototype = {
this._group.add(this);
this._repeat = this._initialRepeat;
if (this._reversed) {
// If we were reversed (f.e. using the yoyo feature) then we need to
// flip the tween direction back to forward.
this._reversed = false;
var property;
for (property in this._valuesStartRepeat) {
this._swapEndStartRepeatValues(property);
this._valuesStart[property] = this._valuesStartRepeat[property];
}
}
this._isPlaying = true;
this._isPaused = false;
@ -196,6 +215,17 @@ TWEEN.Tween.prototype = {
for (var property in this._valuesEnd) {
// If `to()` specifies a property that doesn't exist in the source object,
// we should not set that property in the object
if (this._object[property] === undefined) {
continue;
}
// Save the starting value only once.
if (typeof(this._valuesStart[property]) !== 'undefined') {
continue;
}
// Check if an Array was provided as property value
if (this._valuesEnd[property] instanceof Array) {
@ -215,16 +245,7 @@ TWEEN.Tween.prototype = {
}
// If `to()` specifies a property that doesn't exist in the source object,
// we should not set that property in the object
if (this._object[property] === undefined) {
continue;
}
// Save the starting value, but only once.
if (typeof(this._valuesStart[property]) === 'undefined') {
this._valuesStart[property] = this._object[property];
}
this._valuesStart[property] = this._object[property];
if ((this._valuesStart[property] instanceof Array) === false) {
this._valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings
@ -331,6 +352,7 @@ TWEEN.Tween.prototype = {
repeat: function (times) {
this._initialRepeat = times;
this._repeat = times;
return this;

View File

@ -1069,6 +1069,51 @@
},
'Test yoyo can be stopped and restarted properly': function(test) {
TWEEN.removeAll();
var obj = { x: 0 },
t = new TWEEN.Tween( obj ).to( { x: 100 }, 100 ).repeat( 1 ).yoyo(true);
t.start( 0 );
TWEEN.update( 0 );
test.equal( obj.x, 0 );
TWEEN.update( 25 );
test.equal( obj.x, 25 );
TWEEN.update( 100 );
test.equal( obj.x, 100 );
TWEEN.update( 125 );
test.equal( obj.x, 75 );
t.stop();
t.start( 0 );
TWEEN.update( 0 );
test.equal( obj.x, 0 );
TWEEN.update( 25 );
test.equal( obj.x, 25 );
TWEEN.update( 100 );
test.equal( obj.x, 100 );
TWEEN.update( 125 );
test.equal( obj.x, 75 );
TWEEN.update( 200 );
test.equal( obj.x, 0 );
TWEEN.update( 225 );
test.equal( obj.x, 0 );
test.done();
},
'Test TWEEN.Tween.stopChainedTweens()': function(test) {
var t = new TWEEN.Tween( {} ),
tStarted = false,