visionmedia / move.js

CSS3 backed JavaScript animation framework
http://visionmedia.github.com/move.js/
4.72k stars 686 forks source link

Strange issue when then()-chaining nested elements #51

Open abliss opened 10 years ago

abliss commented 10 years ago

Hi,

I have discovered an issue where then()-chaining does not appear to work correctly. I am trying to chain four animations of two elements (el1 and el2), like so: A(el1) -> B(el2) -> C(el2) -> D(el1). The issue seems to appear ONLY when el2 is a descendant of el1 in the DOM (or perhaps vice versa?). When el1 and el2 are siblings in the DOM tree, it works fine.

When the issue does appear, it seems to take the form of a zero-length animation, and/or the then() callback not occurring.

I tried to create a minimal example. I was able to demonstrate the issue in the master branch, but NOT in the gh-pages branch.

To see it, load up this url: https://rawgit.com/abliss/move.js/9e0f17e8a2711cc35ce3117f8f32aa76c9d791cb/examples/docs.html and scroll down to the last example, number 13.

When the checkbox is clear, el2 is a sibling of el1, and the chain of four animations works as intended.

When the checkbox is checked, el2 is a child of el1, and the fourth animation gets skipped (i.e. has duration 0).

I suspect the issue has something to do with the transition-end callback, reset(), and inheritance -- but I'm having a hard time nailing it down exactly.

Again, using the version of build.js that's deployed in the gh-pages branch, this issue does NOT seem to appear.

Please let me know if you have any insight, or if I'm trying to do something that's not supported.

Thanks!

abliss commented 9 years ago

I can confirm that changing the = '' in reset() back to = 0 fixes the issue, which explains why I could not reproduce in the gh-pages branch. I understand that this change was made to fix something about issue #4. But it seems to me that the best way to handle issue 4 would be to (a) defer the setting of the duration property until end() is called; (b) store the existing value, and (c) restore it to its original value after the animation finishes (rather than setting it to 0 or to '').

I don't understand exactly why an empty duration causes this issue when a duration of 0 does not, but that it probably has something to do with inheritance.

If you agree with my suggestion above, let me know and I'll be happy to prepare a pull request.

Thanks!

abliss commented 9 years ago

FYI, I now believe the problem here is that the 'transitionend' event bubbles up (nobody ever calls stopPropagation), so that if a child's animation ends after a parent's animation has begun, the parent's end() callbacks will be prematurely called. I have a fix locally but it requires messing with the dependencies in a rather ugly way.

abliss commented 9 years ago

BTW should I prepare a pull request based on master or gh-pages? It seems that gh-pages hasn't been updated in a while; example 13 in the docs doesn't seem to work in master.