共计 4494 个字符,预计需要花费 12 分钟才能阅读完成。
欢送关注微信公众号:前端侦探
介绍一个 CSS 动画合成小技巧。先看成果
这是一个十分“动感”的倒计时成果,通常在一些流动收场中比拟常见,剖析一下整个动画过程,不难发现,有以下几类动画
- 数字的变动
- 放大和放大
- 透明度变动
不晓得小伙伴是否观察出来呢?上面来一起来看看具体实现吧
一、数字的变动
先来看数字的变动。
这个技巧在之前的文章:还在应用定时器吗?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~”
如何扭转最初一帧的状态呢?这里有两种形式:
- 通过动画笼罩
- 通过计数器笼罩
首先来看第一种形式,这个比拟好了解,从新定义一个动画,在倒计时完结后,将最初一帧重置一下
@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);
}
}
成果如下
当然还有其余成果,比方旋转,斜切等,这就须要施展你的设想了~
五、总结和阐明
以上就是本文的全部内容了,一个简略的小动画,你学会了吗?上面总结一下实现要点:
- 简单动画能够分解成多个简略的动画
- 数字的变动能够通过多个标签,扭转位移实现
- CSS 计数器能够将数字变量渲染到页面
- CSS @property 以将 CSS 变量设置动画,就像色彩变动一样
- CSS 计数器的益处是能够随便更改类型,比方中文计数
- 倒计时的起点默认是数字 0,能够通过另一个动画重置最初一帧
- 能够通过自定义 CSS 计数器,让某个计数符号渲染成指定字符
- 缩放和通明的变动是同时进行的,能够放在一个动画里
- 数字的变动须要留神安顿在透明度为 0 的时候,不然数字变动很突兀
- 数字的呈现和隐没动画能够增加一个邻近的关键帧来疾速归位
文中用了一些比拟新的属性,比方 @property,还有自定义计数器,不过没关系,文中也都提到了其余解决方案,动画的整体思路是不变的,如何察看和合成动画,这个才是最重要的。最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤
欢送关注微信公众号:前端侦探