欢送关注微信公众号: 前端侦探

介绍一个 CSS 动画合成小技巧。先看成果

这是一个十分“动感”的倒计时成果,通常在一些流动收场中比拟常见,剖析一下整个动画过程,不难发现,有以下几类动画

  1. 数字的变动
  2. 放大和放大
  3. 透明度变动

不晓得小伙伴是否观察出来呢?上面来一起来看看具体实现吧

一、数字的变动

先来看数字的变动。

这个技巧在之前的文章:还在应用定时器吗?CSS 也能实现电子时钟 中首次用到,这里再次介绍一下

在以前,数字的变动可能须要创立多个标签,而后扭转位移来实现

<count-down>    <span>5</span>  <span>4</span>  <span>3</span>  <span>2</span>  <span>1</span></count-down>

这种形式须要创立多个标签,稍微繁琐,也不易扩大。当初有更简洁的形式能够实现了,那就是 CSS @property。这是干什么的呢?简略来讲,能够自定义属性,在这个例子中,能够让数字像色彩一样进行过渡和动画,可能不太懂,间接看例子吧

假如 HTML 是这样的

<count-down style="--t: 5"></count-down>

而后咱们通过 CSS 变量将数字渲染到页面,这里须要借助伪元素和计数器

有趣味的能够参考这篇文章:小tips: 如何借助content属性显示CSS var变量值
count-down::after{  counter-reset: time var(--t);  content: counter(time);}

成果如下

如何让这个数字变动呢?能够用到 CSS 动画

@keyframes count {    to {        --t: 0    }}count-down::after{    --t: 5;    counter-reset: time var(--t);    content: counter(time);    animation: count 5s forwards;}

成果如下

当初的成果仅仅是5秒后,数字从 5 变成了 0,并没有 5 => 4 => 3 => 2 => 1 这种阶段变动。而后最重要的一步来了,加上以下自定义属性

@property --t {     syntax: '<integer>';    inherits: false;    initial-value: 0;}

对的,仅仅增加这一小段 CSS,成果就进去了

是不是很神奇?能够这么了解,通过@property定义后,这个变量--t自身能够独自设置动画了,就像色彩变动一样。

另外,应用计数器的益处是能够随便更换类型,比方将下面的阿拉伯数字换成中文计数,只须要更换计数器类型就行了

残缺类型能够参考:list-style-type
count-down::after{    --t: 5;    counter-reset: time var(--t);    content: counter(time, cjk-decimal); /*中日韩十进制数*/    animation: count 5s forwards;}

成果如下

是不是十分不便呢?

二、倒计时的起点

下面的计数器最初的起点是“0”,显然咱们须要一些特定的提醒,比方“Go~”

如何扭转最初一帧的状态呢?这里有两种形式:

  1. 通过动画笼罩
  2. 通过计数器笼罩

首先来看第一种形式,这个比拟好了解,从新定义一个动画,在倒计时完结后,将最初一帧重置一下

@keyframes stop {    to {        content: 'Go~';    }}count-down::after{    --t: 5;    counter-reset: time var(--t);    content: counter(time);    animation: count 5s forwards,    stop 5s step-end forwards;}

·成果如下

留神这里动画函数是step-end,为啥是这个呢?step-end也可写作steps(1,end),你能够了解为在整个动画只有两种状态,在运行过程中,都是初始状态,只有达到最初一帧才扭转状态,上面是 MDN 的截图

上面来看第二种形式,通过自定义计数器来实现。原理其实和 JS 思维有些相似,当数字为 0 时,让计数器指定一个非凡的值,具体实现如下

@counter-style stop {    system: cyclic;    symbols: "Go~";    range: 0 0;}

这里简略解释一下,这里有个range属性,示意计数器的范畴,因为这里只须要指定为 0,所以是区间0 0。而后是system,示意计算零碎,这里为cyclic,示意循环应用开发者提供的一套字符,字符由symbos定义。而后symbos示意计算符号,也就是具体展现的字符,这里指定为Go~就行了。

这部分自定义计数器内容比较复杂,也比拟新,有趣味的能够参考张鑫旭的这篇文章:CSS @counter-style规定具体介绍

而后是利用

count-down::after{      /**/    counter-reset: time var(--t);    content: counter(time, stop); /*自定义计数器*/}

这样也能达到雷同的成果,实现也更加优雅

三、缩放和透明度变动

这两个动画其实是同时进行的,能够放在一个动画里

@keyframes shark {    0%{        opacity: 1;        transform: scale(1);    }        50%{        opacity: 0;        transform: scale(0.4);    }}

而后设置动画时长为 1s,循环 5 次

count-down::after{    --t: 5;    counter-reset: time var(--t);    content: counter(time);    animation: count 5s steps(5) forwards,    shark 1s 5;}

成果如下

是不是略微有些突兀?因为数字的变动是忽然的,须要将数字的变动暗藏到透明度为 0 的时候,为了达到这种成果,只须要将闪动动画提早 0.5 秒即可

count-down::after{    --t: 5;    counter-reset: time var(--t);    content: counter(time);    animation: count 5s steps(5) forwards,    shark 1s .5s 5; /*提早 0.5s*/}

这样就天然多了

不过还有优化的空间。比方当初数字动画有些太连贯了,如果心愿数字呈现后略微停留一小会,或者说心愿呈现的慢一点,隐没的快一点,如何解决呢?其实这比设想中的要容易许多,只须要改一下关键帧地位就行了,如下

@keyframes shark {    0%{        opacity: 1;        transform: scale(1);    }        20%{        opacity: 0;        transform: scale(0.4);    }}

同时,提早的工夫也须要改成 0.8 秒,成果如下

这样就实现了文章结尾所示成果

上面重点来了~残缺代码如下

@property --t {     syntax: '<integer>';    inherits: false;    initial-value: 0;}@counter-style stop {    system: cyclic;    symbols: "Go~";    range: infinite 0;}html,body{    margin: 0;    height: 100%;    display: grid;    place-content: center;}count-down{    display: flex;    align-items: center;    justify-content: center;    font-family: Consolas, Monaco, monospace;    font-size: 120px;}count-down::after{    --t: 5;    --dur: 1;    counter-reset: time var(--t);    content: counter(time, stop);    animation: count calc( var(--t) * var(--dur) * 1s ) steps(var(--t)) forwards,    shark calc(var(--dur) * 1s) calc(var(--dur) * .8s) calc(var(--t));}@keyframes count {    to {        --t: 0;    }}@keyframes shark {    0%{        opacity: 1;        transform: scale(1);    }        20%{        opacity: 0;        transform: scale(0.4);    }}

你也能够拜访在线例子:CSS count-down(codepen.io)或者CSS count-down(juejin.cn)

另外,demo 中还有个小彩蛋,点击能够从新运行动画,实现形式如下

count-down:active::after{    animation: none;}

四、其余动画成果

除了缩放成果,还能够有一些位移的动画,比方这样的

@keyframes shark {    0%{        opacity: 1;        transform: translateY(0);    }        20%{        opacity: 0;        transform: translateY(100px);    }}

成果如下

是不是有点奇怪?动画不够连贯,一会向下一会向上,有没有方法隐没和呈现都是从上到下的呢?当然也是能够的,实现如下

@keyframes shark {    0%{        opacity: 1;        transform: translateY(0);    }        20%{        opacity: 0;        transform: translateY(100px);    }    21%{        opacity: 0;        transform: translateY(-100px);    }}

这里多加了一个十分“邻近”的关键帧,示意在通明状态下,“迅速”扭转位移,这样在数字呈现时的动画就感觉是从上到下的,整体更为晦涩,成果如下

还能够调整一下后面的缩放成果,让进去的时候更大,成果也更为震撼

@keyframes shark {    0%{        opacity: 1;        transform: scale(1);    }        20%{        opacity: 0;        transform: scale(.4);    }    21%{        opacity: 0;        transform: scale(5);    }}

成果如下

当然还有其余成果,比方旋转,斜切等,这就须要施展你的设想了~

五、总结和阐明

以上就是本文的全部内容了,一个简略的小动画,你学会了吗?上面总结一下实现要点:

  1. 简单动画能够分解成多个简略的动画
  2. 数字的变动能够通过多个标签,扭转位移实现
  3. CSS 计数器能够将数字变量渲染到页面
  4. CSS @property 以将CSS变量设置动画,就像色彩变动一样
  5. CSS 计数器的益处是能够随便更改类型,比方中文计数
  6. 倒计时的起点默认是数字 0 ,能够通过另一个动画重置最初一帧
  7. 能够通过自定义 CSS 计数器,让某个计数符号渲染成指定字符
  8. 缩放和通明的变动是同时进行的,能够放在一个动画里
  9. 数字的变动须要留神安顿在透明度为0的时候,不然数字变动很突兀
  10. 数字的呈现和隐没动画能够增加一个邻近的关键帧来疾速归位

文中用了一些比拟新的属性,比方 @property,还有自定义计数器,不过没关系,文中也都提到了其余解决方案,动画的整体思路是不变的,如何察看和合成动画,这个才是最重要的。最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤

欢送关注微信公众号: 前端侦探