Open NoelDeMartin opened 3 days ago
Thank you very much for this! I have reproduced this issue in the example.
hero-motion
implements transitions for size changes using scaling caused this error, and I have looked at the code in MorphAnimation
, and If my understanding is incorrect, please let me know.
Vivant
seems using querySelector
to and [layout-id]
attribute to filter the child doms under target element, and do the reverse animation for every children.
I'm not sure if I fully understand the implementation of the code, but it still very helpful for me, and I will try to use this approach in hero-motion
Yes, Vivant uses [layout-id]
to look for children that are in both layouts when "morphing". But it looks at the children automatically when the layout changes. I make a distinction between "morphing" (one element turning into another) and "layout animations" (one element changing some properties) because the implementations are different. I think in Framer Motion they call them "Shared Layout Animations" and "Layout Animations".
In any case, these are implementation details, you could choose to do it differently in your library :). The important part is that during the animation, children distortion is corrected. I learned a lot about this in this article, so check it out to understand how this works: Inside Framer's Magic Motion
Wow! This article looks great.
I am facing the issues related to Scale Timing, and it addresses those problems very well.
Thank you so much for your help!
Yes, one of the reasons why I'm implementing this "manually" (updating the styles myself, rather than using vueuse/motion to transition the transforms) is that the inverse doesn't use the same animation curve. It would be nice to use the library for this, but I'm not sure it's possible without a lot of headaches :(. That's why I ended up doing some workaround to animate custom properties here: https://github.com/NoelDeMartin/vivant/blob/main/packages/vivant/src/lib/animate-styles.ts
This seems to be because vueuse/motion
does not expose methods like onUpdate
or a reactive transform property, so we have to manually bind it through watch and define a custom motion instance.
Thank you very much for the implementation you provided; it helped me a lot.
And I need to think about how to achieve a similar effect in hero-motion
I tried using MutationObserver
to watch for style changes on the target element and manually bind 1/scale
to the children. This seems to work and avoids using CustomMotionInstance
(but I'm not sure if this is a good way and if there are any performance issues).
If you're interested, my implementation can be found here:
https://github.com/tmg0/hero-motion/blob/main/packages/core/src/composables/use-style.ts
Thank you very much for the help and suggestions.
I mentioned in https://github.com/vueuse/motion/issues/226 that I've been working on a library to implement layout animations, and @tmg0 asked for some reproduction of what is missing in Hero Motion.
I think there are 2 things missing from Hero Motion at the moment, but they are related so I think we can use this issue to track both. Basically, it has to do with doing scale correction in children elements, and orchestrating nested animations. I have some examples of how this works in my library in this playground: https://noeldemartin.github.io/vivant/ (in particular, the examples talking about "scale correction" and "nested animations").
I could reproduce the scale correction problem in the Hero Motion example replacing the box in the "Toggle Size Animation" example with this:
In particular, this is equivalent to this example in Vivant: https://noeldemartin.github.io/vivant/morphing-with-scale-correction
I also used tailwind for my UI, so it should be easy to implement the other examples in Hero Motion if you want to reproduce more examples (the most notable being https://noeldemartin.github.io/vivant/morphing-with-nested-animations).
I don't think this is easy to implement, and this is why I say that my library is just a "proof of concept" at the moment, because I'm sure there are many edge cases I haven't taken care of. But in case you're interested, the core of how I implement layout animations can be found in these files: