Можно ли вручную отменить и повторно запустить анимацию Svelte? - PullRequest
0 голосов
/ 03 августа 2020

У меня есть анимация, которая зависит от значения доступного для записи хранилища.

Например:

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

Проблема в том, что если значение хранилища изменяется достаточно быстро, переход не перезапускается. Вот REPL, демонстрирующий это поведение.

Я полагаю, это потому, что 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}

Есть ли более изящный способ решить эту проблему?

1 Ответ

3 голосов
/ 03 августа 2020

Вы можете использовать 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 собирает все вступления и концовки и ждет до следующего кадра, чтобы обновить представление в пакетном режиме. Если ваше состояние меняется в той же микрозадаче, то это будет go незаметно для Svelte. Вы можете использовать галочку , чтобы Svelte обновил представление в этом случае.

...