精简列表交叉淡入淡出随机错放元素

问题描述 投票:0回答:1

我有一个列表,我想要设置动画,以便当选择一个项目时,它会浮到顶部,其余的会飞出。重新选择元素时,它会浮回其位置,而其他元素会飞回。

使用这个 crossfade 演示我能够制作一个非常可靠的版本:

REPL

但是,我注意到元素有时不会返回到原始位置,只有随后的重新动画才能修复它。我很确定这是因为我的交叉淡入淡出功能需要更复杂的处理(或者我应该只使用常规过渡?),但我不确定具体如何。

<script>
  import { flip } from 'svelte/animate'
  import { writable } from 'svelte/store'
  import { crossfade, fly } from 'svelte/transition'

  const ACTIONS = [
    { key: 'blue' },
    { key: 'green' },
    { key: 'yellow' },
    { key: 'purple' },
    { key: 'orange' },
    { key: 'red' },
  ]
  const selectedAction = writable(null)
  let shownActions = ACTIONS.map(a => a)

  const [send, receive] = crossfade({
    fallback(node, _params) {
      return fly(node, { x: -800, duration: 600 })
    }
  })

  function selectAction(action) {
    if ($selectedAction === action) {
      shownActions = ACTIONS.map(a => a)
      selectedAction.update(v => {
        if (v === action || action === undefined) {
          return null
        } else {
          return action
        }
      })
    } else {
      shownActions = ACTIONS.filter(a => a.key === action)
      selectedAction.update(v => {
        if (v === action || action === undefined) {
          return null
        } else {
          return action
        }
      })
      window.scrollTo({
        top: 0,
        behavior: 'smooth'
      })
    }
  }
</script>

<ul>
{#each shownActions as action (action)}
  <li
    class={`${$$props.class || ''}`}
    animate:flip={{ duration: 600 }}
    in:receive={{ key: action.key }}
    out:send={{ key: action.key }}
  >
    <button on:click={e => selectAction(action.key)}>{action.key}</button>
  </li>
{/each}
</ul>

<style lang="scss">
    ul {
        list-style: none;
    }
    li {
        display: flex;
        margin-bottom: 1rem;
    }
    button {
        margin-right: 1rem;
        padding: 0.5rem 1rem;
    }
</style>
javascript animation svelte
1个回答
0
投票

看起来当您在动画结束之前单击时会出现此问题。您可以使用过渡事件等待动画结束。但过渡期间元素的位置也存在问题。当使用子

div
旁边的
li
元素时,我得到了更好的结果:

{#each shownActions as action (action)}
  <li>
        <div
            class={`${$$props.class || ''}`}
            in:receive={{ key: action.key }}
            out:send={{ key: action.key }}
        >
            <button on:click={e => selectAction(action.key)}>{action.key}</button>
        </div>
  </li>
{/each}
© www.soinside.com 2019 - 2024. All rights reserved.