Svelte を使用した動的な画像グリッドの構築: フリップ カード トランジションの実装

Barbara Streisand
リリース: 2024-11-25 05:20:17
オリジナル
142 人が閲覧しました

Building a dynamic image grid with Svelte: implementing flip card transitions

魅力的なユーザー インターフェイスを作成するには、多くの場合、機能と視覚的な魅力の間の微妙なバランスが必要です。この記事では、Svelte を使用して、状態を効率的に管理するだけでなく、画像の入れ替え時にスムーズで目を引く遷移を提供する動的画像グリッド コンポーネントを構築する方法を検討します。

ビジョン

画像のグリッドが定期的に更新され、個々のカードが滑らかにめくられて新しい画像が表示されることを想像してください。

これにより、チーム メンバー、製品カタログ、または一度に表示できるサイズより大きい画像のコレクションを紹介するのに最適な魅力的なディスプレイが作成されます。

これは、メンバー リストを表示する画像グリッド ウィジェット用に構築する必要があったものです。メンバーの画像は API から取得され、時間の経過とともに増加します。

これを Svelte で構築することにしたのは、なぜそうしないのですか?!

もっと真剣に考えれば、必要な量のコードにコンパイルされ、Web サイト上の占有面積が非常に小さいものが欲しかったのです。
それに基づいて、私には 2 つの選択肢がありました:

  • バニラ JavaScript でビルドします
  • 特にプロジェクトが非常に小さいことを考慮すると、非常に小さなバンドルを生成する JavaScript ライブラリを使用します。

さらに、洗練されたモデルのほうがシンプルで直感的だと思うので、特に今回のような小規模なプロジェクトでは、選択肢があればそれをデフォルトにします。

もう少し詳しく見ると、svelte を使用すると、他のソリューションと比較して、多くの小さくて複雑な状態変更の処理が非常に簡単になります (これも個人的な好みです)。
通常、物事を台無しにする方法は少なくなります。

コアコンポーネント

私たちの実装は 2 つの主要な Svelte コンポーネントで構成されています:

  1. App.svelte - グリッドを管理し、画像の交換を調整するメインコンポーネント
  2. MemberImageCard.svelte - 反転アニメーションと画像表示を処理する個別のカード

状態管理: グリッドの背後にある頭脳

ウィジェットの中心はその状態管理にあります。いくつかの情報を追跡する必要があります:

let allImages: Image[]; // All available images
let imagesToUse: Image[] = []; // Initial grid images
let imagesInUse: Image[] = []; // Current grid state
let remainingImages: Image[] = []; // Pool of unused images
let imagesSwapMap = new Map<number, Image>(); // Tracks pending swaps
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

現在の状態を個別に追跡する理由

なぜimagesToUseとは別にimagesInUseを維持するのか疑問に思われるかもしれません。この分離には、いくつかの重要な目的があります:

  1. 現在のグリッド状態の信頼できる唯一の情報源を提供します
  2. 重複した画像がグリッドに表示されるのを防ぐのに役立ちます
  3. 完全なグリッドを再レンダリングせずに効率的な更新が可能になります
  4. スワップ操作中にグリッドの整合性を維持します

スワップの振り付け: 詳細な外観

画像の交換プロセスは、グリッドの整合性を維持しながらスムーズな移行を保証する慎重に調整されたシーケンスです。 switchImages 関数を段階的に見てみましょう:

let allImages: Image[]; // All available images
let imagesToUse: Image[] = []; // Initial grid images
let imagesInUse: Image[] = []; // Current grid state
let remainingImages: Image[] = []; // Pool of unused images
let imagesSwapMap = new Map<number, Image>(); // Tracks pending swaps
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

1. プールから画像を選択する

まず、残りのプールからどの画像を交換に使用するかを決定する必要があります。

const switchImages = () => {
  let newImagesSwapMap = new Map<number, Image>()
  let remainingImagesToUse
  let newRemainingImages: Image[]
ログイン後にコピー
ログイン後にコピー

このコードは 2 つのシナリオを処理します:

  • 残りの画像が少なくなった場合は、すべて使用します
  • それ以外の場合は、プールから最後の N 枚の画像を取得します。N は NUMBER_OF_IMAGES_TO_SWITCH です。

2. グリッド位置の選択

次に、画像を交換するグリッド内の位置をランダムに選択します。

if (remainingImages.length <= NUMBER_OF_IMAGES_TO_SWITCH) {
 // If we have fewer remaining images than needed, use all of them
 remainingImagesToUse = remainingImages.slice(0);
 newRemainingImages = [];
} else {
 // Take the last N images from the remaining pool
 remainingImagesToUse = remainingImages.slice(-NUMBER_OF_IMAGES_TO_SWITCH);
 // Keep the rest for future swaps
 newRemainingImages = remainingImages.slice(0, -NUMBER_OF_IMAGES_TO_SWITCH);
}
ログイン後にコピー
ログイン後にコピー

これにより、グリッド サイズ内でランダムなインデックスの配列が作成されます。たとえば、NUMBER_OF_IMAGES_TO_SWITCH が 1、NUMBER_OF_IMAGES_TO_USE が 16 の場合、[7] が得られ、グリッドの 7 番目の位置で画像を交換することを示します。

3. 重複の防止

交換を実行する前に、新しい画像がすでに表示されているかどうかを確認します。

indexesToSwap = Array(NUMBER_OF_IMAGES_TO_SWITCH)
 .fill(null)
 .map(() => Math.floor(Math.random() * NUMBER_OF_IMAGES_TO_USE));
ログイン後にコピー
ログイン後にコピー

この機能は、グリッド内に同じ画像が複数回表示されるのを防ぎます。

4. スワップ操作

ここでコア交換ロジックを説明します:

const imageIsInUse = (image: Image) => {
 const inUse = imagesInUse.find((img: Image) => image.picture_url === img.picture_url);
 return inUse;
};
ログイン後にコピー

各スワップで何が起こるかを詳しく見てみましょう:

  1. ランダムに選択された位置 (インデックス) を取得します
  2. その位置で現在の画像を識別します (imageToSwap)
  3. プールから新しいイメージを取得します (imageToSwapWith)
  4. 新しい画像が有効でまだ表示されていない場合:
    • 画像SwapMapにスワップを記録します
    • imagesInUse のグリッドの状態を更新します
    • 最初に古いイメージをプールに追加し直します

5. 状態を完成させる

すべてのスワップを実行した後、状態を更新します。

for (let i = 0; i < indexesToSwap.length; i++) {
 let index = indexesToSwap[i];
 let imageToSwap = imagesInUse[index]; // Current image in the grid
 let imageToSwapWith = remainingImagesToUse.pop(); // New image to display

 if (imageToSwapWith && !imageIsInUse(imageToSwapWith)) {
  // Record the swap in our map
  newImagesSwapMap.set(index, imageToSwapWith);
  // Update the swap map to trigger component updates
  imagesSwapMap = newImagesSwapMap;
  // Update the grid state
  imagesInUse[index] = imageToSwapWith;
  // Add the old image back to the pool
  newRemainingImages.unshift(imageToSwap);
 } else {
  return; // Skip if the image is already in use
 }
}
ログイン後にコピー

6. アニメーションのトリガー

imageSwapMap はアニメーションをトリガーするための鍵です。更新すると、関連する MemberImageCard コンポーネントが反応します:

remainingImages = newRemainingImages;
imagesInUse = imagesInUse;
ログイン後にコピー

MemberImageCard のこのリアクティブ ステートメント:

  1. そのポジションがスワップに関与していることを検出します
  2. カードの反対側の面に新しい画像をロードします
  3. faceOnDisplay を変更することで反転アニメーションをトリガーします
  4. スムーズな遷移のために画像の読み込み状態をリセットします

このシステムの利点は、次のことを保証しながらスムーズなユーザー エクスペリエンスを維持できることです。

  • グリッドに重複した画像は表示されません
  • 画像は効率的に循環します
  • グリッドは常にその構造を維持します
  • アニメーションはスムーズかつ予測通りに実行されます
  • (重複による) 失敗したスワップは適切に処理されます

フリップ アニメーション: スムーズにする

各 MemberImageCard コンポーネントは、CSS 変換とトランジションを使用して独自の反転アニメーションを管理します。この魔法は、状態追跡と CSS の組み合わせによって起こります。

let allImages: Image[]; // All available images
let imagesToUse: Image[] = []; // Initial grid images
let imagesInUse: Image[] = []; // Current grid state
let remainingImages: Image[] = []; // Pool of unused images
let imagesSwapMap = new Map<number, Image>(); // Tracks pending swaps
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー
const switchImages = () => {
  let newImagesSwapMap = new Map<number, Image>()
  let remainingImagesToUse
  let newRemainingImages: Image[]
ログイン後にコピー
ログイン後にコピー

画像を交換する必要がある場合、次のことを行います:

  1. 裏面に新しい画像をロードします
  2. 反転アニメーションをトリガーします
  3. 反転が完了したら、古い画像をクリーンアップします

UX を向上させるプログレッシブローディング

ユーザー エクスペリエンスを向上させるために、プログレッシブ ローディング効果を実装しました。

if (remainingImages.length <= NUMBER_OF_IMAGES_TO_SWITCH) {
 // If we have fewer remaining images than needed, use all of them
 remainingImagesToUse = remainingImages.slice(0);
 newRemainingImages = [];
} else {
 // Take the last N images from the remaining pool
 remainingImagesToUse = remainingImages.slice(-NUMBER_OF_IMAGES_TO_SWITCH);
 // Keep the rest for future swaps
 newRemainingImages = remainingImages.slice(0, -NUMBER_OF_IMAGES_TO_SWITCH);
}
ログイン後にコピー
ログイン後にコピー

画像は読み込まれるとぼやけ始め、スムーズにフェードインし、洗練された外観と感触を提供します。

ダンスのスケジュールを立てる

定期的なイメージのスワップは、Svelte の onMount ライフサイクル関数を使用してスケジュールされます。

indexesToSwap = Array(NUMBER_OF_IMAGES_TO_SWITCH)
 .fill(null)
 .map(() => Math.floor(Math.random() * NUMBER_OF_IMAGES_TO_USE));
ログイン後にコピー
ログイン後にコピー

結論

この実装は、Svelte のリアクティブ機能と最新の CSS 変換を組み合わせて、動的で魅力的な UI コンポーネントを作成する能力を示しています。

以上がSvelte を使用した動的な画像グリッドの構築: フリップ カード トランジションの実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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