使用 Svelte 建立動態影像網格:實現翻轉卡過渡
創造引人入勝的使用者介面通常需要在功能和視覺吸引力之間取得微妙的平衡。在本文中,我們將探索如何使用 Svelte 建立動態影像網格元件,該元件不僅可以有效管理狀態,而且可以在影像換入和換出時提供平滑、引人注目的過渡。
願景
想像一個定期刷新自身的影像網格,各個卡片平滑地翻轉以顯示新影像。
這創建了一個引人入勝的顯示,非常適合展示團隊成員、產品目錄或任何大於一次顯示的圖像集合。
這就是我必須為顯示成員列表的圖像網格小部件構建的內容。會員圖像來自 API,並隨著時間的推移而增長。
我決定用 Svelte 建造這個,因為為什麼不呢? !
更認真地說,我想要的東西將被編譯為所需的必要程式碼量,並且在網站上佔用的空間非常小。
基於此,我有兩個選擇:
- 使用 vanilla javascript 建構它
- 使用一個 javascript 函式庫,它將產生一個非常小的包,特別是考慮到該專案也非常小。
此外,我發現 svelte 模型更簡單、更直觀,因此如果有選擇,尤其是在像這樣的小項目上,我將預設使用它。
正如您進一步看到的那樣,與其他解決方案相比,svelte 使得處理許多小而複雜的狀態變化變得非常簡單(同樣,個人品味)。
通常,把事情搞砸的方法會更少。
核心組件
我們的實作由兩個主要的 Svelte 元件組成:
- App.svelte - 管理網格和協調影像交換的主要元件
- 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
為什麼要單獨追蹤當前狀態?
您可能想知道為什麼我們將 imagesInUse 與 imagesToUse 分開維護。這種分離有幾個重要目的:
- 它為目前網格狀態提供單一事實來源
- 它有助於防止重複的圖像出現在網格中
- 它可以實現高效更新,無需完全網格重新渲染
- 它在交換操作期間保持網格完整性
交換編排:詳細觀察
影像交換過程是一個精心策劃的序列,可確保平滑過渡,同時保持網格完整性。讓我們一步步分解 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[]
此程式碼處理兩種情況:
- 如果剩餘影像不足,我們會使用所有影像
- 否則,我們從池中取得最後 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; };
讓我們分解一下每次交換中會發生什麼:
- 我們得到隨機選擇的位置(索引)
- 我們辨識該位置的目前影像(imageToSwap)
- 我們從池中取得新映像 (imageToSwapWith)
- 如果新圖像有效且尚未顯示:
- 我們將交換記錄在imagesSwapMap中
- 我們更新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. 觸發動畫
imagesSwapMap是觸發動畫的關鍵。當它更新時,相關的 MemberImageCard 組件會做出反應:
remainingImages = newRemainingImages; imagesInUse = imagesInUse;
MemberImageCard 中的此反應語句:
- 偵測其位置何時涉及交換
- 在卡片的反面載入新圖片
- 透過改變faceOnDisplay觸發翻轉動畫
- 重置影像載入狀態以實現平滑過渡
這個系統的美妙之處在於它保持流暢的使用者體驗,同時確保:
- 網格中沒有出現重複的影像
- 影像高效循環
- 網格始終保持其結構
- 動畫順利且可預測地發生
- 失敗的交換(由於重複)會被妥善處理
翻轉動畫:使其平滑
每個 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[]
當影像需要交換時,我們:
- 在反面載入新圖片
- 觸發翻轉動畫
- 翻轉完成後清理舊影像
漸進式載入以獲得更好的用戶體驗
為了增強使用者體驗,我們實現了漸進式載入效果:
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中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。
