Die Erstellung ansprechender Benutzeroberflächen erfordert oft ein empfindliches Gleichgewicht zwischen Funktionalität und optischer Attraktivität. In diesem Artikel erfahren Sie, wie Sie mit Svelte eine dynamische Bildrasterkomponente erstellen, die nicht nur den Status effizient verwaltet, sondern auch reibungslose, auffällige Übergänge beim Ein- und Auswechseln von Bildern bietet.
Stellen Sie sich ein Bildraster vor, das sich regelmäßig aktualisiert, wobei einzelne Karten sanft umgedreht werden, um neue Bilder freizulegen.
Dadurch entsteht eine ansprechende Anzeige, die sich perfekt für die Präsentation von Teammitgliedern, Produktkatalogen oder einer beliebigen Bildersammlung eignet, die größer ist als das, was auf einmal angezeigt werden kann.
Das musste ich für ein Bildraster-Widget erstellen, das eine Mitgliederliste anzeigt. Die Bilder der Mitglieder stammen von einer API und wachsen mit der Zeit.
Ich habe beschlossen, dies mit Svelte zu bauen, denn warum nicht?!
Im Ernst, ich wollte etwas, das genau so viel Code kompiliert, wie nötig, und nur einen sehr geringen Platzbedarf auf der Website hat.
Basierend darauf hatte ich zwei Möglichkeiten:
Außerdem finde ich das schlanke Modell einfacher und intuitiver. Wenn ich also die Wahl habe, insbesondere bei einem kleinen Projekt wie diesem, werde ich standardmäßig darauf zurückgreifen.
Wie Sie etwas weiter unten sehen werden, macht Svelte den Umgang mit vielen kleinen und komplizierten Zustandsänderungen im Vergleich zu anderen Lösungen (wiederum persönlicher Geschmack) wirklich einfacher.
Normalerweise gibt es weniger Möglichkeiten, Dinge durcheinander zu bringen.
Unsere Implementierung besteht aus zwei Hauptkomponenten von Svelte:
Das Herzstück unseres Widgets liegt in seiner Statusverwaltung. Wir müssen mehrere Informationen verfolgen:
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
Sie fragen sich vielleicht, warum wir imagesInUse getrennt von imagesToUse verwalten. Diese Trennung dient mehreren entscheidenden Zwecken:
Der Bildaustauschprozess ist eine sorgfältig orchestrierte Sequenz, die reibungslose Übergänge gewährleistet und gleichzeitig die Rasterintegrität beibehält. Lassen Sie uns die Funktion „switchImages“ Schritt für Schritt aufschlüsseln:
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
Zuerst müssen wir bestimmen, welche Bilder aus unserem verbleibenden Pool zum Austausch verwendet werden:
const switchImages = () => { let newImagesSwapMap = new Map<number, Image>() let remainingImagesToUse let newRemainingImages: Image[]
Dieser Code behandelt zwei Szenarien:
Als nächstes wählen wir zufällig Positionen im Raster aus, an denen wir Bilder austauschen:
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); }
Dadurch wird ein Array zufälliger Indizes innerhalb unserer Rastergröße erstellt. Wenn beispielsweise NUMBER_OF_IMAGES_TO_SWITCH 1 und NUMBER_OF_IMAGES_TO_USE 16 ist, erhalten wir möglicherweise [7], was bedeutet, dass wir das Bild an Position 7 im Raster austauschen.
Bevor wir einen Austausch durchführen, prüfen wir, ob das neue Bild bereits angezeigt wird:
indexesToSwap = Array(NUMBER_OF_IMAGES_TO_SWITCH) .fill(null) .map(() => Math.floor(Math.random() * NUMBER_OF_IMAGES_TO_USE));
Diese Funktion verhindert, dass dasselbe Bild mehrmals in unserem Raster erscheint.
Jetzt kommt die grundlegende Austauschlogik:
const imageIsInUse = (image: Image) => { const inUse = imagesInUse.find((img: Image) => image.picture_url === img.picture_url); return inUse; };
Lassen Sie uns zusammenfassen, was bei jedem Tausch passiert:
Nachdem wir alle Tauschvorgänge durchgeführt haben, aktualisieren wir unseren Status:
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 } }
Die imagesSwapMap ist der Schlüssel zum Auslösen von Animationen. Bei der Aktualisierung reagieren die relevanten MemberImageCard-Komponenten:
remainingImages = newRemainingImages; imagesInUse = imagesInUse;
Diese reaktive Aussage in MemberImageCard:
Das Schöne an diesem System ist, dass es ein reibungsloses Benutzererlebnis gewährleistet und gleichzeitig Folgendes gewährleistet:
Jede MemberImageCard-Komponente verwaltet ihre eigene Flip-Animation mithilfe von CSS-Transformationen und -Übergängen. Die Magie geschieht durch eine Kombination aus Statusverfolgung und 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[]
Wenn ein Bild ausgetauscht werden muss, tun wir Folgendes:
Um das Benutzererlebnis zu verbessern, haben wir einen progressiven Ladeeffekt implementiert:
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); }
Bilder beginnen unscharf und werden nach dem Laden sanft eingeblendet, was für ein ausgefeiltes Erscheinungsbild sorgt.
Der regelmäßige Bildaustausch wird mithilfe der onMount-Lebenszyklusfunktion von Svelte geplant:
indexesToSwap = Array(NUMBER_OF_IMAGES_TO_SWITCH) .fill(null) .map(() => Math.floor(Math.random() * NUMBER_OF_IMAGES_TO_USE));
Diese Implementierung demonstriert die Leistungsfähigkeit der reaktiven Fähigkeiten von Svelte in Kombination mit modernen CSS-Transformationen, um eine dynamische, ansprechende UI-Komponente zu erstellen.
Das obige ist der detaillierte Inhalt vonErstellen eines dynamischen Bildrasters mit Svelte: Implementierung von Flip-Card-Übergängen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!