CSS实现打字机动画效果

效果展示

image


CSS3 animation(动画)属性

语法:

animation: name duration timing-function delay iteration-count direction fill-mode play-state;
  • name
    • 设置绑定哪个keyframe
  • duration
    • 设置动画多少秒或毫秒完成
  • timing-function
    • 设置动画如何完成一个周期
  • delay
    • 设置动画在启动前的延迟间隔。
  • iteration-count
    • 定义动画的播放次数。
  • direction
    • 指定是否应该轮流反向播放动画。
  • fill-mode
    • 规定当动画不播放时(当动画完成时,或当动画有一个延迟未开始播放时),要应用到元素的样式。
  • play-state
    • 指定动画是否正在运行或已暂停。

详细参考:

CSS3 animation(动画) 属性


打字机效果的实现

实现一个字一个字移动效果的关键知识:

@keyframes typewriter {
    to {
        left: 100%;
    }
}

animation: typewriter 3s steps(18) forwards;
  • steps函数

    • 有两个参数。
      • 第一个参数的意思是,这个动画分成多少段执行。这里就是文本有几个字,就分多少段。
      • 第二个参数表示分成几段后,是start还是end去执行动画。参数二有两个可选值start和end,默认是end。(这里没有使用到)
  • forwards(fill-mode属性)

    • 把物体动画地从一个地方移动到另一个地方,并让它停留在那里。
  • 设置等宽字体

    • 如果每一个字的宽度不一样,就无法保证每次移动会正好一个字的宽度。
    • font-family: monospace;
      

实现光标闪烁效果的关键知识

@keyframes flashing {
    to {
        opacity: 0;
    }
}

animation: flashing .3s ease-out forwards infinite; 
  • ease-out
    • 动画以低速结束。
  • forwards(fill-mode属性)
    • 把物体动画地从一个地方移动到另一个地方,并让它停留在那里。
  • infinite
    • 指定动画播放无限次(永远)

代码示例

下列代码,使用了JS来动态获取文字的个数,从而设置相应的steps值。

思路是:

一个before伪元素来遮挡文字。

一个after伪元素来模拟闪烁的光标。

两个伪元素一起做动画向后移动。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS实现打字机动画效果</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        body {
            background-color: #000;
        }

        #app {
            display: inline-block;
            position: relative;
            top: 300px;
            left: 50%;
            /* 设置等宽字体 */
            font-family: monospace;
            color: #FFF;
            font-size: 32px;
            text-align: center;
            transform: translateX(-50%);
        }

        #app::before,
        #app::after {
            position: absolute;
            inset: 0;
            width: 100%;
            height: 100%;
            background-color: #000;
            content: '';
            /* animation: typewriter 3s steps(18) forwards; */
        }

        #app::after {
            width: 5px;
            border-radius: 1em;
            background-color: #fff;
            /* animation: typewriter 3s steps(18) forwards, flashing .3s ease-out forwards infinite; */
        }

        @keyframes typewriter {
            to {
                left: 100%;
            }
        }

        @keyframes flashing {
            to {
                opacity: 0;
            }
        }
    </style>
</head>
<body>
    <div id="app">welcome to my home</div>
    <script>
        // 选中app元素
        const app = document.querySelector('#app');
        // 获取文本长度
        const wordNum = app.outerText.length;
        // 创建一个style标签
        const styleElement = document.createElement('style');

        styleElement.innerHTML = `#app::before {animation: typewriter ${wordNum * 0.2}s steps(${wordNum}) forwards;}`;

        styleElement.innerHTML += `#app::after {animation: typewriter ${wordNum * 0.2}s steps(${wordNum}) forwards, flashing .3s ease-out forwards infinite;}`;
        
        document.head.appendChild(styleElement);
    </script>
</body>
</html>
posted @ 2022-12-13 09:00  笔下洛璃  阅读(1500)  评论(0编辑  收藏  举报