【问题标题】:Is it possible to manually cancel and retrigger a Svelte animation?是否可以手动取消和重新触发 Svelte 动画?
【发布时间】:2020-08-03 05:42:39
【问题描述】:

我有一个动画,它依赖于可写存储的值。

例如:

{#if $isWorking}
    <span in:fade="{{duration: 200, delay: 750}}">Working...</span>
{/if}

问题在于,如果 store 的值变化得足够快,则转换不会重新启动。 Here's is a REPL that demonstrates this behavior.

我想这是因为 Svelte 非常高效。我的猜测是,如果$isWorking 的值在下一帧开始时相同,Svelte 将确定它没有改变并继续进行过渡。

这似乎是一个很好的默认行为,但有没有办法避免这种情况并手动重置动画?在这种情况下,每当$isWorking 存储发生变化时重新启动延迟?

我想出了一个技巧来避免使用转换的delay 属性并使用setTimeout 自己实现它:

let show = false;
let timeout;

isWorking.subscribe((value) => {
    show = false;
    if (timeout) clearTimeout(timeout);

    timeout = setTimeout(() => {
        showState = true;
    }, 750);
});

{#if show}
    <span in:fade="{{duration: 200}}">Working</span>
{/if}

有没有更简洁的方法来解决这个问题?

【问题讨论】:

标签: javascript svelte


【解决方案1】:

您可以为此使用tick

<script>
    import { fade } from 'svelte/transition';
    import { tick } from 'svelte';
    let show = false;
    
    async function onInput () {
        show = false;
        await tick();
        show = true;
    }
</script>

<input on:input={onInput}>

{#if show}
    <span in:fade="{{duration: 200, delay: 500}}">working...</span>
{/if}

Svelte 收集所有片头和片尾,并等待下一帧以批量更新视图。如果您的状态在同一个微任务中发生变化,那么 Svelte 不会注意到它。在这种情况下,您可以使用tick 强制 Svelte 更新视图。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 2016-01-14
    • 2021-01-03
    • 1970-01-01
    相关资源
    最近更新 更多