当前位置: 首页 > 科技观察

革命性的创新,动画杀手@Scroll-Timeline

时间:2023-03-23 10:59:12 科技观察

在CSS规范Scroll-linkedAnimations[1]中引入了划时代的CSS功能。那就是——@scroll-timeline[2]规则,直译为滚动时间线。本文将带你一探究竟,从入门到学习如何使用CSS@scroll-timeline。什么是@scroll-timeline滚动时间线?什么是@scroll-timeline滚动时间线?@scroll-timeline可以设置动画的开始和结束由滚动容器中的滚动进度决定,而不是时间。也就是说,我们可以定义一个动画效果,它的开始和结束可以通过滚动容器来控制。在系统学习DEMO的语法之前,先用一个DEMO来简单了解一下它的用法:我们先实现一个简单的字体F旋转动画:F

#g-box{animation-名称:旋转;动画持续时间:3s;动画方向:交替;animation-easing-function:linear;}@keyframesrotate{0%{transform:rotate(0);}100%{变换:旋转(360deg);}}通常情况下,就是这样一个简单的动画:接下来,我们将这个动画与@scroll-timeline结合起来,需要将它放在一个可滚动的容器中:F
#g-content{width:300px;身高:170vh;背景:#999;}#g-box{字体大小:150px;保证金:70vh自动0;动画名称:旋转;动画持续时间:3s;动画方向:交替;动画缓动函数:线性;动画时间轴:box-rotate;}@keyframesrotate{0%{transform:rotate(0);}100%{变换:旋转(360deg);}}@scroll-timelinebox-rotate{source:selector("#g-content");}在这里,我们实现了一个可滚动容器#g-content的高度为170vh,是可视化界面高度的1.7倍,#g-box容器放置在距离顶部70vh的高度:有趣的事情来了,旋转我们设置动画不会自动启动,只有当我们向下滚动时,动画才会启动,实际效果Gif:CodePenDemo--@scroll-timelineDemo[3]看到这里,大家应该能看懂@scroll-timeline作用与意义,它赋予了CSS根据滚动条的滚动来控制动画进度的能力!太神奇了!!@scroll-timeline语法介绍要使用@scroll-timeline,核心就是定义一个@scroll-timeline规则:@scroll-timelinemoveTimeline{source:selector("#g-content");方向:垂直;scroll-offsets:0px,500px;}其中:source:绑定触发滚动动画的滚动容器source:auto:绑定到Document,也就是全局的Windows对象source:selector("id-selector"),通过selector(),内置了一个#id选择器,选择一个可滚动的容器source:none:不指滚动容器orientation:设置滚动时间线的方向orientation:auto:默认为垂直,即在verticaldirectionorientation:vertical:垂直方向滚动orientation:horizo??ntal:水平滚动orientation:block:不常用,使用沿block轴的滚动位置,符合书写方式和orientationorientation:inline:不常用,使用scrollpositionalongtheinlineaxis,conformtothewritingmodeandorientationscroll-offsets:滚动时间轴的核心,设置在什么阶段滚动,触发动画,可以设置为三种方式之一:scroll-offsets:none这意味着没有指定滚动偏移量。由逗号分隔的[4]值列表标识。每个值都映射到动画持续时间[5]。例如,如果animation-duration设置为2s,滚动偏移量为0px、30px、100px,在1s时,滚动偏移量将为30px。确定滚动偏移量的第三种方法是使用元素偏移量。这意味着可以在页面中指定其位置决定滚动时间轴的元素以及使用这些元素的哪个边缘。指定元素是使用selector()函数完成的,该函数接收元素的id。边由关键字start或end决定。可选的0-1阈值可用于表示预期在滚动中可见的元素的百分比。scroll-offsets的理解会比较困难,后面会详细说明。设置好@scroll-timeline后,我们只需要将它绑定到动画上,通过animation-timeline:@scroll-timelinemoveTimeline{source:selector("#g-content");方向:垂直;scroll-offsets:0px,500px;}div{animation-name:move;动画持续时间:3s;动画时间轴:moveTimeline;}@keyframesmove{0%{transform:translate(0,0);}100%{转换:翻译(100%,0);}}使用@scroll-timeline实现滚动进度条效果在令人难以置信的纯CSS滚动进度条效果[6]中,我们介绍了一种使用渐变的纯CSS实现滚动进度条效果:这种方法有一些小缺陷。其中之一就是当滚动距离过短时,进度条右侧会出现明显的斜角效果。有了@scroll-timeline,我们终于可以绑定滚动和动画这两个元素,进而实现滚动进度条,非常简单:

...文本内容。..

#g-container{width:100vw;}#g-container::before{content:"";位置:固定;高度:5px;左:0;顶部:0;右:0;背景:#ffc107;动画名称:比例;动画持续时间:1s;动画填充模式:转发;动画时间轴:框旋转;变换原点:050%;}@keyframesscale{0%{transform:scaleX(0);}100%{转换:scaleX(1);}}@scroll-timelinebox-rotate{来源:自动;orientation:vertical;}1.我们在页面顶部,使用一个伪元素实现一个5px高的进度条,占满屏幕100%。通常情况下是这样的:2、设置一个从transform:scaleX(0)到transform:scaleX(1)的动画,绑定到body的滚动,就可以得到一个滚动指示器。效果如下:完整代码可以点击这里:CodePenDemo-使用@scroll-timeline实现滚动进度条[7]使用scroll-offsets精确控制动画触发的时机。大家可以再看看上面的动图。有一个问题,就是动画的开始时间都是在滚动开始的时候开始,刚好在滚动结束的时候结束。那么如果我想让动画在滚动的特定阶段被触发呢?在这里,我们需要使用scroll-offsets来更精确地控制我们的动画。在滚动过程中,我们可以将一个元素分为3个区域:在滚动过程中,从上方视野的盲区,进入滚动过程中视野的盲区,在滚动过程中的视野,从视野,进入下视野的盲区这里,我们可以得到两个边界,上边界和下边界:而对于上边界和下边界,会有两种状态。以上边界为例,会有:元素刚开始进入可见区域和元素已经完全进入可见区域。对于这两个状态,我们用start0和start1来表示。同样,下边界也可以用end0和end1表示:这里的0和1实际上代表元素滚动的预期可见百分比。有了这些状态值,再结合scroll-offsets,我们就可以精确控制滚动动画的触发时间。我们来设置一个从左到右透明变化的动画,看看下面几种情况:滚动动画从元素从下方出现时开始,完全出现时结束。动画运行范围:end0-->end1:@keyframesmove{0%{transform:translate(-100%,0);不透明度:0;}100%{转换:翻译(0,0);不透明度:1;}}@scroll-timelinebox-move{来源:自动;方向:“垂直”;滚动偏移量:选择器(#g-box)结束0,选择器(#g-box)结束1;/*下面的遗留描述符:*/start:selector(#g-box)end0;结束:选择器(#g-box)结束1;时间范围:1秒;}#g-box{动画名称:移动;动画持续时间:3s;动画填充模式:两者;animation-timeline:box-move;}效果如下:元素从底部完全出现时开始滚动动画,滚动到顶部即将离开屏幕时结束:动画运行范围:end1-->开始1://...@scroll-timelinebox-move{source:auto;方向:“垂直”;滚动偏移量:选择器(#g-box)结束1,选择器(#g-box)开始1;/*遗留描述符如下:*/start:selector(#g-box)end1;结束:选择器(#g-box)开始1;time-range:1s;}//...效果如下:滚动动画在元素上方滚动即将离开屏幕时开始,完全离开屏幕时结束:动画运行范围:start1-->start0://...@scroll-timelinebox-move{source:auto;方向:“垂直”;滚动偏移量:选择器(#g-box)开始1,选择器(#g-box)开始0;/*遗留描述符如下:*/start:selector(#g-box)start1;结束:选择器(#g-box)开始0;time-range:1s;}//...效果如下:掌握scroll-offsets的用法是灵活使用滚动时间轴的关键。当然你也会看到start:selector(#g-box)start1和end:selector(#g-box)start0,这是规范历史遗留下来的问题。最新的规范已经用scroll-offsets代替了start:和end:来把上面三种情况放到一起,对比一下:完整代码,可以戳这里:CodePenDemo-@scroll-timelineDemo|element-basedoffset[8]使用@scroll-timeline实现各种效果在掌握了@scroll-timeline的每一个语法之后,我们就可以开始使用它来制作各种动画效果了。比如如下,连续绘制滚动内容:代码比较长,可以点这里,codepen来自bramus的CodePenDemo--Fly-inContactList(CSS@scroll-timelineversion)[9]甚至可以结合用scroll-snap-type做一些全屏滚动的大屏特效动画:要知道,这在以前用纯CSS是完全不可能实现的。完整代码可以点击这里:CodePenDemo--CSSScroll-TimelineSplitScreenCarousel[10]简而言之,现在任何动画效果都可以与滚动结合,甚至与SVG元素结合,这里我也简单修改了一个之前的SVG线条动画:完整代码可以点这里:CodePenDemo--SVGTextLineEffect|ScrollTimeline[11]@scroll-timeline的实验室特征和特征检测@scroll-timeline虽然不错,但还是在实验室特征时间。Chrome从85版本开始支持它,但默认情况下它是关闭的。启用该功能:在浏览器URL框中输入chrome://flags,启用#enable-experimental-web-platform-features特性检测基于目前的兼容性问题,我们可以使用浏览器的特性检测@supports语法逐步增强使用此功能。特征检测的语法也很简单:@supports(animation-timeline:works){@scroll-timelinelist-item-1{source:selector(#list-view);开始:选择器(#list-item-1)结束0;结束:选择器(#list-item-1)结束1;滚动偏移量:选择器(#list-item-1)结束0,选择器(#list-item-1)结束1;时间范围:1s;}//...}通过@supports(animation-timeline:works){}可以判断浏览器是否支持@scroll-timeline。最后,关于@scroll-timeline的介绍很少,但确实是一个非常大的创新,可以改变CSS动画。随着兼容性的逐渐普及,未来势必在CSS中占据一席之地。参考资料[1]滚动链接动画:https://drafts.c??sswg.org/scroll-animations-1/[2]@scroll-timeline:https://drafts.c??sswg.org/scroll-animations/#at-ruledef-scroll-timeline[3]CodePen演示——@scroll-timeline演示:https://codepen.io/Chokcoco/pen/JjOZMaQ[4]:https://developer.mozilla.org/en-US/docs/Web/CSS/length-percentage[5]animation-duration:https://developer.mozilla.org/en-US/docs/Web/CSS/animation-duration[6]不可思议的纯CSS滚动进度条效果:https://www.cnblogs.com/coco1s/p/10244168.html[7]CodePenDemo——使用@scroll-timeline实现滚动进度条:https://codepen.io/Chokcoco/pen/eYeKLMj[8]CodePen演示-@scroll-timeline演示|基于元素的偏移量:https://codepen.io/Chokcoco/pen/qBVyqob[9]CodePen演示-飞入联系人列表(CSS@scroll-timeline版本):https://codepen.io/bramus/pen/bGwJVzg[10]CodePenDemo--CSSScroll-TimelineSplitScreenCarousel:https://codepen.io/Chokcoco/pen/QWOrPdM[11]CodePenDemo--SVG文本行效果|滚动时间轴:https://codepen.io/Chokcoco/笔/wvPxbRm