Skip to content

Commit 20079e6

Browse files
authored
Merge pull request #693 from hoonsbory/groupComplete
feature: implement group-level onComplete callback
2 parents 6536e9d + 8743ea8 commit 20079e6

File tree

8 files changed

+146
-0
lines changed

8 files changed

+146
-0
lines changed

dist/tween.amd.js

+16
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,19 @@ define(['exports'], (function (exports) { 'use strict';
302302
tweenIds = Object.keys(this._tweensAddedDuringUpdate);
303303
}
304304
};
305+
Group.prototype.onComplete = function (callback) {
306+
var group = this.getAll();
307+
group.forEach(function (tween) {
308+
var prevCallback = tween.getCompleteCallback();
309+
tween.onComplete(function () {
310+
prevCallback === null || prevCallback === void 0 ? void 0 : prevCallback(tween);
311+
// After the onComplete callback completes, _isPlaying is updated to false, so if the total number of completed tweens is -1, then they are all complete.
312+
var completedGroup = group.filter(function (tween) { return !tween.isPlaying(); });
313+
if (completedGroup.length === group.length - 1)
314+
callback(group);
315+
});
316+
});
317+
};
305318
return Group;
306319
}());
307320

@@ -448,6 +461,9 @@ define(['exports'], (function (exports) { 'use strict';
448461
Tween.prototype.getId = function () {
449462
return this._id;
450463
};
464+
Tween.prototype.getCompleteCallback = function () {
465+
return this._onCompleteCallback;
466+
};
451467
Tween.prototype.isPlaying = function () {
452468
return this._isPlaying;
453469
};

dist/tween.cjs

+16
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,19 @@ var Group = /** @class */ (function () {
304304
tweenIds = Object.keys(this._tweensAddedDuringUpdate);
305305
}
306306
};
307+
Group.prototype.onComplete = function (callback) {
308+
var group = this.getAll();
309+
group.forEach(function (tween) {
310+
var prevCallback = tween.getCompleteCallback();
311+
tween.onComplete(function () {
312+
prevCallback === null || prevCallback === void 0 ? void 0 : prevCallback(tween);
313+
// After the onComplete callback completes, _isPlaying is updated to false, so if the total number of completed tweens is -1, then they are all complete.
314+
var completedGroup = group.filter(function (tween) { return !tween.isPlaying(); });
315+
if (completedGroup.length === group.length - 1)
316+
callback(group);
317+
});
318+
});
319+
};
307320
return Group;
308321
}());
309322

@@ -450,6 +463,9 @@ var Tween = /** @class */ (function () {
450463
Tween.prototype.getId = function () {
451464
return this._id;
452465
};
466+
Tween.prototype.getCompleteCallback = function () {
467+
return this._onCompleteCallback;
468+
};
453469
Tween.prototype.isPlaying = function () {
454470
return this._isPlaying;
455471
};

dist/tween.d.ts

+2
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ declare class Tween<T extends UnknownProps = any> {
9898
*/
9999
constructor(object: T, group: true);
100100
getId(): number;
101+
getCompleteCallback(): ((object: T) => void) | undefined;
101102
isPlaying(): boolean;
102103
isPaused(): boolean;
103104
getDuration(): number;
@@ -181,6 +182,7 @@ declare class Group {
181182
* tweens, and do not rely on tweens being automatically added or removed.
182183
*/
183184
update(time?: number, preserve?: boolean): void;
185+
onComplete(callback: (object: Tween[]) => void): void;
184186
}
185187

186188
declare const now: () => number;

dist/tween.esm.js

+16
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,19 @@ var Group = /** @class */ (function () {
300300
tweenIds = Object.keys(this._tweensAddedDuringUpdate);
301301
}
302302
};
303+
Group.prototype.onComplete = function (callback) {
304+
var group = this.getAll();
305+
group.forEach(function (tween) {
306+
var prevCallback = tween.getCompleteCallback();
307+
tween.onComplete(function () {
308+
prevCallback === null || prevCallback === void 0 ? void 0 : prevCallback(tween);
309+
// After the onComplete callback completes, _isPlaying is updated to false, so if the total number of completed tweens is -1, then they are all complete.
310+
var completedGroup = group.filter(function (tween) { return !tween.isPlaying(); });
311+
if (completedGroup.length === group.length - 1)
312+
callback(group);
313+
});
314+
});
315+
};
303316
return Group;
304317
}());
305318

@@ -446,6 +459,9 @@ var Tween = /** @class */ (function () {
446459
Tween.prototype.getId = function () {
447460
return this._id;
448461
};
462+
Tween.prototype.getCompleteCallback = function () {
463+
return this._onCompleteCallback;
464+
};
449465
Tween.prototype.isPlaying = function () {
450466
return this._isPlaying;
451467
};

dist/tween.umd.js

+16
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,19 @@
306306
tweenIds = Object.keys(this._tweensAddedDuringUpdate);
307307
}
308308
};
309+
Group.prototype.onComplete = function (callback) {
310+
var group = this.getAll();
311+
group.forEach(function (tween) {
312+
var prevCallback = tween.getCompleteCallback();
313+
tween.onComplete(function () {
314+
prevCallback === null || prevCallback === void 0 ? void 0 : prevCallback(tween);
315+
// After the onComplete callback completes, _isPlaying is updated to false, so if the total number of completed tweens is -1, then they are all complete.
316+
var completedGroup = group.filter(function (tween) { return !tween.isPlaying(); });
317+
if (completedGroup.length === group.length - 1)
318+
callback(group);
319+
});
320+
});
321+
};
309322
return Group;
310323
}());
311324

@@ -452,6 +465,9 @@
452465
Tween.prototype.getId = function () {
453466
return this._id;
454467
};
468+
Tween.prototype.getCompleteCallback = function () {
469+
return this._onCompleteCallback;
470+
};
455471
Tween.prototype.isPlaying = function () {
456472
return this._isPlaying;
457473
};

src/Group.ts

+12
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,16 @@ export default class Group {
8484
tweenIds = Object.keys(this._tweensAddedDuringUpdate)
8585
}
8686
}
87+
onComplete(callback: (object: Tween[]) => void) {
88+
const group = this.getAll()
89+
group.forEach(tween => {
90+
const prevCallback = tween.getCompleteCallback()
91+
tween.onComplete(() => {
92+
prevCallback?.(tween)
93+
// After the onComplete callback completes, _isPlaying is updated to false, so if the total number of completed tweens is -1, then they are all complete.
94+
const completedGroup = group.filter(tween => !tween.isPlaying())
95+
if (completedGroup.length === group.length - 1) callback(group)
96+
})
97+
})
98+
}
8799
}

src/Tween.ts

+4
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ export class Tween<T extends UnknownProps = any> {
8383
return this._id
8484
}
8585

86+
getCompleteCallback(): ((object: T) => void) | undefined {
87+
return this._onCompleteCallback
88+
}
89+
8690
isPlaying(): boolean {
8791
return this._isPlaying
8892
}

src/tests.ts

+64
Original file line numberDiff line numberDiff line change
@@ -2060,6 +2060,70 @@ export const tests = {
20602060
test.ok(group.getAll() instanceof Array)
20612061
test.done()
20622062
},
2063+
'Custom group.onComplete() should be triggered when all Tweens in the group have reached their completion, and the child Tween.onComplete() should also be fired'(
2064+
test: Test,
2065+
): void {
2066+
TWEEN.removeAll()
2067+
2068+
const t = new TWEEN.Tween({x: 1}),
2069+
t2 = new TWEEN.Tween({x: 1}),
2070+
t3 = new TWEEN.Tween({x: 1}),
2071+
group = new TWEEN.Group()
2072+
let groupCounter = 0,
2073+
childCounter = 0,
2074+
childCounter2 = 0,
2075+
childCounter3 = 0
2076+
2077+
group.add(t)
2078+
group.add(t2)
2079+
group.add(t3)
2080+
2081+
t.to({x: 2}, 1000)
2082+
t2.to({x: 2}, 2000)
2083+
t3.to({x: 2}, 3000)
2084+
2085+
t.onComplete(function (): void {
2086+
childCounter++
2087+
})
2088+
t2.onComplete(function (): void {
2089+
childCounter2++
2090+
})
2091+
t3.onComplete(function (): void {
2092+
childCounter3++
2093+
})
2094+
group.onComplete(function (): void {
2095+
groupCounter++
2096+
})
2097+
2098+
t.start(0)
2099+
t2.start(0)
2100+
t3.start(0)
2101+
2102+
group.update(0)
2103+
test.deepEqual(groupCounter, 0)
2104+
test.deepEqual(childCounter, 0)
2105+
test.deepEqual(childCounter2, 0)
2106+
test.deepEqual(childCounter3, 0)
2107+
2108+
group.update(1000)
2109+
test.deepEqual(groupCounter, 0)
2110+
test.deepEqual(childCounter, 1)
2111+
test.deepEqual(childCounter2, 0)
2112+
test.deepEqual(childCounter3, 0)
2113+
2114+
group.update(2000)
2115+
test.deepEqual(childCounter, 1)
2116+
test.deepEqual(groupCounter, 0)
2117+
test.deepEqual(childCounter2, 1)
2118+
test.deepEqual(childCounter3, 0)
2119+
2120+
group.update(3000)
2121+
test.deepEqual(groupCounter, 1)
2122+
test.deepEqual(childCounter, 1)
2123+
test.deepEqual(childCounter2, 1)
2124+
test.deepEqual(childCounter3, 1)
2125+
test.done()
2126+
},
20632127

20642128
'Custom group stores tweens instead of global TWEEN group'(test: Test): void {
20652129
const group = new TWEEN.Group()

0 commit comments

Comments
 (0)