如何用React为代码块创建打字机效果(附代码)

2,149 阅读6分钟

在打字机效果下,文字是一个字母一个字母地显示,而不是一次全部显示,使文字看起来好像是在实时书写。你可以在Codepen的登陆页面上找到一个代码块打字机效果的例子,它使用语法高亮,一种特殊的颜色格式,以代码的形式轻松显示书写的文本。

在这篇文章中,我们将学习如何用React从头开始建立一个类似的代码块打字机效果。我们还将演示另一种方法,即使用预先存在的打字机包。要跟上这个教程,你需要有React的基本知识。我们将涵盖以下内容。

安装依赖项

如果你还没有安装React,在你的系统中导航到你的项目目录,打开一个命令行窗口,并在其中运行以下bash脚本:

npx create-react-app typewriter

上面的命令创建了一个名为typewriter 的React项目文件夹,里面有构建我们的应用程序所需的所有依赖项。为了方便我们的应用程序的样式,我们将使用Tailwind CSS。你可以通过在你的CLI中运行以下命令来安装Tailwind CSS:

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

一旦安装完成,修改tailwind.config.js 文件以允许支持jsx 元素,如下所示:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

最后,在index.css 的顶层添加以下Tailwind CSS指令:

@tailwind base;
@tailwind components;
@tailwind utilities;

建立一个打字机效果

我们的打字机效果将由两个主要部分组成,一个容器,我们将在其中保留我们想要动画化的文本,另一个是模仿打字机的闪烁光标。

打字机显示区

首先,在我们的App.js 文件中,我们将为打字机效果建立一个显示窗口:

import "./App.css";
import {React, useState, useEffect} from "react";

function App() {
  const [text1, setText1] = useState("const sayHello = () = {");
  const [text2, setText2] = useState("Console.log('hello')");
  const [text3, setText3] = useState("//This prints out Hello World");
  return (
    <div className=" flex h-screen justify-center items-center">
      <div className=" h-1/2 w-1/2 bg-black rounded-md flex items-center pl-6">
        {/* type writer display */}
        <span>
          <div className=" text-white text-2xl blinking-cursor">{text1}</div>
          <div className=" text-white text-2xl blinking-cursor">{text2}</div>
          <div className=" text-white text-2xl blinking-cursor">{text3}</div>
          <div className=" text-white text-2xl blinking-cursor">{`}`}</div>
        </span>
      </div>
    </div>
  );
}

export default App;

上面的代码创建了一个容器,我们将在其中保留我们想用打字机效果制作动画的文本。如果我们用npm start 命令运行上面的代码,我们将得到一个类似于下图的 "Hello, World!"的结果:

Typewriter Effect Container

添加一个闪烁的光标

接下来,我们将在文本的结尾处建立并添加一个闪烁的光标。将下面的代码添加到index.css

.bg-code{
  background-color: rgb(40, 42, 54);
}

.blinking-cursor::after {
  content: "|";
  animation: blink 1s step-end infinite;
}
@keyframes blink {
  from,
  to {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
}

上面的CSS样式在每个文本的结尾处添加一个| ,造成一个模仿光标的闪烁效果。

给文本添加打字机效果

为了创建我们的打字机效果,我们将使用React的useEffect Hook。要做到这一点,在你的代码中添加以下修改:

const first_text = "const sayHello = () = {";
  const second_text = "console.log('hello')";
  const third_text = "//This prints out Hello World";

  const [text1, setText1] = useState("");
  const [text2, setText2] = useState("");
  const [text3, setText3] = useState("");

  useEffect(() => {
    const timeout = setTimeout(() => {
      setText1(first_text.slice(0, text1.length + 1));
    }, 100);
    return () => clearTimeout(timeout);
  }, [text1]);

  useEffect(() => {
    const timeout = setTimeout(() => {
      setText2(second_text.slice(0, text2.length + 1));
    }, 250);

    return () => clearTimeout(timeout);
  }, [text2]);

  useEffect(() => {
    const timeout = setTimeout(() => {
      setText3(third_text.slice(0, text3.length + 1));
    }, 300);

    return () => clearTimeout(timeout);
  }, [text3]);

在上面的代码中,我们使用了一个setTimeout 函数和一个分片操作符。setTimeout 函数在指定的时间间隔后执行代码块。我们使用splice操作符将整个字符串分成若干个字符,并逐一返回文本。

对于回调,我们使用状态。每当我们输入一个新的字符,状态就会被更新,setTimeout 函数就会被执行。因此,setTimeout ,直到整个文本被完全打完。

删除和重打文本

为了实现打字机的循环效果,我们将添加两个状态,isdeletingistyping ,分别用于用户想要删除文本和完成打字的时候:

const textState = ["istyping", "isdeleting"];
const [typing, setTyping] = useState(textState[0]);

function sleep(ms) {
    return new Promise((resolve) => setTimeout(resolve, ms));
}

现在我们已经为打字和删除文本创建了状态,让我们使用sleep 函数在这两个状态的切换之间创建一个延迟。因此,当用户完全完成输入文本时,我们将实现一个暂停。让我们继续修改我们的代码来使用这些状态,如下所示:

useEffect(() => {
    const timeout = setTimeout(() => {
      if (typing === "istyping" && text1 !== first_text) {
        setText1(first_text.slice(0, text1.length + 1));
      }
      else if (text1 === first_text && typing === "istyping"){
        sleep(2000).then(()=>{
        setTyping(textState[1])
        })
      }
      else if ( (text1 === first_text && typing==="isdeleting") || typing === "isdeleting" ) {
        setText1(first_text.slice(0, text1.length - 1));
        if(text1.length<=2){
            setTyping(textState[0])
        }
      }
    }, 100);
  return () => clearTimeout(timeout);
}, [text1, typing1]);

在上面的代码中,我们检查typing 是否等于istyping ,以及文本是否不等于完整的字符串。如果这返回true ,我们就会运行打字效果。当文本与完整的字符串相似时,我们使用sleep 函数,在两秒后切换到isdeleting 状态。

最后,我们使用最后一个条件,每次删除文本一个字符,直到只剩下一个字母。这时,typing 状态被设置回istyping ,整个过程重新开始。我们对text2text3 也做同样的处理。

突出显示代码语法

为了突出我们的文本看起来像一个代码块,我们将通过CLI安装React语法高亮程序

npm i react-syntax-highlighter

当这个包安装好后,我们可以在App.js 中导入它,并按如下方式使用它:

import SyntaxHighlighter from 'react-syntax-highlighter';
import { docco } from 'react-syntax-highlighter/dist/esm/styles/hljs';
//...
<span>
  <div className=" text-2xl">
    <SyntaxHighlighter className="blinking-cursor" language="javascript" style={dracula}>
      {text1}
    </SyntaxHighlighter>
  </div>
  <div className=" text-2xl">
    <SyntaxHighlighter className="blinking-cursor" language="javascript" style={dracula}>
      {text2}
    </SyntaxHighlighter>
  </div>
  <div className=" text-2xl">
    <SyntaxHighlighter className="blinking-cursor" language="javascript" style={dracula}>
      {text3}
    </SyntaxHighlighter>
  </div>
  <div className=" text-2xl">
    <SyntaxHighlighter className="blinking-cursor" language="javascript" style={dracula}>
      {`}`}
    </SyntaxHighlighter>
  </div>
</span>

现在我们已经实现了我们的Syntax Higlighter 组件,我们可以把我们的打字机效果包装起来。

使用预先建立的打字机库

作为一个替代编码和定制我们自己的打字机效果的方法,我们可以使用一个预建的库来节省时间。

处理打字机效果的库的一个例子是 [react-typewriter-effect](https://www.npmjs.com/package/typewriter-effect).我们可以通过CLI用以下命令安装这个包:

npm i react-typewriter-effect

一旦安装完成,我们可以在我们的应用程序中使用它,如下所示,以获得打字机效果:

import TypeWriterEffect from 'react-typewriter-effect';
//...

<TypeWriterEffect
  textStyle={{ fontFamily: 'Red Hat Display' }}
  startDelay={100}
  cursorColor="black"
  text="Text for typewriting effect here"
  typeSpeed={100}
  eraseSpeed={100}
/>

上面的代码将为指定的文本字符串产生打字机效果。

总结

在这篇文章中,我们已经学会了如何使用React轻松地创建一个打字机效果。在你的网站或应用程序中实现这一功能,可以通过增加视觉趣味和引导用户的注意力来改善你的用户界面。你可以在我们从头开始构建的打字机效果上添加更多你自己的定制,或者你可以使用一个为你实现这一功能的库,比如react-typewriter-effect

我希望你喜欢这篇文章,如果你有任何问题,请务必留下评论。编码愉快!