纯css实现:单行文本的打字机动画效果

6,096 阅读5分钟

这是我参与更文挑战的第19天,活动详情查看: 更文挑战

前言

今天准备给个人博客的时间线页面添加一个动态打字的效果,之前的打字机效果我一直用JS实现的。之前写了一篇文章申请一个免费的毒鸡汤api,并且用原生JS实现竖行文本的打字机效果,里面用原生JS实现了打字机的效果。不过今天我打算来尝试一下用css实现打字机的效果,想法是根据文字盒子的宽度来给文字盒子添加动态变化的宽度,这样做就无法适用于多行文本,说起来,如果使用多行文本做打字机效果的话,除非是满足一定的逻辑场景,不然很考验用户的耐心,因为大多数人并不想一直盯着一个动画看很长时间。

限于css实现的方式是文字盒子宽度的变化,所以能做的只是单行文本的打字机效果。

思路

文字是完全展示的,但是通过css动画效果,使得文字盒子的宽度从小到大动态变化,这样的话看起来文字也随着盒子宽度的增加而逐渐完全显示。 1,光标效果,可以使用伪元素 after 实现,或者直接给文字盒子设置右边框。 2,文字盒子的动画效果应该是逐字展示的动画,而不是平滑连贯的。

实现过程

首先把文字的动画过程实现出来:文字要确定不换行,可以使用 white-space: nowrap; ,然后宽度应该为字的总宽度,例子中15个字,即15em,动画从宽度为0开始运行。代码如下:

    <style>
        @keyframes typing {
            from { width: 0 }
        }
        p {
            font-size: 22px;
            width: 15em;
            white-space: nowrap;
            overflow: hidden;
            animation: typing 5s; 执行typing动画,在5s内执行完毕
        }
    </style>

    <p>这是一段文本呀,请用打字机实现</p>

运行一下,实现效果如下:

GIF 2021-6-19 22-52-42.gif

可以看到,动画并没有逐字展现,而是直接平滑连贯的展示出来了,我们可以使用 steps() 来解决平滑过渡的问题。

steps() 有两个参数: 参数一是表示动画分割的段数。 参数二是表示分成几段后,是由段数的开始帧还是结束帧去执行动画。默认end。

好了,那么下面让我们来添加 steps() 看一下:

    <style>
        @keyframes typing {
            from { width: 0 }
        }
        p {
            font-size: 22px;
            width: 15em;
            white-space: nowrap;
            overflow: hidden;
            animation: typing 5s steps(15); 执行typing动画,在5s内执行完毕,分15段执行
        }
    </style>

    <p>这是一段文本呀,请用打字机实现</p>

运行一下,实现效果如下:

GIF 2021-6-19 23-09-18.gif

可以看到,动画已经变成逐帧展示的了~ 离胜利又近了一步!下面就是添加光标了,根据我们的思路,我们来使用右边框来添加边框,边框动画为边框颜色变成黑色,边框为透明边框,这样文字打印结束后光标会有一个消失不见的效果。代码如下:

    <style>
        @keyframes typing {
            from { width: 0 }
        }
        @keyframes caret {
            50% { border-right-color: #000; }
        }
        p {
            font-size: 22px;
            width: 15em;
            white-space: nowrap;
            overflow: hidden;
            animation: typing 5s steps(15), 执行typing动画,在5s内执行完毕,分15段执行
                       caret .5s steps(1) infinite; 执行typing动画,在0.5s内执行完毕,分1段执行,循环执行
            border-right: 1px solid transparent;

        }
    </style>

    <p>这是一段文本呀,请用打字机实现</p>

运行一下,实现效果如下:

GIF 2021-6-19 23-26-45.gif

完美实现,但是后面的光标效果一直在持续,这让我们很是苦恼,因为文字打字机效果完成之后,光标应该消失才对,那么我们该怎么改这个动画呢?我们自然能想到animation-iteration-count ,这个属性定义动画应该播放多少次。

动画 typing 执行的时间是5s,也就是说,我们要在5s后停止 caret 动画即可,这样两个动画执行时间是一样的。 caret 动画每次执行时间是0.5s,5s应该执行10次,即:

    <style>
        @keyframes typing {
            from { width: 0 }
        }
        @keyframes caret {
            50% { border-right-color: #000; }
        }
        p {
            font-size: 22px;
            width: 15em;
            white-space: nowrap;
            overflow: hidden;
            animation: typing 5s steps(15), 执行typing动画,在5s内执行完毕,分15段执行
                       caret .5s steps(1) 10; 执行typing动画,在0.5s内执行完毕,分1段执行,循环执行10border-right: 1px solid transparent;

        }
    </style>

    <p>这是一段文本呀,请用打字机实现</p>

运行一下,实现效果如下:

GIF 2021-6-19 23-33-40.gif

这次真的是完美实现了,加到我的个人博客中看一下效果吧:

GIF 2021-6-19 23-41-38.gif

后记

今天是我坚持日更的第十九天,又到快乐的周末啦!在吃喝玩乐的过程中,也要记得学习啊~ 每天输出一点点,进步一点点。有志者,事竟成。大家一起加油吧~

更文挑战的文章目录如下: