苗条的动画 - 从键控每个块中删除项目时不需要的重叠内容

svelte animation - unwanted overlapping content when removing items from the keyed each block

我计划向现有的 svelte 应用程序添加通知,以向用户显示错误、警告和信息消息。我从一个简单的想法开始,显示一个消息框列表,可以在几秒钟后点击或消失。没问题,但是当我开始添加过渡和动画以使其看起来更令人愉悦时,我陷入了困境。这是演示该问题的简化 REPL 版本:https://svelte.dev/repl/dadfc61322b74a24ace88b368d5fdbe9?version=3.23.2

点击按钮让一些盒子出现,点击盒子然后它们被移除,当所有的都消失后,按钮又回来了。

当用户点击消息框时,页面的下部会在消息框被移除之前跳起来。当您从顶部移除框时,效果变得可见。

我想要的是页面的下部与列表元素同步向上滑动。或者,至少,在动画完成后跳起来,而不是在动画开始时跳起来。

有没有人发现我在 REPL 上犯的错误或知道如何使用 svelte 实现错误?

使用 slide 转换比使用 animate: 指令更容易实现:

import {flip} from 'svelte/animate';
import {slide} from 'svelte/transition';
<div animate:flip={{delay: 1000, duration: 500}}>
<div out:slide={{delay: 1000, duration: 500}}>
  <Message {text} on:click="{() => remove(text)}" />
</div>

请注意,这不适用于 <Message> 组件上的 margin 样式,因为边距的工作方式(如果删除通知 2,通知 1 和 3 将具有 8px它们和 2 之间的边距,直到 2 最终从 DOM 中移除,此时 1 和 3 将捕捉到彼此之间只有 8px 的边距),因此最好在 [= 周围的容器元素上使用填充15=].

此外,通过这种方法,通知在滑出之前仍然可见,这不是您想要的。你需要一个元素 inside 滑动元素变得不可见但留在 DOM 中(以保持正确的布局)直到结尾,这可以通过这样的事情来实现:

const hide = (node, { duration, delay }) => {
  return {
    duration: duration + delay,
    css: t => `opacity: 0`
  };
};
<div class="message-container" out:slide={anim_opts}>
  <div out:hide={anim_opts}>
    <Message {text} on:click="{() => remove(text)}" />
  </div>
</div>

Demo here.