I’m making an animated clickable gallery using Vue 3 transition-group.
Everything works fine except there is a small jump when the gallery slide goes from one side to the other, I’ve narrowed this down to being an issue with scaling the gallery panels as vue is not accounting for the extra distance when moving the item. This can be seen in the example below.
It may seem like an insignificant issue, but it becomes quite obvious compared to the non-scaled gallery, and is very noticeable with larger items as well as transition easing.
Is there a way to fix this? I’ve tried js transition hooks as well as changing every part of the transition to no avail.
Example
Here’s an example of the problem, you can slow down the slide animation to see the jump more clearly.
2
Answers
After a lot of digging and changes, I decided to simply remove transition-group entirely and rely on classes and styling to accomplish the same effect.
There is currently no method to hook into the transition-group move transition which is what would be needed to fix this issue.
Instead the item list is not filtered and instead items are hidden or removed with css, unfortunately this adds a render overhead for very large galleries compared to a filtered array but this is not an issue for my use case
Working Example
play.vuejs example
This is related to how Vue handles the transition of scaled elements within a
<transition-group>
, which uses a "flip" technique to determine the starting and ending positions of elements and apply a "smooth" transition between them. When scaling is involved, the bounding box’s size and position change, which can throw off Vue’s internal calculations.To address this, you can try to utilize Vue’s transition hooks and some manual calculations to attempt a smoother transition. You’re mileage may vary depending, however.
beforeEnter
,enter
, andafterEnter
hooks to adjust the element’s transition.Integrate Hooks
First, you need to integrate hooks into the
ClickGallery
component. I’ll include a generalized example of this.Now, include these hooks in the
transition-group
With this approach, we’re manually determining the starting and ending positions of the element, including its scale, and applying a reverse transition at the beginning. This gives the effect of the element sliding from its starting position to its final position, but with our manual calculations accounting for the scale.
Vue’s internal mechanism might still attempt to handle the transition, so you may have to experiment a bit to get the exact effect you want. This should get you started in the right direction, however.
Hope this helps!