ホームページ > ウェブフロントエンド > CSSチュートリアル > XSTATEとSvelteアニメーションを調整します

XSTATEとSvelteアニメーションを調整します

Lisa Kudrow
リリース: 2025-03-25 09:35:14
オリジナル
317 人が閲覧しました

XSTATEとSvelteアニメーションを調整します

この投稿は、Svelteプロジェクトで使用される可能性のあるXSTATEの紹介です。 XSTATEは、JavaScriptエコシステムでユニークです。 DOMはアプリケーションの状態と同期し続けることはありませんが、有限状態マシン(FSM)としてモデル化できるようにすることで、アプリケーションの状態を管理するのに役立ちます。

州の機械や正式な言語に深く掘り下げられているのは、この投稿の範囲を超えていますが、ジョン・ベラは別のCSS-Tricksの記事でそれを行います。とりあえず、FSMをフローチャートと考えてください。フローチャートには、バブルとして表される多くの状態と、ある状態から次の状態への矢印があり、ある状態から次の状態への移行を意味します。州のマシンには、州からつながる複数の矢印がある場合、または最終的な状態であれば、まったくありません。また、状態を離れて、同じ状態に戻る矢印さえあります。

すべてが圧倒的に聞こえる場合は、リラックスしてください。すべての詳細を説明します。今のところ、高レベルの見解は、アプリケーションを状態マシンとしてモデル化すると、アプリケーションが存在する可能性があるさまざまな「状態」を作成することです(取得…状態マシン…状態?)、および発生して状態の変化を引き起こすイベントはそれらの状態間の矢印になります。 XSTATEは、州を「州」と呼び、州間の矢印を「行動」と呼びます。

私たちの例

XSTATEには学習曲線があり、それが教えるのが難しいです。不自然なユースケースがあまりにも複雑に見えます。 XSTATEが輝くのは、アプリケーションのコードが少しもつれたときだけです。これは、それについて書くことが難しくなります。とはいえ、私たちが見る例は、オートコンプリートウィジェット(AutoSuggestと呼ばれることもあります)、またはクリックすると、選択するアイテムのリストを表示する入力ボックスです。

この投稿では、アニメーションコードのクリーンアップを確認します。これが出発点です:

これは私のSvelte-Helpersライブラリの実際のコードですが、この投稿では不必要なピースが削除されています。入力をクリックしてアイテムをフィルタリングすることはできますが、アイテム、ホバーなどを介して「矢印」を選択することはできません。この投稿とは無関係なすべてのコードを削除しました。

アイテムのリストのアニメーションを検討します。入力をクリックし、結果リストの最初のレンダリングをクリックすると、アニメーション化します。入力してフィルタリングすると、リストの寸法を変更すると、大きくて小さくなります。入力が焦点を失ったり、ESCをクリックしたりすると、リストの高さをゼロにアニメーション化し、フェードアウトしてからDOMから削除します(以前ではありません)。物事をより面白くするため(そしてユーザーにとっては素晴らしい)、閉鎖に使用するものとは異なるスプリング構成を開口部に使用してみましょう。そのため、リストはもう少し速く、または硬く閉じます。

なぜSvelte Transitionを使用してAnimationをDOMの内外で管理していないのか疑問に思っている場合、それは、ユーザーがフィルターをフィルターし、トランジション間を調整するためにリストのディメンションをアニメーション化しているからです。また、通常のSpringアニメーションと通常のSpringアニメーションは、Spring Updateを待つよりもはるかに難しくなります。たとえば、ユーザーがリストをすばやく入力してフィルターしている場合、アニメーション化されている場合はどうなりますか?ご覧のとおり、XSTATEはこのようなトリッキーな状態移行を簡単にします。

問題のスコーピング

これまでの例のコードを見てみましょう。リストが開いているときに制御するオープン変数と、それがDOMにあるべきかどうかを制御するためのResultSlistVisibleプロパティがあります。また、リストが閉鎖のプロセスにあるかどうかを制御する閉鎖変数もあります。

28行目には、入力がクリックまたは焦点を合わせたときに実行される入力メソッドがあります。とりあえず、それがオープンに設定し、trueに結果を出すことができることに注意してみましょう。 InputChangedは、ユーザーが入力を入力したときに呼び出され、Trueに開かれます。これは、入力が集中している場合、ユーザーはエスケープをクリックして閉じますが、タイピングを開始するため、再開できます。そして、もちろん、inputblurred関数は予想されるときに実行され、閉じてTrueに設定し、Falseに開かれます。

この絡み合った混乱を引き出して、アニメーションがどのように機能するかを見てみましょう。上部にあるスライディンスプリングと不透明度に注意してください。前者はリストを上下にスライドさせ、ユーザーのタイプとしてサイズを調整します。後者は、隠されたときにリストをフェードアウトします。主にSlideinspringに焦点を当てます。

SetSpringDimensionsと呼ばれる関数の怪物を見てください。これにより、スライドスプリングが更新されます。重要な部分に焦点を当てて、いくつかのブール特性を取ります。リストが開いている場合、spring configを設定すると、{hard:true} configを介して、リストの幅をすぐに設定します(リストを下にスライドさせ、下にスライドさせます)。高さを設定します。閉じた場合、アニメーション化され、アニメーションが完了すると、結果をfalseにリストに導くことができます(クロージングアニメーションが中断された場合、Svelteは約束を解決しないように賢くなり、コールバックが実行されないようにします)。最後に、この方法は、結果のサイズが変更されたとき、つまりユーザーがフィルターとして変更されるときはいつでも呼び出されます。これを管理するために、他の場所にResizeObserverを設定します。

Spaghetti Galore

このコードを取り上げましょう。

  • リストが開いているかどうかを追跡するオープン変数があります。
  • リストがDOMにある必要があるかどうかを追跡するResultsListVisible変数があります(そして、クローズアニメーションが完了した後にfalseに設定されています)。
  • リストがクロージングのプロセスにある場合に追跡するクロージング変数があります。これは、入力フォーカス/クリックハンドラーで確認して、閉じる前にユーザーがウィジェットをすばやく再エンゲージする場合に閉じるアニメーションを逆にすることができます。
  • また、4つの異なる場所で呼び出すSetSpringDimensionsもあります。リストの開閉、閉鎖、または開いている間にサイズを変更しているかどうかに応じて、スプリングを設定します(つまり、ユーザーがリストをフィルターする場合)。
  • 最後に、結果のdom要素がレンダリングされたときに実行されるsvelteアクションの結果としてリースレンダーがあります。それは私たちのResizeObserverを起動し、DOMノードがアンマウントを外したとき、閉じてfalseに設定します。

バグをキャッチしましたか? ESCボタンが押されたとき、私はfalseにオープンのみを設定します。閉鎖を真に設定し、SetSpringDimensions(False、True)に電話するのを忘れました。このバグは、このブログ投稿で意図的に考案されていませんでした!これは、このウィジェットのアニメーションをオーバーホールしていたときに犯した実際の間違いです。入力のコードをコピーして、エスケープボタンがキャッチされている場所にコピーをコピーしたり、新しい関数に移動して両方の場所から呼び出すこともできます。このバグは根本的に解決するのは難しくありませんが、コードの認知負荷が増加します。

私たちが追跡していることはたくさんありますが、最悪なことに、この状態はモジュール全体に散らばっています。上記の任意の状態を取り、CodeSandboxのFind機能を使用して、その状態が使用されているすべての場所を表示します。ファイル全体でカーソルが跳ね返るのがわかります。今、あなたがこのコードを理解しようとしていると想像してください。あなたが追跡しなければならないこれらすべての州の精神モデルの成長を考えて、それが存在するすべての場所に基づいてそれがどのように機能するかを理解してください。私たちは皆そこにいました。それは吸う。 XSTATEはより良い方法を提供します。方法を見てみましょう。

XSTATEの紹介

少し後退しましょう。ユーザーが対話するときにイベントが発生し、副作用が発生し、新しい状態に移行するという点で、どのような状態にあるかという点でウィジェットをモデル化する方が簡単ではないでしょうか?もちろん、それは私たちがすでにやっていたことです。問題は、コードがどこにでも散らばっていることです。 XSTATEは、このように状態を適切にモデル化する能力を提供します。

期待を設定します

XSTATEが私たちのすべての複雑さを魔法のように消滅させることを期待しないでください。まだスプリングを調整し、開閉状態と閉鎖状態に基づいてスプリングの構成を調整し、サイズを処理するなどを処理する必要があります。XSTATEが提供するのは、この状態管理コードを簡単に推論し、調整する方法で集中化することができることです。実際、州全体のマシンのセットアップの結果として、全体的なラインカウントが少し増加します。見てみましょう。

あなたの最初の状態マシン

すぐに飛び込んで、裸の骨のマシンがどのように見えるか見てみましょう。 XSTATEのFSMパッケージを使用しています。これは、XSTATEの最小限の削除バージョンで、1kbの小さなバンドルサイズで、ライブラリ(AutoSuggestウィジェットなど)に最適です。完全なXSTATEパッケージのような高度な機能はあまりありませんが、ユースケースには必要ありません。このような紹介の投稿を望んでいません。

州のマシンのコードは以下にあり、インタラクティブなデモはコードサンドボックスで終わりました。たくさんありますが、まもなくそれを調べます。明確にするために、まだ機能していません。

 const statemachine = createmachine(
  {
    初期:「初期」、
    コンテクスト: {
      open:false、
      ノード:null
    }、
    州:{
      イニシャル: {
        オン:{open: "open"}
      }、
      開ける: {
        の上: {
          レンダリング:{アクション: "レンダリング"}、
          sizeize:{action: "resize"}、
          閉じる:「閉鎖」
        }、
        エントリ:「オープン」
      }、
      閉鎖:{
        の上: {
          open:{ターゲット: "open"、action:["resize"]}、
          閉鎖:「閉じた」
        }、
        エントリ:「閉じる」
      }、
      閉じた:{
        の上: {
          オープン:「オープン」
        }、
        エントリ:「閉じ」
      }
    }
  }、
  {
    アクション:{
      オープン:assign(context => {
        return {... context、open:true};
      })、
      レンダリング:assign((context、evt)=> {
        const {node} = evt;
        {... context、node}を返します。
      })、
      近い() {}、
      resize(context){}、
      閉じた:assign(()=> {
        return {open:false、node:null};
      })
    }
  }
);
ログイン後にコピー

上から下へ行きましょう。初期プロパティは、初期状態が何であるかを制御します。これは「初期」と呼ばれています。コンテキストは、状態マシンに関連付けられたデータです。結果リストが現在開いているかどうか、および同じ結果リストのノードオブジェクトについてブール値を保存しています。次に、私たちの州を見ます。各州は州の財産の鍵です。ほとんどの州では、私たちには財産とエントリープロパティがあることがわかります。

イベントの構成で。各イベントについて、新しい状態に移行できます。アクションと呼ばれる副作用を実行できます。または両方。たとえば、初期状態の内部でオープンイベントが発生すると、オープン状態に移動します。レンダリングされたイベントがオープン状態で発生したら、レンダリングされたアクションを実行します。また、オープンイベントがクロージング状態内で発生すると、オープン状態に移行し、サイズ変更アクションも実行します。ほとんどの州で見られるエントリフィールドは、状態が入力されるたびに自動的に実行するアクションを構成します。ここでは必要ありませんが、出口アクションもあります。

まだカバーするものがいくつかあります。州のマシンのデータ、またはコンテキストがどのように変更されるかを見てみましょう。アクションがコンテキストを変更したい場合は、アクションでそれを包み込み、アクションから新しいコンテキストを返します。処理が必要ない場合は、新しい状態を直接渡すだけで割り当てることができます。アクションがコンテキストを更新しない場合、つまり、副作用のためだけのものである場合、アクション関数を割り当てず、必要な副作用を実行するだけです。

州のマシンの変化に影響を与えます

ステートマシン用のクールなモデルがありますが、どのように実行しますか?解釈関数を使用します。

 const statemachineservice = reluttion(statemachine).start();
ログイン後にコピー

現在、StateMachineserviceはランニングステートマシンであり、その上でイベントを呼び出して移行とアクションを強制することができます。イベントを発射するには、Sendを呼び出し、イベント名を渡し、その後、オプションでイベントオブジェクトを渡します。たとえば、結果リストが最初にDOMにマウントされたときに実行されるSvelteアクションでは、これがあります。

 statemachineservice.send({type: "rendered"、node});
ログイン後にコピー

これが、レンダリングされたアクションが結果リストのノードを取得する方法です。 AutoComplete.svelteファイルの残りの部分を見回すと、すべてのアドホック状態管理コードがシングルラインイベントディスパッチに置き換えられます。入力クリック/フォーカスのイベントハンドラーでは、オープンイベントを実行します。 ResizeObserverがサイズ変更イベントを発射します。等々。

しばらく一時停止し、XSTATEがここで無料で提供するものに感謝します。 XSTATEを追加する前に、入力がクリックまたは焦点を合わせたときに実行されるハンドラーを見てみましょう。

関数extengaged(evt){
  if(閉じる){
    SetSpringDimensions();
  }
  open = true;
  resultsListVisible = true;
}
ログイン後にコピー

以前は、閉店しているかどうかを確認し、もしそうなら、スライドスプリングの再計算を強制していました。それ以外の場合は、ウィジェットを開きました。しかし、入力が既に開いているときに入力をクリックした場合はどうなりましたか?同じコードを再ランします。幸いなことに、それは本当に重要ではありませんでした。 Svelteは、オープンし、すでに保有している価値に登録​​できない場合に再設定しても気にしません。しかし、これらの懸念はXSTATEで消えます。新しいバージョンは次のようになります:

関数extengaged(evt){
  statemachineservice.send( "open");
}
ログイン後にコピー

州のマシンがすでにオープン状態にあり、オープンイベントを発射する場合、その状態で構成されているオープンイベントがないため、何も起こりません。そして、結果が閉じているときに入力がクリックされたときの特別な取り扱い?これは、State Machine Configでも処理されます。オープンイベントが、閉鎖状態から実行されたときに、サイズ変更アクションにどのようにタックするかに注意してください。

そして、もちろん、ESCキーバグを以前から修正しました。さて、キーを押すと、単に緊密なイベントを発射するだけです。それはそれです。

仕上げます

エンディングはほぼ抗climacticです。以前に行っていたすべての作業を受けて、それを私たちの行動の中で正しい場所に移動する必要があります。 XSTATEは、コードを書く必要性を削除しません。それは、それを置くための構造化された明確な場所を提供するだけです。

 {
  アクション:{
    オープン:assign({open:true})、
    レンダリング:assign((context、evt)=> {
      const {node} = evt;
      const dimensions = getResultSlistDimensions(node);
      itemsheightobserver.observe(node);
      OpacitySpring.set(1、{hard:true});
      Object.Assign(SlideInspring、Slide_open);
      slideinspring.update(prev =>({... prev、width:dimensions.width})、{
        ハード:本当
      });
      slideinspring.set(dimensions、{hard:false});
      {... context、node}を返します。
    })、
    近い() {
      OpacitySpring.set(0);
      Object.Assign(SlideInspring、Slide_Close);
      Slideinspring
        .update(prev =>({... prev、height:0}))
        .then(()=> {
          statemachineservice.send( "閉じた");
        });
    }、
    resize(context){
      OpacitySpring.set(1);
      slideinspring.set(getResultSlistDimensions(context.node));
    }、
    閉じた:assign(()=> {
      itemsheightobserver.unobserve(resultlist);
      return {open:false、node:null};
    })
  }
}
ログイン後にコピー

オッズと終わり

私たちのアニメーション状態は私たちの州のマシンにありますが、どうすればそれを取り出すのですか?結果リストのレンダリングを制御するにはオープン状態が必要です。このデモでは使用されていませんが、このAutoSuggestウィジェットの実際のバージョンには、現在強調表示されているアイテムを視界にスクロールするなどの結果リストDOMノードが必要です。

Statemachineserviceには、状態の変更があるたびに発射する購読方法があることがわかりました。渡すコールバックは、コンテキストオブジェクトを含む現在の状態マシン状態で呼び出されます。しかし、Svelteにはその袖に特別なトリックがあります。$の反応的な構文:コンポーネント変数やSvelteストアだけでは機能しません。また、購読メソッドを備えた任意のオブジェクトでも動作します。つまり、これほど単純なものと州のマシンと同期することができます。

 $:({open、node:resultlist} = $ statemachineservice.context);
ログイン後にコピー

定期的な破壊で、物事が正しく解析されるのを助けるためのいくつかのパレンズがあります。

改善の領域として、ここで1つの簡単なメモ。現在、どちらも副作用を実行し、状態を更新するアクションがいくつかあります。理想的には、おそらくこれらを2つのアクションに分割する必要があります。1つは副作用のためだけに、もう1つは新しい状態の割り当てを使用する必要があります。しかし、私はこの記事がXSTATEの導入を容易にするのに役立つように、この記事のためにできるだけシンプルに保つことにしました。

これがデモです

別れの考え

この投稿がXSTATEへの関心を引き起こしたことを願っています。複雑な状態を管理するための非常に便利で使いやすいツールであることがわかりました。表面を傷つけただけだと知ってください。最小限のFSMパッケージに焦点を当てましたが、XSTATEライブラリ全体は、ネストされた状態から約束のためのファーストクラスのサポートまで、ここでカバーしているものよりもはるかに多くのことができます。チェックアウトすることをお勧めします。

ハッピーコーディング!

以上がXSTATEとSvelteアニメーションを調整しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
関連するチュートリアル
人気のおすすめ
最新のコース
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート