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

动画合成技巧!CSS实现动态倒计时效果_0

时间:2023-03-18 13:38:08 科技观察

介绍CSS动画合成技巧。先看效果:Kapture2022-06-26at16.57.42这是一个非常“动感”的倒计时效果,比较常见于一些活动的开启。分析整个动画过程,不难发现有以下几类动画:数字在缩小和放大上的透明度变化变化,不知道小伙伴们能观察到吗?一起来看看具体的实现吧!1、数字的变化我们先来看数字的变化。这个技巧在上一篇文章:还在用定时器?CSS也可以第一次用在电子钟上,这里再介绍一下。以往,数字的改变可能需要创建多个标签,然后改变位移来实现。<倒计时>54321该方法需要创建多个标签,有点繁琐,不易扩展。现在有一种更简洁的实现方式,那就是CSS@property[1]。这个是来做什么的?简单来说就是可以自定义属性。在此示例中,您可以使数字像颜色一样过渡和动画。可能大家看不懂,还是看例子吧!假设HTML是这样的:然后我们通过CSS变量将数字渲染到页面,这就需要伪元素和计数器的帮助。有兴趣的可以参考这篇文章:Tips:HowtodisplayCSSvarvariablevaluewiththehelpofthecontentattribute[2]。倒计时::之后{计数器重置:时间var(--t);content:counter(time);}效果如下:image-20220626135133534如何让这个数字发生变化?可以使用CSS动画:@keyframescount{to{--t:0}}count-down::after{--t:5;计数器复位:时间变量(--t);内容:计数器(时间);animation:count5sforward;}效果如下:Kapture2022-06-26at13.55.42当前效果只过了5秒,数字从5变成0,没有5=>4=>3=>2=>1这样的相变。然后最重要的一步来了,添加如下自定义属性:@property--t{syntax:'';继承:假的;initial-value:0;}没错,就是加上这一小段CSS,效果就出来了。Kapture2022-06-26在14.03.07是不是很神奇?可以理解为通过@property定义后,这个变量--t本身就可以单独动画了,就像颜色变化一样。另外,使用计数器的好处是可以随意改变类型。比如把上面的阿拉伯数字改成中文计数,只需要改变计数器类型即可。完整类型请参考:list-style-type[3]。倒计时::之后{--t:5;计数器复位:时间变量(--t);内容:计数器(时间,cjk-decimal);/*CJK十进制数*/animation:count5sforward;}效果如下:Kapture2022-06-26at14.14.20是不是很方便?2、倒计时的终点上面的计数器的最终终点是“0”,显然我们需要一些特定的提示,比如“Go~”。如何改变上一帧的状态?这里有两种方式:throughanimationcoveragethroughcountercoverage先看第一种方式,比较容易理解,重新定义一个动画,倒计时结束后重置最后一帧。@keyframesstop{to{content:'Go~';}}倒计时::之后{--t:5;计数器复位:时间变量(--t);内容:计数器(时间);animation:count5sforward,stop5sstep-endforward;}·效果如下:Kapture2022-06-26at14.46.18注意这里的动画函数是step-end,为什么会这样?step-end也可以写成steps(1,end)。你可以理解为整个动画只有两种状态。在运行过程中,它们都是初始状态,只有到最后一帧时状态才会发生变化。下面是MDN的截图。再来看第二种方式,通过自定义计数器来实现。原理其实有点类似JS的思想。当数字为0时,让计数器指定一个特殊值。具体实现如下:@counter-stylestop{system:cyclic;符号:“去~”;range:00;}这里简单说明一下,这里有一个range属性,表示计数器的范围。由于只需要指定为0,就是区间00。然后就是system,就是计算系统,这里是cyclic,就是循环使用开发者提供的一组字符,字符由符号定义。然后symbols代表计算符号,也就是具体显示的字符,这里指定Go~即可。海关柜台这部分内容比较复杂,也比较新。有兴趣的可以参考张新旭的这篇文章:CSS@counter-style规则详解[4]。然后是应用程序;count-down::after{/**/counter-reset:timevar(--t);内容:计数器(时间,停止);/*自定义计数器*/}这样也可以达到同样的效果,也比较优雅;Kapture2022-06-26at14.46.183.缩放和透明度变化这两个动画实际上是同时执行的,可以放在一个动画中。@keyframes鲨鱼{0%{不透明度:1;变换:规模(1);}50%{不透明度:0;变换:比例(0.4);}}然后设置动画时长为1s,循环5次。倒计时::之后{--t:5;计数器复位:时间变量(--t);内容:计数器(时间);animation:count5ssteps(5)forwards,shark1s5;}效果如下:Kapture2022-06-26at16.47.09是不是有点突兀?因为数字的变化是突然的,所以需要隐藏数字的变化,直到透明度为0。为了达到这个效果,只需要将闪烁动画延迟0.5秒即可。倒计时::之后{--t:5;计数器复位:时间变量(--t);内容:计数器(时间);动画:向前数5ssteps(5),鲨鱼1s.5s5;/*Delay0.5s*/}这样就自然多了;Kapture2022-06-26at16.51.37但仍有优化空间。比如现在的数字动画太连贯了。如果希望数字出现后停留一段时间,或者希望数字出现的慢一些,消失的快一些,该如何处理呢?其实这比想象的简单多了,只需要改变关键帧位置即可,如下:@keyframesshark{0%{opacity:1;变换:规模(1);}20%{不透明度:0;变换:比例(0.4);同时,延迟时间也需要改为0.8秒,效果如下:Kapture2022-06-26at16.57.42这样就达到了文章开头所示的效果。重点来了~完整代码如下:@property--t{syntax:'';继承:假的;初始值:0;}@counter-stylestop{系统:循环;symbols:"Go~";range:infinite0;}html,body{margin:0;高度:100%;显示:网格;放置内容:中心;}倒计时{显示:flex;对齐项目:居中;证明内容:居中;字体系列:Consolas、Monaco、等宽字体;字体大小:120px;}倒计时::之后{--t:5;--杜尔:1;计数器复位:时间变量(--t);:计数器(时间,停止);动画:计算calc(var(--t)*var(--dur)*1s)步数(var(--t))向前,鲨鱼calc(var(--dur)*1s)calc(var(--dur)*.8s)calc(var(--t));}@keyframescount{to{--t:0;}}@keyframes鲨鱼{0%{不透明度:1;变换:规模(1);}20%{不透明度:0;变换:比例(0.4);}}也可以访问在线示例:CSScount-down(codepen.io)[5]orCSScount-down(juejin.cn)[6]另外,demo中还有一个小彩蛋,点击重新-新建跑步动画,实现方法如下:count-down:active::after{animation:none;}四、其他动画效果除了缩放效果,还可以有一些位移动画,比如这个:@关键帧鲨鱼{0%{不透明度:1;转换:翻译Y(0);}20%{不透明度:0;转换:translateY(100px);}}效果如下:Kapture2022-06-26at17.07.00是不是有点奇怪?动画不够连贯,一个往下一个往上。有没有办法从上到下消失和出现?当然也可以,实现如下:@keyframesshark{0%{opacity:1;转换:翻译Y(0);}20%{不透明度:0;转换:translateY(100px);}21%{不透明度:0;变换:平移(-100px);}}这里加入了一个很“相邻”的关键帧,意思是在透明状态下,位移变化“很快”,这样数字出现时的动画是从上到下的,整体比较流畅效果如下:Kapture2022-06-26at17.15.02还可以调整之前的缩放效果,出来的时候更大更震撼@keyframes鲨鱼{0%{不透明度:1;变换:规模(1);}20%{不透明度:0;变换:比例(.4);}21%{不透明度:0;变换:比例(5);}效果如下:Kapture2022-06-26at17.38.54当然还有其他的效果,比如旋转,斜切等,需要你的想象力了~五、总结与解释以上就是全部内容这篇文章的一个简单的小动画,你学会了吗?让我们总结一下实现的要点:复杂的动画可以分解成多个简单的动画。通过多个标签改变位移可以实现数字的变化。CSS计数器可以将数字变量渲染到页面。CSS@property可以为CSS变量设置动画,就像颜色一样。改变同一个CSS计数器的好处是可以随意改变类型。比如中文倒计时的结束点默认是数字0。您可以通过另一个动画重置最后一帧。可以自定义CSS计数器,将某个计数符号渲染为指定字符缩放,同时进行透明度的改变。它可以放在动画中。透明度为0时需要安排数字的变化,否则数字的变化会很突兀。数字出现和消失的动画可以通过添加相邻的关键帧来快速返回。另外文中用到了一些比较新的属性,比如@property,自定义计数器,不过没关系,文中也提到了其他的解决方案,动画的整体思路不变,如何观察和分解动画是最重要的。