Skip to content

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

打字机效果

1.安装类型声明

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

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

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

2.安装 typeit-react 模块

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

pnpm
pnpm install typeit-react

import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

3.创建自定义类型声明

  • 如果没有找到现成的类型声明,【自己实操是有的,跳过此步骤】
  • 你可以为 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;
}

4.组件中引入

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

tsx
import TypeIt from 'typeit-react';

5.使用

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';
// highlight-next-line
import TypeIt from 'typeit-react';

const variants: Variants = {
  // highlight-next-line
  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}
      // highlight-next-line
      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}
        // highlight-next-line
        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">
           // highlight-start
          <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']} // 添加彩虹色类
            // highlight-end
          />
        </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}>
            // highlight-start
          <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">
            // highlight-end
              <Translate id="hompage.hero.introduce">自我介绍</Translate>
            </a>
          </MovingButton>
        </motion.div>
      </div>
      <motion.div className={styles.background}>
        <HeroSvg />
        <Circle />
      </motion.div>
    </motion.div>
  )
}
最近更新