文字輪播與圖片輪播?CSS 不在話下

来源:https://www.cnblogs.com/coco1s/archive/2022/06/07/16350891.html
-Advertisement-
Play Games

今天,分享一個實際業務中能夠用得上的動畫技巧。 巧用逐幀動畫,配合補間動畫實現一個無限迴圈的輪播效果,像是這樣: 看到上述示意圖,有同學不禁會發問,這不是個非常簡單的位移動畫麽? 我們來簡單分析分析,從錶面上看,確實好像只有元素的 transform: translate() 在位移,但是註意,這裡 ...


今天,分享一個實際業務中能夠用得上的動畫技巧。

巧用逐幀動畫,配合補間動畫實現一個無限迴圈的輪播效果,像是這樣:

看到上述示意圖,有同學不禁會發問,這不是個非常簡單的位移動畫麽?

我們來簡單分析分析,從錶面上看,確實好像只有元素的 transform: translate() 在位移,但是註意,這裡有兩個難點:

  1. 這是個無限輪播的效果,我們的動畫需要支持任意多個元素的無限輪播切換
  2. 因為是輪播,所以,運行到最後一個的時候,需要動畫切到第一個元素

到這裡,你可以暫停思考一下,如果有 20 個元素,需要進行類似的無限輪播播報,使用 CSS 實現,你會怎麼去做呢?

逐幀動畫控制整體切換

首先,我需要利用到逐幀動畫效果,也被稱為步驟緩動函數,利用的是 animation-timing-function 中,的 steps,語法如下:

{
    /* Keyword values */
    animation-timing-function: step-start;
    animation-timing-function: step-end;
    /* Function values */
    animation-timing-function: steps(6, start)
    animation-timing-function: steps(4, end);
}

如果你對 steps 的語法還不是特別瞭解,強烈建議你先看看我的這篇文章 -- 深入淺出 CSS 動畫,它對理解本文起著至關重要的作用。

好的,還是文章以開頭的例子,假設我們存在這樣 HTML 結構:

<div class="g-container">
  <ul>
    <li>Lorem ipsum 1111111</li>
    <li>Lorem ipsum 2222222</li>
    <li>Lorem ipsum 3333333</li>
    <li>Lorem ipsum 4444444</li>
    <li>Lorem ipsum 5555555</li>
    <li>Lorem ipsum 6666666</li>
  </ul>
</div>

首先,我們實現這樣一個簡單的佈局:

在這裡,要實現輪播效果,並且是任意個數,我們可以藉助 animation-timing-function: steps()

:root {
  // 輪播的個數
  --s: 6;
  // 單個 li 容器的高度
  --h: 36;
  // 單次動畫的時長
  --speed: 1.5s;
}
.g-container {
  width: 300px;
  height: calc(var(--h) * 1px);
}
ul {
  display: flex;
  flex-direction: column;
  animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite;
}
ul li {
  width: 100%;
}
@keyframes move {
  0% {
    transform: translate(0, 0);
  }
  100% {
    transform: translate(0, calc(var(--s) * var(--h) * -1px));
  }
}

別看到上述有幾個 CSS 變數就慌了,其實很好理解:

  1. calc(var(--speed) * var(--s)):單次動畫的耗時 * 輪播的個數,也就是總動畫時長
  2. steps(var(--s)) 就是逐幀動畫的幀數,這裡也就是 steps(6),很好理解
  3. calc(var(--s) * var(--h) * -1px)) 單個 li 容器的高度 * 輪播的個數,其實就是 ul 的總體高度,用於設置逐幀動畫的終點值

上述的效果,實際如下:

如果給容器添加上 overflow: hidden,就是這樣的效果:

這樣,我們就得到了整體的結構,至少,整個效果是迴圈的。

但是由於只是逐幀動畫,所以只能看到切換,但是每一幀之間,沒有過渡動畫效果。所以,接下來,我們還得引入補間動畫。

利用補間動畫實現兩組數據間的切換

我們需要利用補間動畫,實現動態的切換效果。

這一步,其實也非常簡單,我們要做的,就是將一組數據,利用 transform,從狀態 A 位移到 狀態 B。

單獨拿出一個來演示的話,大致的代碼如下:

<div class="g-container">
  <ul style="--s: 6">
    <li>Lorem ipsum 1111111</li>
    <li>Lorem ipsum 2222222</li>
    <li>Lorem ipsum 3333333</li>
    <li>Lorem ipsum 4444444</li>
    <li>Lorem ipsum 5555555</li>
    <li>Lorem ipsum 6666666</li>
  </ul>
</div>
:root {
  --h: 36;
  --speed: 1.2s;
}
ul li {
  height: 36px;
  animation: liMove calc(var(--speed)) infinite;
}
@keyframes liMove {
  0% {
    transform: translate(0, 0);
  }
  80%,
  100%  {
    transform: translate(0, -36px);
  }
}

非常簡單的一個動畫:

基於上述效果,我們如果把一開始提到的 逐幀動畫 和這裡這個 補間動畫 結合一下,ul 的整體移動,和 li 的 單個移動疊在在一起:

:root {
  // 輪播的個數
  --s: 6;
  // 單個 li 容器的高度
  --h: 36;
  // 單次動畫的時長
  --speed: 1.5s;
}
.g-container {
  width: 300px;
  height: calc(var(--h) * 1px);
}
ul {
  display: flex;
  flex-direction: column;
  animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite;
}
ul li {
  width: 100%;
  animation: liMove calc(var(--speed)) infinite;
}
@keyframes move {
  0% {
    transform: translate(0, 0);
  }
  100% {
    transform: translate(0, calc(var(--s) * var(--h) * -1px));
  }
}
@keyframes liMove {
  0% {
    transform: translate(0, 0);
  }
  80%,
  100%  {
    transform: translate(0, calc(var(--h) * -1px));
  }
}

就能得到這樣一個效果:

Wow,神奇的化學反應產生了!基於 逐幀動畫補間動畫 的結合,我們幾乎實現了一個輪播效果。

當然,有一點瑕疵,可以看到,最後一組數據,是從第六組數據 transform 移動向了一組空數據:

末尾填充頭部第一組數據

實際開發過輪播的同學肯定知道,這裡,其實也很好處理,我們只需要在末尾,補一組頭部的第一個數據即可:

改造下我們的 HTML:

<div class="g-container">
  <ul>
    <li>Lorem ipsum 1111111</li>
    <li>Lorem ipsum 2222222</li>
    <li>Lorem ipsum 3333333</li>
    <li>Lorem ipsum 4444444</li>
    <li>Lorem ipsum 5555555</li>
    <li>Lorem ipsum 6666666</li>
    <!--末尾補一個首條數據-->
    <li>Lorem ipsum 1111111</li>
  </ul>
</div>

這樣,我們再看看效果:

Beautiful!如果你還有所疑惑,我們給容器加上 overflow: hidden,實際效果如下,通過額外添加的最後一組數據,我們的整個動畫剛好完美的銜接上,一個完美的輪播效果:

完整的代碼,你可以戳這裡:CodePen Demo -- Vertical Infinity Loop

橫向無限輪播

當然,實現了豎直方向的輪播,橫向的效果也是一樣的。

並且,我們可以通過在 HTML 結構中,通過 style 內填寫 CSS 變數值,傳入實際的 li 個數,以達到根據不同 li 個數適配不同動畫:

<div class="g-container">
  <ul style="--s: 6">
    <li>Lorem ipsum 1111111</li>
    <li>Lorem ipsum 2222222</li>
    <li>Lorem ipsum 3333333</li>
    <li>Lorem ipsum 4444444</li>
    <li>Lorem ipsum 5555555</li>
    <li>Lorem ipsum 6666666</li>
    <!--末尾補一個首尾數據-->
    <li>Lorem ipsum 1111111</li>
  </ul>
</div>

整個動畫的 CSS 代碼基本是一致的,我們只需要改變兩個動畫的 transform 值,從豎直位移,改成水平位移即可:

:root {
  --w: 300;
  --speed: 1.5s;
}
.g-container {
  width: calc(--w * 1px);
  overflow: hidden;
}
ul {
  display: flex;
  flex-wrap: nowrap;
   animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite;
}
ul li {
  flex-shrink: 0;
  width: 100%;
  height: 100%;
  animation: liMove calc(var(--speed)) infinite;
}
@keyframes move {
  0% {
    transform: translate(0, 0);
  }
  100% {
    transform: translate(calc(var(--s) * var(--w) * -1px), 0);
  }
}
@keyframes liMove {
  0% {
    transform: translate(0, 0);
  }
  80%,
  100%  {
    transform: translate(calc(var(--w) * -1px), 0);
  }
}

這樣,我們就輕鬆的轉化為了橫向的效果:

完整的代碼,你可以戳這裡:CodePen Demo -- Horizontal Infinity Loop

輪播圖?不在話下

OK,上面的只是文字版的輪播,那如果是圖片呢?

沒問題,方法都是一樣的。基於上述的代碼,我們可以輕鬆地將它修改一下後得到圖片版的輪播效果。

代碼都是一樣的,就不再列出來,直接看看效果:

完整的代碼,你可以戳這裡:CodePen Demo -- Horizontal Image Infinity Loop

掌握了這個技巧之後,你可以將它運用在非常多只需要簡化版的輪播效果之上。

再簡單總結一下,非常有意思的技巧:

  1. 利用 逐幀動畫,實現整體的輪播的迴圈效果
  2. 利用 補間動畫,實現具體的 *狀態A狀態B 的動畫效果
  3. 逐幀動畫 配合 補間動畫 構成整體輪播的效果
  4. 通過向 HTML 結構末尾補充一組頭部數據,實現整體動畫的銜接
  5. 通過 HTML 元素的 style 標簽,利用 CSS 變數,填入實際的參與迴圈的 DOM 個數,可以實現 JavaScript 與 CSS 的打通

最後

OK,本文到此結束,希望本文對你有所幫助

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.前言 hi,大家好,我是三合,距離上一篇博客已經過去了整整兩年,這兩年裡,博主通關了《人生》這個游戲里的兩大關卡,買房和結婚。最近閑了下來,那麼當然要繼續寫博客了,今天這篇博客的主要內容是,net core/.net6中,如何利用SummerBoot(點我打開詳情介紹)中的feign模塊快速接入 ...
  • 鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站 在CentOS中使用yum命令出現報錯: 今天想給linux裝個git 管理代碼 執行命令: 1 yum -y install git 然後出現了這麼一句 error:There are no enabled repositories in "/ ...
  • 鏡像下載、功能變數名稱解析、時間同步請點擊 阿裡雲開源鏡像站 一、鏡像 鏡像是一種輕量級、可執行的獨立軟體包,它包含運行某個軟體所需的所有內容,我們把應用程式和配置依賴打包形成一個可交付的運行環境(包括代碼、運行時需要的庫、環境變數和配置文件等),這個打包好的運行環境就是image鏡像文件 1.鏡像分層 以 ...
  • 一、基本說明 • Oracle 中的函數可以返回表類型,但是這個表類型實際上是集合類型(與數組類似)。從 Oracle 9i 開始,提供了一個叫做"管道化表函數"來解決此問題。 • 管道化表函數,必須返回一個集合類型,且標明 pipelined。它不能返回具體變數,必須以一個空 return 返回, ...
  • 1、Spark Catalyst擴展點 Spark catalyst的擴展點在SPARK-18127中被引入,Spark用戶可以在SQL處理的各個階段擴展自定義實現,非常強大高效,是SparkSQL的核心組件(查詢優化器),它負責將SQL語句轉換成物理執行計劃,Catalyst的優劣決定了SQL執行 ...
  • 隨著電子產品的普遍應用,AR技術也開始廣泛普及,在游戲、電商、家裝等領域都有涉及。比如,在室內設計時,我們可以通過AR技術在實際場景中進行虛擬軟裝的搭配,運用華為AR Engine運動跟蹤能力在實際應用中實時輸出室內環境的三維坐標信息,確定現實室內環境和虛擬軟裝之間的變換關係,從而穩定精準的實現軟裝 ...
  • 近年來,以機器學習為代表的人工智慧技術(以下簡稱AI技術)蓬勃發展。新演算法層出不窮,開發出的圖像識別、自然語言、活體檢測等能力令智能化的未來生活不再遙不可及。同時,這些AI技術正持續演化和發展,數據和算力的限制也在被不斷突破。依托層出不窮的新技術和新產品,交通出行、購物快遞、金融理財等各類與用戶生活 ...
  • Vue Echare 圖表 的基本使用 Apache ECharts 一個基於 JavaScript 的開源可視化圖表庫 npm install echarts vue-echartsnpm i -D @vue/composition-api 在main.js 當中(全局引用) import ech ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...