<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          精妙的配合!文字輪播與圖片輪播?CSS 不在話下

          共 9079字,需瀏覽 19分鐘

           ·

          2023-01-12 19:49

          今天,分享一個(gè)實(shí)際業(yè)務(wù)中能夠用得上的動(dòng)畫(huà)技巧。

          巧用逐幀動(dòng)畫(huà),配合補(bǔ)間動(dòng)畫(huà)實(shí)現(xiàn)一個(gè)無(wú)限循環(huán)的輪播效果,像是這樣:

          看到上述示意圖,有同學(xué)不禁會(huì)發(fā)問(wèn),這不是個(gè)非常簡(jiǎn)單的位移動(dòng)畫(huà)么?

          我們來(lái)簡(jiǎn)單分析分析,從表面上看,確實(shí)好像只有元素的 transform: translate() 在位移,但是注意,這里有兩個(gè)難點(diǎn):

          1. 這是個(gè)無(wú)限輪播的效果,我們的動(dòng)畫(huà)需要支持任意多個(gè)元素的無(wú)限輪播切換
          2. 因?yàn)槭禽啿ィ?,運(yùn)行到最后一個(gè)的時(shí)候,需要?jiǎng)赢?huà)切到第一個(gè)元素

          到這里,你可以暫停思考一下,如果有 20 個(gè)元素,需要進(jìn)行類(lèi)似的無(wú)限輪播播報(bào),使用 CSS 實(shí)現(xiàn),你會(huì)怎么去做呢?

          逐幀動(dòng)畫(huà)控制整體切換

          首先,我需要利用到逐幀動(dòng)畫(huà)效果,也被稱(chēng)為步驟緩動(dòng)函數(shù),利用的是 animation-timing-function 中,的 steps,語(yǔ)法如下:

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

          如果你對(duì) steps 的語(yǔ)法還不是特別了解,強(qiáng)烈建議你先看看我的這篇文章 -- 深入淺出 CSS 動(dòng)畫(huà)[1],它對(duì)理解本文起著至關(guān)重要的作用。

          好的,還是文章以開(kāi)頭的例子,假設(shè)我們存在這樣 HTML 結(jié)構(gòu):

          <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>

          首先,我們實(shí)現(xiàn)這樣一個(gè)簡(jiǎn)單的布局:

          在這里,要實(shí)現(xiàn)輪播效果,并且是任意個(gè)數(shù),我們可以借助 animation-timing-function: steps()

          :root {
            // 輪播的個(gè)數(shù)
            --s6;
            // 單個(gè) li 容器的高度
            --h36;
            // 單次動(dòng)畫(huà)的時(shí)長(zhǎng)
            --speed1.5s;
          }
          .g-container {
            width300px;
            heightcalc(var(--h) * 1px);
          }
          ul {
            display: flex;
            flex-direction: column;
            animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite;
          }
          ul li {
            width100%;
          }
          @keyframes move {
            0% {
              transformtranslate(00);
            }
            100% {
              transformtranslate(0, calc(var(--s) * var(--h) * -1px));
            }
          }

          別看到上述有幾個(gè) CSS 變量就慌了,其實(shí)很好理解:

          1. calc(var(--speed) * var(--s)):?jiǎn)未蝿?dòng)畫(huà)的耗時(shí) * 輪播的個(gè)數(shù),也就是總動(dòng)畫(huà)時(shí)長(zhǎng)
          2. steps(var(--s)) 就是逐幀動(dòng)畫(huà)的幀數(shù),這里也就是 steps(6),很好理解
          3. calc(var(--s) * var(--h) * -1px)) 單個(gè) li 容器的高度 * 輪播的個(gè)數(shù),其實(shí)就是 ul 的總體高度,用于設(shè)置逐幀動(dòng)畫(huà)的終點(diǎn)值

          上述的效果,實(shí)際如下:

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

          這樣,我們就得到了整體的結(jié)構(gòu),至少,整個(gè)效果是循環(huán)的。

          但是由于只是逐幀動(dòng)畫(huà),所以只能看到切換,但是每一幀之間,沒(méi)有過(guò)渡動(dòng)畫(huà)效果。所以,接下來(lái),我們還得引入補(bǔ)間動(dòng)畫(huà)。

          利用補(bǔ)間動(dòng)畫(huà)實(shí)現(xiàn)兩組數(shù)據(jù)間的切換

          我們需要利用補(bǔ)間動(dòng)畫(huà),實(shí)現(xiàn)動(dòng)態(tài)的切換效果。

          這一步,其實(shí)也非常簡(jiǎn)單,我們要做的,就是將一組數(shù)據(jù),利用 transform,從狀態(tài) A 位移到 狀態(tài) B。

          單獨(dú)拿出一個(gè)來(lái)演示的話,大致的代碼如下:

          <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 {
            --h36;
            --speed1.2s;
          }
          ul li {
            height36px;
            animation: liMove calc(var(--speed)) infinite;
          }
          @keyframes liMove {
            0% {
              transformtranslate(00);
            }
            80%,
            100%  {
              transformtranslate(0, -36px);
            }
          }

          非常簡(jiǎn)單的一個(gè)動(dòng)畫(huà):

          bgg1

          基于上述效果,我們?nèi)绻岩婚_(kāi)始提到的 逐幀動(dòng)畫(huà) 和這里這個(gè) 補(bǔ)間動(dòng)畫(huà) 結(jié)合一下,ul 的整體移動(dòng),和 li 的 單個(gè)移動(dòng)疊在在一起:

          :root {
            // 輪播的個(gè)數(shù)
            --s6;
            // 單個(gè) li 容器的高度
            --h36;
            // 單次動(dòng)畫(huà)的時(shí)長(zhǎng)
            --speed1.5s;
          }
          .g-container {
            width300px;
            heightcalc(var(--h) * 1px);
          }
          ul {
            display: flex;
            flex-direction: column;
            animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite;
          }
          ul li {
            width100%;
            animation: liMove calc(var(--speed)) infinite;
          }
          @keyframes move {
            0% {
              transformtranslate(00);
            }
            100% {
              transformtranslate(0, calc(var(--s) * var(--h) * -1px));
            }
          }
          @keyframes liMove {
            0% {
              transformtranslate(00);
            }
            80%,
            100%  {
              transformtranslate(0, calc(var(--h) * -1px));
            }
          }

          就能得到這樣一個(gè)效果:

          Wow,神奇的化學(xué)反應(yīng)產(chǎn)生了!基于 逐幀動(dòng)畫(huà)補(bǔ)間動(dòng)畫(huà) 的結(jié)合,我們幾乎實(shí)現(xiàn)了一個(gè)輪播效果。

          當(dāng)然,有一點(diǎn)瑕疵,可以看到,最后一組數(shù)據(jù),是從第六組數(shù)據(jù) transform 移動(dòng)向了一組空數(shù)據(jù):

          末尾填充頭部第一組數(shù)據(jù)

          實(shí)際開(kāi)發(fā)過(guò)輪播的同學(xué)肯定知道,這里,其實(shí)也很好處理,我們只需要在末尾,補(bǔ)一組頭部的第一個(gè)數(shù)據(jù)即可:

          改造下我們的 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>
              <!--末尾補(bǔ)一個(gè)首條數(shù)據(jù)-->
              <li>Lorem ipsum 1111111</li>
            </ul>
          </div>

          這樣,我們?cè)倏纯葱Ч?/p>

          Beautiful!如果你還有所疑惑,我們給容器加上 overflow: hidden,實(shí)際效果如下,通過(guò)額外添加的最后一組數(shù)據(jù),我們的整個(gè)動(dòng)畫(huà)剛好完美的銜接上,一個(gè)完美的輪播效果:

          完整的代碼,你可以戳這里:CodePen Demo -- Vertical Infinity Loop[2]

          橫向無(wú)限輪播

          當(dāng)然,實(shí)現(xiàn)了豎直方向的輪播,橫向的效果也是一樣的。

          并且,我們可以通過(guò)在 HTML 結(jié)構(gòu)中,通過(guò) style 內(nèi)填寫(xiě) CSS 變量值,傳入實(shí)際的 li 個(gè)數(shù),以達(dá)到根據(jù)不同 li 個(gè)數(shù)適配不同動(dòng)畫(huà):

          <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>
              <!--末尾補(bǔ)一個(gè)首尾數(shù)據(jù)-->
              <li>Lorem ipsum 1111111</li>
            </ul>
          </div>

          整個(gè)動(dòng)畫(huà)的 CSS 代碼基本是一致的,我們只需要改變兩個(gè)動(dòng)畫(huà)的 transform 值,從豎直位移,改成水平位移即可:

          :root {
            --w300;
            --speed1.5s;
          }
          .g-container {
            widthcalc(--w * 1px);
            overflow: hidden;
          }
          ul {
            display: flex;
            flex-wrap: nowrap;
             animation: move calc(var(--speed) * var(--s)) steps(var(--s)) infinite;
          }
          ul li {
            flex-shrink0;
            width100%;
            height100%;
            animation: liMove calc(var(--speed)) infinite;
          }
          @keyframes move {
            0% {
              transformtranslate(00);
            }
            100% {
              transformtranslate(calc(var(--s) * var(--w) * -1px), 0);
            }
          }
          @keyframes liMove {
            0% {
              transformtranslate(00);
            }
            80%,
            100%  {
              transformtranslate(calc(var(--w) * -1px), 0);
            }
          }

          這樣,我們就輕松的轉(zhuǎn)化為了橫向的效果:

          完整的代碼,你可以戳這里:CodePen Demo -- Horizontal Infinity Loop[3]

          輪播圖?不在話下

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

          沒(méi)問(wèn)題,方法都是一樣的?;谏鲜龅拇a,我們可以輕松地將它修改一下后得到圖片版的輪播效果。

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

          完整的代碼,你可以戳這里:CodePen Demo -- Horizontal Image Infinity Loop[4]

          掌握了這個(gè)技巧之后,你可以將它運(yùn)用在非常多只需要簡(jiǎn)化版的輪播效果之上。

          再簡(jiǎn)單總結(jié)一下,非常有意思的技巧:

          1. 利用 逐幀動(dòng)畫(huà),實(shí)現(xiàn)整體的輪播的循環(huán)效果
          2. 利用 補(bǔ)間動(dòng)畫(huà),實(shí)現(xiàn)具體的 *狀態(tài)A狀態(tài)B 的動(dòng)畫(huà)效果
          3. 逐幀動(dòng)畫(huà) 配合 補(bǔ)間動(dòng)畫(huà) 構(gòu)成整體輪播的效果
          4. 通過(guò)向 HTML 結(jié)構(gòu)末尾補(bǔ)充一組頭部數(shù)據(jù),實(shí)現(xiàn)整體動(dòng)畫(huà)的銜接
          5. 通過(guò) HTML 元素的 style 標(biāo)簽,利用 CSS 變量,填入實(shí)際的參與循環(huán)的 DOM 個(gè)數(shù),可以實(shí)現(xiàn) JavaScript 與 CSS 的打通

          最后

          OK,本文到此結(jié)束,希望本文對(duì)你有所幫助 :)

          想 Get 到最有意思的 CSS 資訊,千萬(wàn)不要錯(cuò)過(guò)我的公眾號(hào) -- iCSS前端趣聞

          更多精彩 CSS 技術(shù)文章匯總在我的 Github -- iCSS[5] ,持續(xù)更新,歡迎點(diǎn)個(gè) star 訂閱收藏。

          如果還有什么疑問(wèn)或者建議,可以多多交流,原創(chuàng)文章,文筆有限,才疏學(xué)淺,文中若有不正之處,萬(wàn)望告知。

          參考資料

          [1]

          深入淺出 CSS 動(dòng)畫(huà): https://github.com/chokcoco/iCSS/issues/141

          [2]

          CodePen Demo -- Vertical Infinity Loop: https://codepen.io/Chokcoco/pen/RwQVByx

          [3]

          CodePen Demo -- Horizontal Infinity Loop: https://codepen.io/Chokcoco/pen/JjpNBXY

          [4]

          CodePen Demo -- Horizontal Image Infinity Loop: https://codepen.io/Chokcoco/pen/GRQvqgq

          [5]

          Github -- iCSS: https://github.com/chokcoco/iCSS

          iCSS,不止于 CSS,如果你也對(duì)各種新奇有趣的前端(CSS)知識(shí)感興趣,歡迎關(guān)注 。同時(shí)如果你有任何想法疑問(wèn),或者也想入群參與大前端技術(shù)討論,圍觀答疑解惑,共同成長(zhǎng)進(jìn)步,可以關(guān)注公眾號(hào)加我微信,拉你入群


          因?yàn)槲⑿殴娞?hào)修改規(guī)則,如果不標(biāo)星或點(diǎn)在看,你可能會(huì)收不到我公眾號(hào)文章的推送,請(qǐng)大家將本公眾號(hào)星標(biāo),看完文章后記得點(diǎn)下贊或者在看,謝謝各位!

          瀏覽 98
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  强开小嫩苞一区二区三区在线 | 婷婷五月丁香花 | 亚欧精品久久久久久久久久久 | 五月丁香婷婷也去 | 91麻豆精品国产91久久久熟女 |