乐趣区

关于css:动画合成小技巧CSS-实现动感的倒计时效果

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

介绍一个 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,还有自定义计数器,不过没关系,文中也都提到了其余解决方案,动画的整体思路是不变的,如何察看和合成动画,这个才是最重要的。最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤

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

退出移动版