You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently if you want to use animation in Laminar, you can use native CSS transitions and/or Kit's Animus library.
There are two main aspects to animation when it comes to the DOM:
Smooth transitions of an element's property (e.g. width, opacity)
Smooth transitions when adding / removing elements in the DOM.
Animating individual properties is relatively easy. You can already do a lot with CSS transitions alone, but if you need custom code for one reason or another, the main challenge to implementing those in Laminar is that Airstream's transaction system is poorly suited for rapid-fire animation events. So, instead of implementing animation in terms of observables, you might want a special implementation of animations, with syntax perhaps like:
Animus has more advanced features like deriving Animatable of case classes, but that's too much for Laminar core.
Animating removal / addition of elements in the DOM is a more complex problem. Typically a dynamic list of elements is rendered from an observable of a list of models, which is then split by some id key. Well, you know how the split operator works.
So, for example, if you want to remove an element, the source observable needs to emit an updated list of models where the corresponding model is now missing. The split operator detects this change, and removes the element from the list of elements that it emits. Then Laminar's children <-- algorithm receives the new list of elements, detects the missing element, and removes it from the DOM. So, if we want to e.g. fade-out the removal of this element, it needs to be done at one of two stages:
In the split operator, or
In the children reconciliation algorithm
Either way, when removal is triggered, we need to trigger the fade-out animation, and keep the original element in the list until the animation finishes, and then remove it from the list. It gets a lot more complicated when you consider that the source observable can re-add the model corresponding to this element before it finishes animating out, etc.
Currently Animus has a custom implementation of the split operator that does this, but the split operator is perhaps the most complex / fragile code in Airstream, and maintaining a separate copy of that algorithm long term will take a lot of effort. I'm also not sure if it's entirely 100% robust, as it sort of plays fast and loose with Transactions (for the sake of performance I guess).
Without using Laminar animations or Animus, in cases where an element's removal is triggered by a user interaction, one workaround is for that interaction to trigger the fade-out animation, and then only trigger the element's removal after that is finished. But of course this is not ideal because you need to code such logic yourself, and it's not trivial to get it right.
Bottom line – it would be great to add some kind of delayed-element-removal support either to children <-- or to the Airstream split operator. Note that animated addition of elements is trivial because you can just add the element first and then animate it onMount, whereas in case of removal, you need to actually delay the removal to allow the animation to run first.
Personally I'm not a big fan of animations (that go beyond simple and quick CSS transitions) so I won't be rushing to implement any of this any time soon, but if there's enough demand for this, it can potentially be done.
The text was updated successfully, but these errors were encountered:
Currently if you want to use animation in Laminar, you can use native CSS transitions and/or Kit's Animus library.
There are two main aspects to animation when it comes to the DOM:
width
,opacity
)Animating individual properties is relatively easy. You can already do a lot with CSS transitions alone, but if you need custom code for one reason or another, the main challenge to implementing those in Laminar is that Airstream's transaction system is poorly suited for rapid-fire animation events. So, instead of implementing animation in terms of observables, you might want a special implementation of animations, with syntax perhaps like:
Animus has more advanced features like deriving Animatable of case classes, but that's too much for Laminar core.
Animating removal / addition of elements in the DOM is a more complex problem. Typically a dynamic list of elements is rendered from an observable of a list of models, which is then
split
by some id key. Well, you know how thesplit
operator works.So, for example, if you want to remove an element, the source observable needs to emit an updated list of models where the corresponding model is now missing. The split operator detects this change, and removes the element from the list of elements that it emits. Then Laminar's
children <--
algorithm receives the new list of elements, detects the missing element, and removes it from the DOM. So, if we want to e.g. fade-out the removal of this element, it needs to be done at one of two stages:split
operator, orEither way, when removal is triggered, we need to trigger the fade-out animation, and keep the original element in the list until the animation finishes, and then remove it from the list. It gets a lot more complicated when you consider that the source observable can re-add the model corresponding to this element before it finishes animating out, etc.
Currently Animus has a custom implementation of the
split
operator that does this, but thesplit
operator is perhaps the most complex / fragile code in Airstream, and maintaining a separate copy of that algorithm long term will take a lot of effort. I'm also not sure if it's entirely 100% robust, as it sort of plays fast and loose with Transactions (for the sake of performance I guess).Without using Laminar animations or Animus, in cases where an element's removal is triggered by a user interaction, one workaround is for that interaction to trigger the fade-out animation, and then only trigger the element's removal after that is finished. But of course this is not ideal because you need to code such logic yourself, and it's not trivial to get it right.
Bottom line – it would be great to add some kind of delayed-element-removal support either to
children <--
or to the Airstreamsplit
operator. Note that animated addition of elements is trivial because you can just add the element first and then animate it onMount, whereas in case of removal, you need to actually delay the removal to allow the animation to run first.Personally I'm not a big fan of animations (that go beyond simple and quick CSS transitions) so I won't be rushing to implement any of this any time soon, but if there's enough demand for this, it can potentially be done.
The text was updated successfully, but these errors were encountered: