8

私は Svelte が大好きですが、基本的なもの (表面的なものにすぎません) にこだわっています。次のコードは 2 つの要素間をスムーズに遷移するはずですが、代わりに「ジャンプ」します。つまり、到着する前に着信要素のためのスペースを作っているようです。

この問題は、Rich Harris が数年前に指摘したものと似ていますが、解決策が実装されたようには見えません。Svelte チュートリアル サイトのすべての例は、単一の要素のみを移行します。

基本的なマークアップ/コードは次のとおりです。

{#if div1}
    <div 
      in:fly={{ x: 100, duration: 400, delay: 400 }}
      out:fly={{ x: 100, duration: 400 }}>Div 1</div>
{:else}
    <div 
      in:fly={{ x: 100, duration: 400, delay: 400 }}
      out:fly={{ x: 100, duration: 400 }}>Div 2</div>
{/if}

<button on:click={()=>{ div1 = !div1}}>Switch</button>

Vue での同等の機能は次のようになります。

<transition name="fly" mode="out-in">
    <div v-if="div1">Div 1</div>
    <div v-else>Div 2</div>
</transition>

コード サンドボックスの例を次に示します。ボタンが下にジャンプして、新しい要素のためのスペースを空けることがわかります。400 の持続時間に等しい「イン」トランジション遅延を追加しました (これがデフォルトであることはわかっていますが、わかりやすくするために明示的に設定したかったのです)。遅延は、最初のリンク (Harris が「遅延のハッキーな使用」と呼んだもの) に記載されているように、最初の要素が次の要素を移行する前に移行できるようにする必要があります

また、outro'd される要素を position: absolute に明示的に設定して、スペースを占有しないようにしました。以下は (まだ正しく動作していない) 例です。機能していたとしても、少しエレガントではないようです。何らかの理由で、トランジションが position:absolute を設定するクラスの設定をオーバーライドしています。

どんな助けでも大歓迎です!

更新:このコードで目的の効果が得られました。ここで行ったのは、Svelte のフライ トランジションをコピーして変更し、追加のパラメーター (「位置」) を取得することでした。これは、「絶対」または「相対」など、必要に応じて設定できます。奇妙な副作用 (コンテナを position: relative に設定し、各要素の幅を 100% に設定してサイズが変わらないようにする) がないように、CSS を微調整します。これは機能しますが、Svelte のトランジションを変更せずに、労働集約的ではない方法が必要であると私は感じています。

4

2 に答える 2

5

スワップする状態が 3 つ以上ある場合は、動作をカスタム ストアに抽象化すると非常に役立ちます。ストアは次のようになります。

statefulSwap(initialState) {
    const state = writable(initialState);
    let nextState = initialState;
    
    function transitionTo(newState) {
        if(nextState === newState) return;
        nextState = newState
        state.set(null)
    }
    
    function onOutro() {
        state.set(nextState)
    }
    return {
        state,
        transitionTo,
        onOutro
    }
}

条件付きブロックを使用して要素を交換できます。

{#if $state == "first"}
    <h1 transition:fade on:outroend={onOutro}>
        First
</h1>
{:else if $state == "second"}
    <h1 transition:fade on:outroend={onOutro}>
        Second
</h1>
{/if}

この手法は、最初に現在の状態を に設定し、最初の要素が遷移した後に新しい状態を適用することでout-in、Vue の動作をエミュレートします。nullonOutro

以下はREPLの例です。ここでの利点は、スワップ ロジックを追跡しなくても、さまざまなアニメーション アクションとタイミングで必要な数の状態を設定できることです。elseただし、条件付きマークアップに既定のブロックがある場合、これは機能しません。

于 2020-12-06T19:00:17.673 に答える