hybridsjs / hybrids

Extraordinary JavaScript UI framework with unique declarative and functional architecture
https://hybrids.js.org
MIT License
3.03k stars 85 forks source link

Extension for FLIP / Miotion Animations in planning? #193

Closed dobexx closed 1 year ago

dobexx commented 2 years ago

Hello,

we are still convinced of the project and use it diligently. Recently, we finally saw an interesting solution in a similar project "Lit". There animations are cleverly implemented at transitions of the data structure and the generated HTML. The integration effort, as seen there in the Playground example, is minimal. Is something like this also to be expected for HybridsJS or to be implemented directly?

Best thanks in advance

smalluban commented 2 years ago

I'll take a look, and back with an answer :)

Currently, I am working on the built-in layout system based on something similar to the atomic CSS solutions, but implemented right in the template engine. If you are interested, please take a look here - https://github.com/hybridsjs/hybrids/pull/194. You should be able to open codesandbox (from the PR) and test it out :)

smalluban commented 2 years ago

I read linked articles. Thanks for sharing. It's an interesting feature, I'll definitely add it to my to-do list, but it might take some time, as like I wrote above, I'm currently working on something else.

However, I think you can try to implement something similar (or play with the idea) by creating a custom nested template function:

const targets = new WeakSet();
function animate(fn, options = {}) {
  return (host, target) => {
    if (!targets.has(target)) {
      fn(host, target);
      targets.add(target);
      // TODO: possible "in" animation
    } else {
      // target for the nested function is an empty Text node, so the template is appended just after this node
      const el = target.nextElementSibling;

      const first = el.getBoundingClientRect();

      // update the DOM (to get last state)
      fn(host, target);

      const last = el.getBoundingClientRect();

      // TODO: invert the props and animate
    }
  };
};

define({
  tag: "my-element",
  active: false,
  render: ({ active }) => html`
    <div>${animate(html`<span class="${ { active } }">Animating text</span>`)}</div>
  `,
}

The above animate function is a simplified version (it would break if the nested template (fn) would change, as the el reference would not be the same, etc...), but I hope you get the idea.

dobexx commented 2 years ago

Thank you for the prompt response and a first rough implementation. As soon as I get closer to it, I'll be happy to look into your feature in detail.

There's no rush, but it's good to know that this feature will eventually make its way into HybridsJS.💪

dobexx commented 1 year ago

Hi,

on the subject, I have now found an upcoming extension in the Blink Engine (Chrome, Edge, etc.) that makes this much easier.

Maybe this can be easily integrated as an opt-in?

smalluban commented 1 year ago

I knew about the Transition API, but it is still unavailable at least in Chrome. However, it's good timing, as I have a need to use that kind of animation. I will take some time on the subject to find out the best solution for now.

dobexx commented 1 year ago

Well, it can currently be enabled via this flag in the current Chrome:

It's currently behind the chrome://flags/#view-transition flag in Chrome 109+.

It will certainly be released regularly during the year. It is a wonderful opt-in. Like the Shared CSS at the time.

smalluban commented 1 year ago

Transition API landed in Chrome 111, so I've got no more excuses ;) - https://developer.chrome.com/blog/spa-view-transitions-land.

I'll try to look at this soon. The one thing that must be addressed is if this should work with some fallback to custom FLIP implementation, or just work where the API is supported (of course the latter seems to be easier to implement).

dobexx commented 1 year ago

In my humble opinion, I would only prefer the API implementation. The Blink engine has a large distribution via Chrome, Brave, Edge etc..

smalluban commented 1 year ago

@dobexx When you find some spare time, please have a look at the opened PR 😀

dobexx commented 1 year ago

Hi @smalluban,

sorry for the delay. I was only very insufficiently inside the topic. I have added a small extension to test this.

Here is the link:

https://codesandbox.io/embed/hybrids-web-components-playground-forked-u27kkz?fontsize=14&hidenavigation=1&theme=dark

When adding, the transition does not exist when removing. Where is my error in thinking?