I have a large list that I'm introducing velocity-animate into. At the moment, my test list has 59 individual items that a user can filter by search query (potentially could grow to hundreds of items). I am animating currently according to the way the Vue docs show it being done, but of course their list only has a few items.
In my app, it takes several seconds for the animation to finish which is definitely not ideal. Is there any way of "batch" animating? I think ideally what would happen is I would debounce the input so that only after a second or two, will the search actually perform. Then in the method, the items are filtered, and all of the items that aren't a match disappear. How can I accomplish this?
<template>
<v-text-field
background-color="#fff"
clearable
dense
flat
hide-details
label="Search"
placeholder="Search"
solo-inverted
:value="searchQuery"
@click:append="clearSearch"
@input="debounceSearchQuery" />
<v-list>
<v-list-item-group>
<draggable
class="drag-area list-group"
:group="{ name: 'items', pull: 'clone', put: false}"
handle=".gear-handle"
:list="filteredItems"
:sort="false"
@change="log">
<transition-group
:css="false"
name="staggered-fade"
@before-enter="beforeEnter"
@enter="enter"
@leave="leave">
<v-list-item
v-for="(item, i) in filteredItems"
:key="item.id"
:data-index="i">
<p class="mb-0 white--text">
{{ item.name }}
</p>
</v-list-item>
</transition-group>
</draggable>
</v-list-item-group>
</v-list>
</template>
export default {
data: () => ({
searchQuery: ''
}),
computed: {
filteredItems () {
const filteredItems = [];
this.categories.forEach(category => {
if (this.searchQuery) {
const text = this.searchQuery.toLowerCase();
filteredItems.push(category.items.filter(item => item.name && item.name.toLowerCase().includes(text)));
} else {
filteredItems.push(category.items);
}
});
return filteredItems.flat();
},
},
methods: {
// gsap methods //
beforeEnter (el) {
el.style.opacity = 0;
el.style.height = 0;
},
enter (el, done) {
const delay = el.dataset.index * 150;
setTimeout(() => {
this.$velocity(
el,
{ opacity: 1, height: '1.6em', duration: 50 },
[0.57, 0.06, 0, 1.06],
{ complete: done }
);
}, delay);
},
leave (el, done) {
const delay = el.dataset.index * 150;
setTimeout(() => {
this.$velocity(
el,
{ opacity: 0, height: 0 },
{ complete: done }
);
}, delay);
},
// end gsap methods
debounceSearchQuery: debounce(function (e) {
this.searchQuery = e;
}, 1000)
}
}
I think "staggering" animation and "batch" running transitions are more like two different things—it's almost like you can't have your cake and eat it too.
Nonetheless, if you are simply after smooth, sliding transitions that kind of have staggering effect, you could actually do that with
<transition-group>+ CSS only (no transition hooks necessary). Here's a quick example (click "Run" and then "Full-page" for better view):Another recommendation would be Velocity UI pack. This add-on allows you to do sequence running and it comes with some pre-registered effects, which are great for staggering effects. (Check out the docs for more transition effects).