文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

动画合成小技巧!CSS 实现动感的倒计时效果

2024-12-01 19:55

关注

Kapture 2022-06-26 at 16.57.42

这是一个非常“动感”的倒计时效果,在一些活动开场中比较常见,分析一下整个动画过程,不难发现,有以下几类动画:

不知道小伙伴能否观察出来呢?下面来一起来看看具体实现吧!

一、数字的变化

先来看数字的变化。

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

在以前,数字的变化可能需要创建多个标签,然后改变位移来实现。

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

这种方式需要创建多个标签,略微繁琐,也不易扩展。现在有更简洁的方式可以实现了,那就是 CSS @property[1]。这是干什么的呢?简单来讲,可以自定义属性,在这个例子中,可以让数字像颜色一样进行过渡和动画,可能不太懂,直接看例子吧!

假设 HTML 是这样的:

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

然后我们通过 CSS 变量将数字渲染到页面,这里需要借助伪元素和计数器。

有兴趣的可以参考这篇文章:小tips: 如何借助content属性显示CSS var变量值[2]。

count-down::after{
counter-reset: time var(--t);
content: counter(time);
}

效果如下:

image-20220626135133534

如何让这个数字变化呢?可以用到 CSS 动画:

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

效果如下:

Kapture 2022-06-26 at 13.55.42

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

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

对的,仅仅添加这一小段 CSS,效果就出来了。

Kapture 2022-06-26 at 14.03.07

是不是很神奇?可以这么理解,通过@property定义后,这个变量--t本身可以单独设置动画了,就像颜色变化一样。

另外,使用计数器的好处是可以随意更换类型,比如将上面的阿拉伯数字换成中文计数,只需要更换计数器类型就行了。

完整类型可以参考:list-style-type[3]。

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

效果如下:

Kapture 2022-06-26 at 14.14.20

是不是非常方便呢?

二、倒计时的终点

上面的计数器最后的终点是“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;
}

·效果如下:

Kapture 2022-06-26 at 14.46.18

注意这里动画函数是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规则详细介绍[4]。

然后是应用;

count-down::after{

counter-reset: time var(--t);
content: counter(time, stop);
}

这样也能达到相同的效果,实现也更加优雅;

Kapture 2022-06-26 at 14.46.18

三、缩放和透明度变化

这两个动画其实是同时进行的,可以放在一个动画里。

@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;
}

效果如下:

Kapture 2022-06-26 at 16.47.09

是不是稍微有些突兀?因为数字的变化是突然的,需要将数字的变化隐藏到透明度为 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;
}

这样就自然多了;

Kapture 2022-06-26 at 16.51.37

不过还有优化的空间。比如现在数字动画有些太连贯了,如果希望数字出现后稍微停留一小会,或者说希望出现的慢一点,消失的快一点,如何处理呢?其实这比想象中的要容易许多,只需要改一下关键帧位置就行了,如下:

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

20%{
opacity: 0;
transform: scale(0.4);
}
}

同时,延迟的时间也需要改成 0.8 秒,效果如下:

Kapture 2022-06-26 at 16.57.42

这样就实现了文章开头所示效果。

下面重点来了~完整代码如下:

@property --t { 
syntax: '';
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)[5]或者CSS count-down(juejin.cn)[6]

另外,demo 中还有个小彩蛋,点击可以重新运行动画,实现方式如下:

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

四、其他动画效果

除了缩放效果,还可以有一些位移的动画,比如这样的:

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

20%{
opacity: 0;
transform: translateY(100px);
}
}

效果如下:

Kapture 2022-06-26 at 17.07.00

是不是有点奇怪?动画不够连贯,一会向下一会向上,有没有办法消失和出现都是从上到下的呢?当然也是可以的,实现如下:

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

20%{
opacity: 0;
transform: translateY(100px);
}

21%{
opacity: 0;
transform: translateY(-100px);
}
}

这里多加了一个非常“邻近”的关键帧,表示在透明状态下,“迅速”改变位移,这样在数字出现时的动画就感觉是从上到下的,整体更为流畅,效果如下:

Kapture 2022-06-26 at 17.15.02

还可以调整一下前面的缩放效果,让出来的时候更大,效果也更为震撼。

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

20%{
opacity: 0;
transform: scale(.4);
}

21%{
opacity: 0;
transform: scale(5);
}
}

效果如下:

Kapture 2022-06-26 at 17.38.54

当然还有其他效果,比如旋转,斜切等,这就需要发挥你的想象了~

五、总结和说明

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

另外,文中用了一些比较新的属性,比如 @property,还有自定义计数器,不过没关系,文中也都提到了其他解决方案,动画的整体思路是不变的,如何观察和分解动画,这个才是最重要的。

来源:前端侦探内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯