anime
anime copied to clipboard
Complete callback only fires once in looping timeline (v3.0.1)
Describe the bug
The complete
callback function is only firing the first time when used within a single animation in a looping timeline.
To Reproduce
https://codepen.io/anon/pen/GLrdMb -- using animejs version 3.0.1
Expected behavior
I would expect that the complete
event would fire every time the given animation completes, and not just the first time it is completed within a looping timeline.
Additional context I did a quick search to see if this was already a documented issue, but only came across one potential mention of it, without a demo or steps to reproduce: #521
Anxious to know if this is expected behavior, and if so, if there are any workarounds to achieve what I'm after.
I am also experiencing this, let me add to that it only happens to the last piece in the timeline. Every other complete callbacks in the other pieces of the timeline works. Also it does not happen in the first time it only happens when animation is played more than once. For knowing if the timeline as a whole has completed, we may need to use in the meantime https://animejs.com/documentation/#finishedPromise
I have run into this issue also. As interim solution, the following approaches seem to work pretty reliably for me, although YMMV.
https://codepen.io/anon/pen/zXmJNV (I've modified your codepen to show examples)
1st example: Non-timeline anime
instance - use loopComplete callback that will fire on every loop.
2nd example: "Simple" timeline instance with only one animation, or callback firing at the end of multiple animations (when the timeline loops) - uses parameter inheritance to fire on each loop.
3rd example: "Complex" timeline, with keyframed animations with callback firing after each specific animation - use changeComplete (could add changeBegin to multiple animations at different points within timeline to fire different callbacks.
My workaround:
const timeline = anime.timeline({
easing: "linear",
duration: duration,
loop,
loopComplete: () => {
for (let i = 0; i < timeline.children.length; i += 1) {
timeline.children[i].completed = false;
timeline.children[i].began = false;
}
}
});
Now begin
and complete
are fired in each loop.
For a particular use case where looping isn't important and you're performing a timeline sequence based animation, just comment out the loop prop and the complete function will execute.
@QuincyHe workaround does not work for me. Has anyone else found any other workaround?
A small modification to @QuincyHe workaround.
const timeline = anime.timeline({
easing: "linear",
duration: duration,
loop,
loopComplete: () => {
for (let i = 0; i < timeline.children.length; i += 1) {
timeline.children[i].completed = false;
timeline.children[i].began = false;
timeline.children[i].currentTime=0;
}
}
});