I am trying to animate a changing list of elements, where some disappear, some move, and some appear.
Ideal animation sequence:
The problem (bug?) is that the old elements, as they fade out, appear stacked on top of each other at the top or bottom of the list.
Can I not use animate:flip
and transition:fade
(in
/out
shorthand) at the same time?
REPL: https://svelte.dev/repl/5feb66e2ac544e10a11b98890c1b24dd?version=3.55.1
Code here for completeness:
<script>
import { flip } from 'svelte/animate'
import { fade } from 'svelte/transition'
let startInt = 0
$:items = Array(5).fill().map((x,i) => i+startInt)
function shiftDown() {
startInt = startInt + 3
}
function shiftUp() {
startInt = startInt - 3
}
</script>
<a href="#" on:click|preventDefault="{e => shiftUp()}">up</a>
{#each items as item (item)}
<div
animate:flip="{{delay: 1000, duration: 1000}}"
in:fade="{{delay: 2000, duration: 1000}}"
out:fade="{{duration: 1000}}"
>
{item}
</div>
{/each}
<a href="#" on:click|preventDefault="{e => shiftDown()}">down</a>
Wrapping the elements in a container with display: flex
seems to solve the problem
<script>
import { flip } from 'svelte/animate'
import { fade } from 'svelte/transition'
let startInt = 0
$:items = Array(5).fill().map((x,i) => i+startInt)
function shiftDown() {
startInt = startInt + 3
}
function shiftUp() {
startInt = startInt - 3
}
</script>
<button on:click={shiftUp}>up</button>
<div id="wrapper">
{#each items as item (item)}
<div
animate:flip="{{delay: 1000, duration: 1000}}"
in:fade="{{delay: 2000, duration: 1000}}"
out:fade="{{duration: 1000}}"
>
{item}
</div>
{/each}
</div>
<button on:click={shiftDown}>down</button>
<style>
#wrapper {
display: flex;
flex-direction: column;
}
</style>