Skip to content
0

文章发布较早,内容可能过时,阅读注意甄别。

打字机效果

安装类型声明

首先,确认是否有适用于 typeit-react 的类型声明包。某些库没有自带类型声明,但社区可能提供了相关的声明包。

运行以下命令来安装 @types 类型声明包(如果有的话):

sh
pnpm install @types/typeit-react --save-dev
  • 如果没有找到对应的类型声明包,继续执行下面的步骤。

安装 typeit-react 模块

确保你已经安装了 typeit-react 模块

sh
pnpm install typeit-react
json
"typeit-react": "^2.7.2"
yaml
typeit-react:
  specifier: ^2.7.2
  version: 2.7.2

创建自定义类型声明

  • 如果没有找到现成的类型声明,【自己实操是有的,跳过此步骤】
  • 你可以为 typeit-react 创建一个自定义的声明文件。

在项目的 src 目录下创建一个 types 文件夹(如果没有的话),然后在 types 文件夹内创建一个 typeit-react.d.ts 文件,并添加以下内容:

ts
declare module "typeit-react" {
  // 在这里添加自定义的类型声明
  import { FC } from "react";

  interface TypeItProps {
    options?: any; // 根据需要添加具体的选项类型
    children?: React.ReactNode;
  }

  const TypeIt: FC<TypeItProps>;

  export default TypeIt;
}

组件中引入

在 src\components\landing\Hero\index.tsx 组件中引入

tsx
import TypeIt from "typeit-react";

使用

tsx
import { type Variants, motion } from "framer-motion";
import Translate from "@docusaurus/Translate";
import HeroSvg from "./img/hero.svg";
import SocialLinks from "@site/src/components/SocialLinks";
import { MovingButton } from "../../magicui/moving-border";
import styles from "./styles.module.css";
import TypeIt from "typeit-react"; 

const variants: Variants = {
  visible: (i) => ({
    opacity: 1,
    y: 0,
    transition: {
      type: "spring",
      damping: 25,
      stiffness: 100,
      duration: 0.3,
      delay: i * 0.3,
    },
  }),
  hidden: { opacity: 0, y: 30 },
};

function Circle() {
  return <div className={styles.circle} />;
}

function Name() {
  return (
    <motion.div
      className={styles.hero_text}
      custom={1}
      initial="hidden"
      animate="visible"
      variants={variants}
      onMouseMove={(e) => {
        e.currentTarget.style.setProperty("--x", `${e.clientX}px`);
        e.currentTarget.style.setProperty("--y", `${e.clientY}px`);
      }}
    >
      <Translate id="homepage.hero.greet">你好! 我是</Translate>
      <span
        className={styles.name}
        onMouseMove={(e) => {
          const bounding = e.currentTarget.getBoundingClientRect();
          e.currentTarget.style.setProperty("--mouse-x", `${bounding.x}px`);
          e.currentTarget.style.setProperty("--mouse-y", `${bounding.y}px`);
        }}
      >
        <Translate id="homepage.hero.name">Hyde</Translate>
      </span>
      <span className="ml-1">👋</span>
    </motion.div>
  );
}

export default function Hero() {
  return (
    <motion.div className={styles.hero}>
      <div className={styles.intro}>
        <Name />
        <motion.p
          custom={2}
          initial="hidden"
          animate="visible"
          variants={variants}
          className="max-lg:px-4"
        >
          <TypeIt
            getBeforeInit={(instance) => {
              instance
                .type("明心静性,爱自己。")
                .pause(2000) // 停顿3秒
                .delete(9)
                .pause(500)
                .type("越长大,越孤独!")
                .pause(2000); // 停顿3秒
              return instance;
            }}
            options={{ loop: true, speed: 200 }} // 添加 speed 参数
            className={styles["rainbow-text"]} // 添加彩虹色类
          />
        </motion.p>
        <motion.div
          custom={3}
          initial="hidden"
          animate="visible"
          variants={variants}
        >
          <SocialLinks />
        </motion.div>
        <motion.div
          className="mt-4 flex gap-2"
          custom={4}
          initial="hidden"
          animate="visible"
          variants={variants}
        >
          <MovingButton
            borderRadius="1.25rem"
            className="relative z-10 flex items-center rounded-2xl border border-neutral-200 border-solid bg-background px-5 py-3 text-center font-semibold text-base dark:border-neutral-800"
          >
            <a href={"/"} className="font-semibold">
              <Translate id="hompage.hero.introduce">自我介绍</Translate>
            </a>
          </MovingButton>
        </motion.div>
      </div>
      <motion.div className={styles.background}>
        <HeroSvg />
        <Circle />
      </motion.div>
    </motion.div>
  );
}
最近更新