无法使用 `svelte/animate` 使列表项飞入 header
Can't use `svelte/animate` to make a list item fly into a header
我正在尝试获得 material 设计风格的东西,其中位置名称会飞入 header。看来 Svelte 想不通这两个东西是有联系的。
演示:https://svelte.dev/repl/865750b1ffb642f59d317747bd9f3534?version=3.4.4
基本上,我试图让它工作的方法是有一个像这样的位置列表:
{#each visibleLocations as location (location.id)}
<div
on:click={() => (selectedLocation = location)}
class="location"
animate:flip
out:send={{ key: location.id }}
in:receive={{ key: selectedLocation.id }}>
<div class="name"> {location.name} </div>
</div>
{/each}
然后我有 header 看起来像这样。请注意,我必须将它包装在每个块中才能让编译器让我这样做。自然这让我觉得我做错了什么
{#each selectedLocaitonList as chosenLocaiton (chosenLocaiton.id)}
<div
class="header"
animate:flip
in:send={{ key: chosenLocaiton.id }}
out:receive={{ key: chosenLocaiton.id }}>
{#if chosenLocaiton.id}
<button on:click={() => (selectedLocation = { id: null })}>◀️</button>
{chosenLocaiton.name}
{:else}Pick a Location near you{/if}
</div>
{/each}
也许是因为 selectedLocation 没有被认为是同一回事?我不确定它是如何计算出来的,我希望它会通过 ID。
事实证明,如果我交换 out
和 in
,它就会按预期工作。不知道这是为什么,所以需要一个更好的答案。
in
应始终与 receive
配对,out
应始终与 send
配对; in:send
总是会给出奇怪的结果。这里的位置也不匹配:
out:send={{ key: location.id }}
in:receive={{ key: selectedLocation.id }}
它们必须相同。
animate
指令用于重新排序列表 中的项目 — 因为在这种情况下,第一个列表总是从 [x]
到 [y]
而第二个总是从 []
到 [x, y, z]
没有共同的元素可以设置动画,所以它不是使用该指令的正确位置。
当使用 crossfade
时,sent/received 元素应该具有相同的尺寸,并且理想情况下应该在彼此重叠时看起来不错(即在相对于元素边界框的相同位置键入, ETC)。在这里,<button>
元素使事物的大小不同。
换句话说,有点像这样:https://svelte.dev/repl/f4386ec88df34e3b9a6b513e19374824?version=3.4.4
不幸的是,仍然存在一些视觉故障 — 因为我们使用比例变换作为后备,layout 没有过渡,这意味着外边框卡入和错位而不是平滑地调整大小。我们可以改用 slide
过渡,但是滑动元素和交叉渐变元素似乎会相互绊倒。在任何一种情况下,DOM 中似乎都有一个幻影元素,扰乱了布局。在没有进一步调查的情况下,我不确定这是否是一个 Svelte 错误(如果是,是否可以修复),所以我提出了一个问题:https://github.com/sveltejs/svelte/issues/2957
我正在尝试获得 material 设计风格的东西,其中位置名称会飞入 header。看来 Svelte 想不通这两个东西是有联系的。
演示:https://svelte.dev/repl/865750b1ffb642f59d317747bd9f3534?version=3.4.4
基本上,我试图让它工作的方法是有一个像这样的位置列表:
{#each visibleLocations as location (location.id)}
<div
on:click={() => (selectedLocation = location)}
class="location"
animate:flip
out:send={{ key: location.id }}
in:receive={{ key: selectedLocation.id }}>
<div class="name"> {location.name} </div>
</div>
{/each}
然后我有 header 看起来像这样。请注意,我必须将它包装在每个块中才能让编译器让我这样做。自然这让我觉得我做错了什么
{#each selectedLocaitonList as chosenLocaiton (chosenLocaiton.id)}
<div
class="header"
animate:flip
in:send={{ key: chosenLocaiton.id }}
out:receive={{ key: chosenLocaiton.id }}>
{#if chosenLocaiton.id}
<button on:click={() => (selectedLocation = { id: null })}>◀️</button>
{chosenLocaiton.name}
{:else}Pick a Location near you{/if}
</div>
{/each}
也许是因为 selectedLocation 没有被认为是同一回事?我不确定它是如何计算出来的,我希望它会通过 ID。
事实证明,如果我交换 out
和 in
,它就会按预期工作。不知道这是为什么,所以需要一个更好的答案。
in
应始终与 receive
配对,out
应始终与 send
配对; in:send
总是会给出奇怪的结果。这里的位置也不匹配:
out:send={{ key: location.id }}
in:receive={{ key: selectedLocation.id }}
它们必须相同。
animate
指令用于重新排序列表 中的项目 — 因为在这种情况下,第一个列表总是从 [x]
到 [y]
而第二个总是从 []
到 [x, y, z]
没有共同的元素可以设置动画,所以它不是使用该指令的正确位置。
当使用 crossfade
时,sent/received 元素应该具有相同的尺寸,并且理想情况下应该在彼此重叠时看起来不错(即在相对于元素边界框的相同位置键入, ETC)。在这里,<button>
元素使事物的大小不同。
换句话说,有点像这样:https://svelte.dev/repl/f4386ec88df34e3b9a6b513e19374824?version=3.4.4
不幸的是,仍然存在一些视觉故障 — 因为我们使用比例变换作为后备,layout 没有过渡,这意味着外边框卡入和错位而不是平滑地调整大小。我们可以改用 slide
过渡,但是滑动元素和交叉渐变元素似乎会相互绊倒。在任何一种情况下,DOM 中似乎都有一个幻影元素,扰乱了布局。在没有进一步调查的情况下,我不确定这是否是一个 Svelte 错误(如果是,是否可以修复),所以我提出了一个问题:https://github.com/sveltejs/svelte/issues/2957