regularjs / regular

regularjs: a living template engine that helps us to create data-driven component.
http://regularjs.github.io/
MIT License
1.06k stars 149 forks source link

Animation events on:enter and on:leave should be propagated to descendant elements #24

Open mekto opened 9 years ago

mekto commented 9 years ago

I have some issues with Regular animations. Very often the animations are not called, because the element which I want to animate is wrapped in another element, like in example below:

{#if show}
<!-- this element will be animated as expected -->
<div class="box" r-animation="on:enter;slide:in"></div>

<div>
  <!-- this element won't be animated -->
  <div class="box" r-animation="on:enter;slide:in"></div>
</div>
{/if}

I find this behavior unreliable, especially when I have some animations in components, sometimes they are fired, sometimes not. Also there are some elements you don't want to animate, like <tr> when it is shown, but you want to animate elements inside of it, but how to do this in Regular?

The similar goes to on:leave animation. Element should be removed from the DOM only when all of it's descendant elements have stopped being animated. Now it is just removed immediately.

I think that is also could be useful, although less important, to provide additional directives for on:enter and on:leave animations, some kind of shortcuts, because they are quite common. For example Ractive has intro and outro directives which are very useful and commonly used.

I would also like to mention, that the animation directive could be also used for something different than animating, eg.

<!-- in Ractive.js -->
<input type="text" intro="focus">

<!-- in Regular.js -->
<input type="text" r-animation="on:enter;focus">

which is very simple to create:

Regular.animation('focus', function(t) {
  return function(complete) {
    t.element.focus();
    complete();
  };
});

Unfortunately because of the problem with wrapping elements, this event in Regular in most cases won't be fired.

leeluolee commented 9 years ago

Now, enter, leave only fired at the first-level in the section (or component). Beacuse It is expensive to handle deep animation among all children. animation module should be rewrited to fit the advanced usage.

Before rewriting complete, There is also a trick to realize your case in current version.

  <div class='box' r-hide={test} r-animation="on: enter; class: animated bounceIn; emit: inner ;on: leave;emit:ileave; wait: 500">
    Box: <span r-animation="on:inner;class: animated swing; on:ileave;class:animated swing;">Inner</span>
</div>

see it in codepen http://codepen.io/anon/pen/raGObo

It is very dirty, but works.

regularjs's animation is designed to have the ability of creating complex animation sequence but not onlyenter and leave. Although, obviously, current version is difficult to use. I will make it better and release stable animation system before 0.3.5;

leeluolee commented 9 years ago

Maybe I need to explain it to detail.

when a group(if list, or a component) is going to destory.

  1. compute the first-level elements animation sequence
  2. unlink all children (destory directive, event or other living things), but not remove them from parent.
  3. when compelete, directly remove the first-level elements.

So, the deep element's leave animation doesn't trigger as expect