深入了解CSS動畫新功能:@scroll-timeline

青灯夜游
發布: 2022-03-18 10:55:15
轉載
2906 人瀏覽過

在之前的文章《2022年你值得了解的幾個CSS新特性(收藏學習)》中帶大家簡單介紹了幾個CSS新特性,今天帶大家深入了解其中的一個新特色(動畫殺手鐧):@scroll-timeline,希望對大家有幫助!

深入了解CSS動畫新功能:@scroll-timeline

在 CSS 規格Scroll-linked Animations中,推出了一個劃時代的 CSS 功能。也就是 -- The@scroll-timelineat-rule,直譯過來就是滾動時間軸

本文,就將帶大家一探究竟,從入門到學會使用 CSS@scroll-timeline。 (建議學習:css影片教學

何為 @scroll-timeline 捲動時間軸?

什麼是@scroll-timeline滾動時間軸呢?

@scroll-timeline能夠設定一個動畫的開始和結束由滾動容器內的滾動進度決定,而不是由時間決定。

意思是,我們可以定義一個動畫效果,該動畫的開始和結束可以透過容器的滾動來控制

示意DEMO

再系統性學習文法之前,我們透過一個DEMO,簡單了解一下它的用法:

#我們先實作一個簡單的字體F旋轉動畫

F
登入後複製
#g-box { animation-name: rotate; animation-duration: 3s; animation-direction: alternate; animation-easing-function: linear; } @keyframes rotate { 0% { transform: rotate(0); } 100% { transform: rotate(360deg); } }
登入後複製

正常而言,它是這樣一個簡單的動畫:

深入了解CSS動畫新功能:@scroll-timeline

接下來,我們把這個動畫和@scroll-timeline結合,需要把它放置到一個可滾動的容器中:

         
F
登入後複製
#g-content { width: 300px; height: 170vh; background: #999; } #g-box { font-size: 150px; margin: 70vh auto 0; animation-name: rotate; animation-duration: 3s; animation-direction: alternate; animation-easing-function: linear; animation-timeline: box-rotate; } @keyframes rotate { 0% { transform: rotate(0); } 100% { transform: rotate(360deg); } } @scroll-timeline box-rotate { source: selector("#g-content"); }
登入後複製

這裡,我們實作了一個可滾動容器#g-content,它的高度是170vh,也就是可視界面高度的1.7 倍,並且把#g-box容器放置在一個距離頂部70vh高度的地方:

深入了解CSS動畫新功能:@scroll-timeline

有意思的來了,我們設定的旋轉動畫不會自動開始,只有當我們向下滾動的時候,動畫才會開始進行,實際效果Gif:

深入了解CSS動畫新功能:@scroll-timeline

CodePen Demo -- @scroll-timeline Demo

https://codepen.io/Chokcoco/pen/JjOZMaQ

看到這裡,大家應該能夠理解@scroll-timeline的作用及意義了,它賦予了CSS 能夠基於滾動條的滾動去控制動畫行進的能力!Amazing! !

@scroll-timeline 文法介紹

接下來,我們先緩一緩,簡單看一看@scroll-timeline的文法。

使用@scroll-timeline,最核心的就是需要定義一個@scroll-timeline規則:

@scroll-timeline moveTimeline { source: selector("#g-content"); orientation: vertical; scroll-offsets: 0px, 500px; }
登入後複製

其中:

  • source:绑定触发滚动动画的滚动容器
    • source: auto:绑定到Document,也就是全局 Windows 对象
    • source: selector("id-selector"),通过selector(),内置一个#id选择器,选取一个可滚动容器
    • source: none:不指的滚动容器
  • orientation:设定滚动时间线的方向
    • orientation: auto:默认为 vertical,也就是竖直方向的滚动
    • orientation: vertical:竖直方向的滚动
    • orientation: horizontal:水平方向的滚动
    • orientation: block:不太常用,使用沿块轴的滚动位置,符合书写模式和方向性
    • orientation: inline:不太常用,使用沿内联轴的滚动位置,符合书写模式和方向性
  • scroll-offsets:滚动时间线的核心,设定在滚动的什么阶段,触发动画,可通过三种方式之一进行设置:
    • scroll-offsets: none这意味着没有 scroll-offset 指定。
    • 由逗号分隔的length-percentage值列表确定。每个值都映射到animation-duration。例如,如果 ananimation-duration 设置为 2s 且滚动偏移量为 0px, 30px, 100px,则在 1s 时,滚动偏移量将为 30px。
    • 第三种确定滚动偏移量的方法是使用元素偏移量。这意味着可以指定页面内的元素,其位置决定了滚动时间线以及要使用这些元素的哪个边缘。指定元素是使用 selector() 函数完成的,该函数接收元素的 id。边缘由关键字 start 或确定 end。可选的阈值的 0–1 可用于表示元素滚动中预期可见的百分比。

scroll-offsets的理解会比较困难,我们稍后详述。

在设定了一个@scroll-timeline之后,我们只需要将它和动画绑定起来即可,通过animation-timeline

@scroll-timeline moveTimeline { source: selector("#g-content"); orientation: vertical; scroll-offsets: 0px, 500px; } div { animation-name: move; animation-duration: 3s; animation-timeline: moveTimeline; } @keyframes move{ 0% { transform: translate(0, 0); } 100% { transform: translate(100%, 0); } }
登入後複製

使用 @scroll-timeline 实现滚动进度指示器

之前在不可思议的纯 CSS 滚动进度条效果一文中,我们介绍了一种使用渐变实现的纯 CSS 滚动进度指示器效果:

深入了解CSS動畫新功能:@scroll-timeline

该方法有些小小的瑕疵。其中一个就是当滚动距离太短的时候,进度条右侧会有明显的斜边效果。

而有了@scroll-timeline之后,我们终于可以将滚动和动画这两个元素绑定起来,再实现滚动进度指示器,就已经非常轻松了:

...文本内容...

登入後複製
#g-container { width: 100vw; } #g-container::before { content: ""; position: fixed; height: 5px; left: 0; top: 0; right: 0; background: #ffc107; animation-name: scale; animation-duration: 1s; animation-fill-mode: forwards; animation-timeline: box-rotate; transform-origin: 0 50%; } @keyframes scale { 0% { transform: scaleX(0); } 100% { transform: scaleX(1); } } @scroll-timeline box-rotate { source: auto; orientation: vertical; }
登入後複製

1、我们在页面最上方,通过一个伪元素,实现一个占满屏幕100%5px高的进度条。正常而言是这样:

深入了解CSS動畫新功能:@scroll-timeline

2、通过设定一个transform: scaleX(0)transform: scaleX(1)的动画,并且将它与 body 的滚动相绑定,即可得到滚动指示器,效果如下:

深入了解CSS動畫新功能:@scroll-timeline

完整的代码,你可以戳这里:CodePen Demo - 使用 @scroll-timeline 实现滚动进度条

https://codepen.io/Chokcoco/pen/eYeKLMj

使用 scroll-offsets 精确控制动画触发时机

大家可以再看看上面的 Gif 图,都有一个问题,就是动画的开始时间都是从滚动一开始就开始了,刚好在滚动结束时结束。那么如果我希望动画在滚动的特定阶段触发,那该怎么办呢?

这里,就需要借助scroll-offsets,去更加精确的控制我们的动画。

在滚动过程中,我们可以将一个元素,划分为 3 个区域:

  • 滚动过程中,从上方视野盲区,进入视野
  • 滚动过程中,处于视野中
  • 滚动过程中,从视野中,进入下方视野盲区

在这里,我们就可以得到两个边界,上方边界,下方边界:

深入了解CSS動畫新功能:@scroll-timeline

而对于上下两个边界,又会有两种状态。以上边界为例子,会有:

  • 元素刚刚开始进入可视区
  • 元素完全进入可视区

对于这两种状态,我们用start 0start 1表示,同理,下方的边界也可以用end 0end 1表示:

深入了解CSS動畫新功能:@scroll-timeline

这里的 0 和 1 实际表示的是,元素滚动中预期可见的百分比

有了这些状态值,配合scroll-offsets,我们就可以精确控制滚动动画的触发时间。

我们设定一个从左向右并且伴随透明度变化的动画,的看看下面几种情况:

1、滚动动画在元素从下方开始出现时开始,完全出现后截止。

动画运行范围:end 0-->end 1

@keyframes move { 0% { transform: translate(-100%, 0); opacity: 0; } 100% { transform: translate(0, 0); opacity: 1; } } @scroll-timeline box-move { source: auto; orientation: "vertical"; scroll-offsets: selector(#g-box) end 0, selector(#g-box) end 1; /* Legacy Descriptors Below: */ start: selector(#g-box) end 0; end: selector(#g-box) end 1; time-range: 1s; } #g-box { animation-name: move; animation-duration: 3s; animation-fill-mode: both; animation-timeline: box-move; }
登入後複製

效果如下:

深入了解CSS動畫新功能:@scroll-timeline

2、滚动动画在元素从下方完全出现时开始,在滚动到上方即将离开屏幕后截止:

动画运行范围:end 1-->start 1

// ... @scroll-timeline box-move { source: auto; orientation: "vertical"; scroll-offsets: selector(#g-box) end 1, selector(#g-box) start 1; /* Legacy Descriptors Below: */ start: selector(#g-box) end 1; end: selector(#g-box) start 1; time-range: 1s; } // ...
登入後複製

效果如下:

深入了解CSS動畫新功能:@scroll-timeline

3、滚动动画在元素滚动到上方即将离开屏幕后开始,完全离开屏幕后截止:

动画运行范围:start 1-->start 0

// ... @scroll-timeline box-move { source: auto; orientation: "vertical"; scroll-offsets: selector(#g-box) start 1, selector(#g-box) start 0; /* Legacy Descriptors Below: */ start: selector(#g-box) start 1; end: selector(#g-box) start 0; time-range: 1s; } // ...
登入後複製

效果如下:

1深入了解CSS動畫新功能:@scroll-timeline

掌握scroll-offsets的用法是灵活运用滚动时间线的关键,当然,在上面你还会看到start: selector(#g-box) start 1end: selector(#g-box) start 0这种写法,这是规范历史遗留问题,最新的规范已经使用了scroll-offsets去替代start:end:的写法。

把上述 3 种情况放在一起,再比较比较:

1深入了解CSS動畫新功能:@scroll-timeline

完整的代码,你可以戳这里:CodePen Demo - @scroll-timeline Demo | element-based offset

使用 @scroll-timeline 实现各类效果

在能够掌握 @scroll-timeline 的各个语法之后,我们就可以开始使用它创造各种动画效果了。

譬如如下的,滚动内容不断划入:

1深入了解CSS動畫新功能:@scroll-timeline

代码较长,可以戳这里,来自 bramus 的 Codepen CodePen Demo -- Fly-in Contact List (CSS @scroll-timeline version)

https://codepen.io/bramus/pen/bGwJVzg

甚至可以结合scroll-snap-type制作一些全屏滚动的大屏特效动画:

1深入了解CSS動畫新功能:@scroll-timeline

要知道,这在以前,是完全不可能利用纯 CSS 实现的。完整的代码你可以戳这里:CodePen Demo -- CSS Scroll-Timeline Split Screen Carousel

https://codepen.io/Chokcoco/pen/QWOrPdM

简而言之,任何动画效果,如今,都可以和滚动相结合起来,甚至乎是配合 SVG 元素也不例外,这里我还简单改造了一下之前的一个 SVG 线条动画:

1深入了解CSS動畫新功能:@scroll-timeline

完整的代码你可以戳这里:CodePen Demo -- SVG Text Line Effect | Scroll Timeline

https://codepen.io/Chokcoco/pen/wvPxbRm

@scroll-timeline 的实验室特性与特性检测

@scroll-timeline虽好,目前仍处于实验室特性时间,Chrome 从 85 版本开始支持,但是默认是关闭的。

兼容性如下(2022-03-07):

1深入了解CSS動畫新功能:@scroll-timeline

在最新的 chrome、Edge、Opera 可以通过浏览器配置开启该特性,Chrome 下开启该特性需要:

  • 浏览器 URL 框输入chrome://flags

  • 开启#enable-experimental-web-platform-features

美酒虽好,但是离完全能用,浏览器大规模支持还需要等待一会,给时间一点时间吧!

特性检测

基于目前的兼容性问题,我们可以通过浏览器的特性检测@supports语法,来渐进增强使用该功能。

特性检测的语法也非常简单:

@supports (animation-timeline: works) { @scroll-timeline list-item-1 { source: selector(#list-view); start: selector(#list-item-1) end 0; end: selector(#list-item-1) end 1; scroll-offsets: selector(#list-item-1) end 0, selector(#list-item-1) end 1 ; time-range: 1s; } // ... }
登入後複製

通过@supports (animation-timeline: works) {}可以判断浏览器是否支持@scroll-timeline

最后

目前关于 @scroll-timeline 的相关介绍还非常少,但是它确是能够改变 CSS 动画的一个非常大的革新。随着兼容性的逐渐普及,未来势必会在 CSS 中占据一席之地。

本文到此结束,希望对你有帮助 :)

(学习视频分享:web前端

以上是深入了解CSS動畫新功能:@scroll-timeline的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:juejin.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!