Published on

模拟打字效果

Authors
  • avatar
    Name
    yushenw
    Linkedin

实现聊天应用中的打字机效果(即消息一个字一个字地显示出来,模仿人类打字的效果)是一种提高用户体验的常用技术。在前端开发中,这可以通过多种方式实现,以下是一些常用的方法和步骤,主要使用 JavaScript:

方法一:使用 setTimeout 函数

这是实现打字效果最基础的方法,通过递归调用setTimeout来逐字显示文本。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Typewriter Effect</title>
<style>
    body {
        font-family: 'Courier New', Courier, monospace;
        font-size: 24px;
        margin: 40px;
    }
</style>
</head>
<body>
<div id="message"></div>
<script>
    function typeWriter(text, n) {
        if (n < (text.length)) {
            document.getElementById('message').innerHTML += text.charAt(n);
            setTimeout(function() {
                typeWriter(text, n + 1);
            }, 100); // Adjust typing speed by changing delay (100 ms here)
        }
    }

    const text = "Hello, this is an example of a typewriter effect!";
    typeWriter(text, 0);
</script>
</body>
</html>

方法二:使用 setInterval 函数

这个方法使用 setInterval 来定期执行函数,逐字显示文本,并在文本结束时清除间隔。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Typewriter Effect</title>
<style>
    body {
        font-family: 'Courier New', Courier, monospace;
        font-size: 24px;
        margin: 40px;
    }
</style>
</head>
<body>
<div id="message"></div>
<script>
    function typeWriter(text) {
        let i = 0;
        const speed = 100; // Typing speed in milliseconds
        const interval = setInterval(function() {
            if (i < text.length) {
                document.getElementById('message').innerHTML += text.charAt(i);
                i++;
            } else {
                clearInterval(interval);
            }
        }, speed);
    }

    const text = "Hello, this is another example of a typewriter effect!";
    typeWriter(text);
</script>
</body>
</html>

方法三:使用 CSS 动画

如果你想要一个简单的打字效果并可以使用 CSS 实现,可以考虑以下方法,虽然它不是逐字显示,而是逐渐显示整行文本。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CSS Typewriter Effect</title>
<style>
    body {
        font-family: 'Courier New', Courier, monospace;
        font-size: 24px;
        margin: 40px;
    }
    .typewriter h1 {
        overflow: hidden; /* Ensures the content is not revealed until the animation */
        border-right: .15em solid orange; /* The cursor */
        white-space: nowrap; /* Keeps the content on a single line */
        margin: 0 auto; /* Gives that scrolling effect as the typing happens */
        letter-spacing: .15em; /* Adjust as needed */
        animation: 
        typing 3.5s steps(40, end),
        blink-caret .75s step-end infinite;
    }

    /* The typing effect */
    @keyframes typing {
        from { width: 0 }
        to { width: 100% }
    }

    /* The typewriter cursor effect */
    @keyframes blink-caret {
        from, to { border-color: transparent }
        50% { border-color: orange; }
    }
</style>
</head>
<body>
<div class="typewriter">
    <h1>The quick brown fox jumps over the lazy dog</h1>
</div>
</body>
</html>

这些方法各有优劣,可以根据实际需要选择使用。对于真实的打字效果,setTimeoutsetInterval 的方法更加灵活和适用,因为它们可以控制每个字符的显示。CSS 方法提供了简单和平滑的视觉效果,但不具备逐字逻辑的控制灵活性。

step函数

在 CSS 动画中,steps() 函数和 step-end 关键词是用来控制动画中每一帧的切换方式的。它们提供了一种方式来分割动画的时间线,使动画以离散的步骤而非连续平滑的过渡执行。这在创建某些特定类型的动画,如打字机效果,时非常有用。

steps() 函数

steps() 函数用于将动画分成几个阶段,使动画在每个阶段“跳转”到下一个状态,而不是平滑过渡。函数的语法如下:

animation: animation-name duration steps(number-of-steps, jump-term) [other parameters];
  • number-of-steps:指定动画应该分成多少步。例如,steps(40, end) 表示动画被分成 40 步。
  • jump-term:可以是 startendend 表示每一步的变化在步骤的结尾发生,而 start 表示变化在步骤的开始发生。通常在打字效果中使用 end,因为我们希望字符在每个时间间隔的结束时显现,这样看起来每次添加的字符都会停留一段固定时间。

例如:

typing 3.5s steps(40, end)

这表示动画总持续时间为 3.5 秒,动画被分为 40 步,每步的变化都在该步骤的结尾时刻发生,这适合模拟打字机的效果,因为字符逐一显示,并且在下一个字符显示之前都保持静止。

step-end 关键词

step-endsteps() 函数的一种特殊用例,相当于 steps(1, end)。这意味着动画在结束时立即跳转到最终状态,而动画的其余部分都保持在初始状态。这通常用于需要快速切换状态的场景。

在光标闪烁动画中的应用如下:

blink-caret .75s step-end infinite;

这表示光标的动画周期为 0.75 秒,使用 step-end(等同于 steps(1, end))保持光标在大部分时间内可见,然后瞬间切换为不可见,再立即返回到可见状态,形成闪烁效果。infinite 表示动画无限次重复。

总的来说,这两种方式通过控制动画帧的更新时机,为创建具有特定视觉效果的动画(如打字机效果和光标闪烁)提供了简单有效的手段。