在 CSS 中,無(wú)需任何 JavaScript 就可以實(shí)現(xiàn)一些滾動(dòng)動(dòng)畫(huà)。只需查看關(guān)于 滾動(dòng)指示器 的章節(jié),這顯然是 CSS 的魔力。但我們可以在 CSS 中直接完成大量滾動(dòng)動(dòng)畫(huà)工作,只需要 JavaScript 提供的一點(diǎn)點(diǎn)信息:頁(yè)面滾動(dòng)多遠(yuǎn)。
所以讓我們先解決這個(gè)問(wèn)題。使用 JavaScript 的單行代碼,我們可以設(shè)置一個(gè) CSS 自定義屬性,它知道頁(yè)面滾動(dòng)的百分比
window.addEventListener('scroll', () => { document.body.style.setProperty('--scroll', window.pageYOffset / (document.body.offsetHeight - window.innerHeight)); }, false);
現(xiàn)在我們有了 --scroll 作為可以在 CSS 中使用的值。
這個(gè)技巧來(lái)自 Scott Kellum,他是一位非常厲害的 CSS 技巧大師!
讓我們先不使用該值來(lái)設(shè)置動(dòng)畫(huà)。這是一個(gè)簡(jiǎn)單的 SVG 元素旋轉(zhuǎn)動(dòng)畫(huà),它會(huì) 永遠(yuǎn)旋轉(zhuǎn)
svg { display: inline-block; animation: rotate 1s linear infinite; } @keyframes rotate { to { transform: rotate(360deg); } } 你懂的,它會(huì)旋轉(zhuǎn),永遠(yuǎn)旋轉(zhuǎn)。
重點(diǎn)來(lái)了! 現(xiàn)在讓我們暫停這個(gè)動(dòng)畫(huà)。我們不會(huì)在一段時(shí)間內(nèi)對(duì)其進(jìn)行動(dòng)畫(huà),而是通過(guò)頁(yè)面滾動(dòng)調(diào)整 animation-delay 來(lái)通過(guò)滾動(dòng)位置對(duì)其進(jìn)行動(dòng)畫(huà)。如果 animation-duration 為 1s,這意味著滾動(dòng)頁(yè)面的整個(gè)長(zhǎng)度。是動(dòng)畫(huà)的一次迭代。
svg { position: fixed; /* make sure it stays put so we can see it! */ animation: rotate 1s linear infinite; animation-play-state: paused; animation-delay: calc(var(--scroll) * -1s); }
嘗試將 animation-duration 更改為 0.5s。這樣就可以在頁(yè)面向下滾動(dòng)時(shí)使用 animation-delay 數(shù)學(xué)運(yùn)算完成兩個(gè)完整的動(dòng)畫(huà)循環(huán)。
Scott 在他的原始演示中指出,還設(shè)置了…
animation-iteration-count: 1; animation-fill-mode: both;
… 考慮了一些“過(guò)沖”的奇怪現(xiàn)象,我可以證明我也見(jiàn)過(guò),尤其是在短視窗上,所以設(shè)置它們也是值得的。
Scott 還將與滾動(dòng)相關(guān)的動(dòng)畫(huà)屬性設(shè)置為 :root {} 本身,這意味著它可以同時(shí)控制頁(yè)面上的所有動(dòng)畫(huà)。 這是他的演示,它同時(shí)控制三個(gè)動(dòng)畫(huà)