---
title: React 动效组件展示
description: 展示 NovaBlog 中可用的 React 动效 HTML 组件，包括悬浮卡片、打字机效果、翻转卡片、粒子背景和数学公式卡片
pubDate: 2024-01-20
author: NovaBlog
tags: [React, 动效, 组件, 教程]
category: 教程
heroImage: '/images/hello-world.jpg'
---

import AnimatedCard from '../../components/react/AnimatedCard';
import TypewriterText from '../../components/react/TypewriterText';
import FlipCard from '../../components/react/FlipCard';
import ParticleBackground from '../../components/react/ParticleBackground';
import MathFlipCard from '../../components/react/MathFlipCard';
import MergeTable, { Cell } from '../../components/react/MergeTable';

# React 动效组件展示

NovaBlog 支持在 MDX 中直接使用 React 组件，实现丰富的交互动效。本文展示了一些内置的动效组件示例。

## 🎴 悬浮卡片 (AnimatedCard)

鼠标悬停时卡片会浮起并放大，配合阴影效果增强立体感。

<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))', gap: '1.5rem', margin: '2rem 0' }}>
  <AnimatedCard 
    title="🚀 快速开发" 
    description="使用 Astro + React 实现极速开发体验"
    color="#3b82f6"
    client:load
  />
  <AnimatedCard 
    title="🎨 精美设计" 
    description="内置多种动效组件，轻松创建炫酷页面"
    color="#10b981"
    client:load
  />
  <AnimatedCard 
    title="⚡ 高性能" 
    description="Islands 架构，按需加载，极致性能"
    color="#f59e0b"
    client:load
  />
</div>

## ⌨️ 打字机效果 (TypewriterText)

模拟打字机的逐字显示效果，支持循环播放。

<div style={{ 
  background: '#1a1a2e', 
  padding: '2rem', 
  borderRadius: '1rem', 
  textAlign: 'center',
  margin: '2rem 0'
}}>
  <TypewriterText 
    text="Hello, NovaBlog! 欢迎来到你的新博客..." 
    speed={80}
    loop={true}
    client:load
  />
</div>

### 使用方式

```tsx
<TypewriterText 
  text="你要显示的文字" 
  speed={100}      // 打字速度（毫秒）
  loop={true}      // 是否循环播放
  client:load
/>
```

## 🔄 翻转卡片 (FlipCard)

点击卡片实现 3D 翻转效果，适合展示正反两面内容。

<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', gap: '1.5rem', margin: '2rem 0' }}>
  <FlipCard
    frontTitle="💡 小提示"
    frontDescription="点击翻转查看更多"
    backTitle="✅ 详细说明"
    backDescription="这是一个翻转卡片的背面内容"
    frontColor="#8b5cf6"
    backColor="#06b6d4"
    client:load
  />
  <FlipCard
    frontTitle="🎯 技术栈"
    frontDescription="React + TypeScript"
    backTitle="📦 组件库"
    backDescription="支持自定义样式和动画"
    frontColor="#ec4899"
    backColor="#14b8a6"
    client:load
  />
</div>

### 使用方式

```tsx
<FlipCard
  frontContent={<div>正面内容</div>}
  backContent={<div>背面内容</div>}
  frontColor="#3b82f6"
  backColor="#10b981"
  client:load
/>
```

## ✨ 粒子背景 (ParticleBackground)

基于 Canvas 的粒子动画背景，粒子之间会自动连线，营造科技感。

<ParticleBackground 
  particleCount={60}
  color="#60a5fa"
  speed={0.8}
  client:load
/>

### 自定义内容

<ParticleBackground 
  particleCount={30}
  color="#f472b6"
  speed={1.5}
  client:load
>
  <div style={{ textAlign: 'center' }}>
    <h2 style={{ fontSize: '2.5rem', marginBottom: '1rem' }}>🎉 自定义内容</h2>
    <p>可以在粒子背景上放置任意内容</p>
  </div>
</ParticleBackground>

## 📐 数学公式翻转卡片 (MathFlipCard)

专门用于展示 LaTeX 数学公式的翻转卡片组件。正面显示渲染后的公式，点击"显示 LaTeX"按钮可以查看源码。

### 质能方程

<MathFlipCard latex="E = mc^2" client:load />

### 麦克斯韦方程组

<MathFlipCard latex="\nabla \cdot \mathbf{E} = \frac{\rho}{\varepsilon_0}" client:load />

### 薛定谔方程

<MathFlipCard latex="i\hbar\frac{\partial}{\partial t}\Psi(\mathbf{r},t) = \left[-\frac{\hbar^2}{2m}\nabla^2 + V(\mathbf{r},t)\right]\Psi(\mathbf{r},t)" client:load />

### 傅里叶变换

<MathFlipCard latex="\hat{f}(\xi) = \int_{-\infty}^{\infty} f(x) e^{-2\pi i x \xi} dx" client:load />

### 矩阵运算

<MathFlipCard latex="\begin{pmatrix} a & b \\ c & d \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} = \begin{pmatrix} ax + by \\ cx + dy \end{pmatrix}" client:load />

### 使用方式

```tsx
import MathFlipCard from '../../components/react/MathFlipCard';

<MathFlipCard 
  latex="E = mc^2" 
  displayMode={true}  // 可选，默认为 true
  client:load
/>
```

**属性说明**：
- `latex`：LaTeX 公式字符串
- `displayMode`：是否为块级公式（可选，默认为 true）
- `className`：自定义 CSS 类名（可选）

**特点**：
- 点击"显示 LaTeX"按钮可查看公式源码
- 点击"显示公式"按钮返回渲染结果
- 支持 KaTeX 的所有语法
- 适合教学和技术文档

## 📊 合并单元格表格 (MergeTable)

支持跨行跨列合并的高级表格组件，类似 Typst 的 tablex 功能。

### 基础示例：课程表

<MergeTable 
  headerRows={1}
  client:load
  data={[
    [
      Cell({ children: '时间/星期', header: true, rowspan: 2, align: 'center' }),
      Cell({ children: '星期一', header: true, colspan: 2, align: 'center' }),
      Cell({ children: '星期二', header: true, colspan: 2, align: 'center' }),
      Cell({ children: '星期三', header: true, colspan: 2, align: 'center' }),
    ],
    [
      Cell({ children: '上午', header: true }),
      Cell({ children: '下午', header: true }),
      Cell({ children: '上午', header: true }),
      Cell({ children: '下午', header: true }),
      Cell({ children: '上午', header: true }),
      Cell({ children: '下午', header: true }),
    ],
    ['第1节', '数学', '语文', '英语', '物理', '化学'],
    ['第2节', '语文', '数学', '物理', '英语', '生物'],
    [
      Cell({ children: '午休', rowspan: 2, align: 'center'}),
      Cell({ children: '午休', rowspan: 2, align: 'center'}),
      Cell({ children: '午休', rowspan: 2, align: 'center'}),
      Cell({ children: '午休', rowspan: 2, align: 'center'}),
      Cell({ children: '午休', rowspan: 2, align: 'center'}),
      Cell({ children: '午休', rowspan: 2, align: 'center'}),
    ],
    [],
    ['第3节', '体育', '音乐', '美术', '历史', '地理'],
    ['第4节', '自习', '自习', '自习', '自习', '自习'],
  ]}
/>

### 复杂合并示例：项目进度表

<MergeTable 
  headerRows={2}
  striped
  client:load
  data={[
    [
      Cell({ children: '项目阶段', header: true, rowspan: 2, align: 'center' }),
      Cell({ children: '任务详情', header: true, colspan: 3, align: 'center' }),
      Cell({ children: '状态', header: true, rowspan: 2, align: 'center' }),
    ],
    [
      Cell({ children: '任务名称', header: true }),
      Cell({ children: '负责人', header: true }),
      Cell({ children: '截止日期', header: true }),
    ],
    [
      Cell({ children: '需求分析', rowspan: 2, align: 'center'}),
      '用户调研',
      '张三',
      '2024-02-01',
      Cell({ children: '✅ 已完成'}),
    ],
    [
      '需求文档',
      '李四',
      '2024-02-15',
      Cell({ children: '✅ 已完成'}),
    ],
    [
      Cell({ children: '开发阶段', rowspan: 3, align: 'center'}),
      '前端开发',
      '王五',
      '2024-03-01',
      Cell({ children: '🔄 进行中'}),
    ],
    [
      '后端开发',
      '赵六',
      '2024-03-15',
      Cell({ children: '🔄 进行中'}),
    ],
    [
      '数据库设计',
      '钱七',
      '2024-02-28',
      Cell({ children: '✅ 已完成'}),
    ],
    [
      Cell({ children: '测试上线', rowspan: 2, align: 'center'}),
      '功能测试',
      '孙八',
      '2024-04-01',
      Cell({ children: '⏳ 待开始'}),
    ],
    [
      '部署上线',
      '周九',
      '2024-04-15',
      Cell({ children: '⏳ 待开始'}),
    ],
  ]}
/>

### 简洁语法示例

你也可以使用更简洁的语法，直接传入二维数组：

<MergeTable 
  headerRows={1}
  client:load
  data={[
    ['姓名', '年龄', '城市', '职业'],
    ['张三', '28', '北京', '工程师'],
    ['李四', '32', '上海', '设计师'],
    ['王五', '25', '广州', '产品经理'],
  ]}
/>

### 使用方式

```tsx
import MergeTable, { Cell } from '../../components/react/MergeTable';

// 使用 Cell 函数定义合并单元格
<MergeTable 
  headerRows={1}           // 前几行作为表头
  bordered={true}          // 显示边框（默认 true）
  striped={false}          // 斑马纹（默认 false）
  hoverable={true}         // 悬停效果（默认 true）
  compact={false}          // 紧凑模式（默认 false）
  client:load
  data={[
    [
      Cell({ children: '标题', header: true, colspan: 2 }),
      Cell({ children: '操作', header: true }),
    ],
    [
      Cell({ children: '合并内容', colspan: 2 }),
      '编辑',
    ],
  ]}
/>
```

**Cell 函数属性**：
- `children`：单元格内容
- `colspan`：跨列数
- `rowspan`：跨行数
- `align`：对齐方式（`'left' | 'center' | 'right'`）
- `header`：是否为表头单元格（使用 `<th>` 标签）
- `style`：自定义样式
- `className`：自定义 CSS 类名

**MergeTable 属性**：
- `data`：表格数据（二维数组）
- `headerRows`：表头行数（这些行会使用 `<th>` 标签）
- `bordered`：是否显示边框
- `striped`：是否显示斑马纹
- `hoverable`：是否启用悬停效果
- `compact`：紧凑模式（更小的内边距）

## 📝 如何在文章中使用

### 1. 导入组件

在文章顶部添加 import 语句：

```mdx
import AnimatedCard from '../../components/react/AnimatedCard';
```

### 2. 使用组件

```mdx
<AnimatedCard 
  title="标题" 
  description="描述"
  color="#3b82f6"
  client:load
/>
```

### 3. client 指令说明

| 指令 | 说明 |
|------|------|
| `client:load` | 页面加载时立即激活组件 |
| `client:visible` | 组件进入视口时激活 |
| `client:idle` | 浏览器空闲时激活 |
| `client:media="(min-width: 768px)"` | 满足媒体查询时激活 |

## 🎨 创建自定义组件

你可以在 `src/components/react/` 目录下创建自己的 React 组件：

```tsx
// src/components/react/MyComponent.tsx
import { useState } from 'react';

interface MyComponentProps {
  title: string;
}

export default function MyComponent({ title }: MyComponentProps) {
  const [count, setCount] = useState(0);
  
  return (
    <div style={{ padding: '1rem', background: '#f3f4f6' }}>
      <h3>{title}</h3>
      <button onClick={() => setCount(count + 1)}>
        点击次数: {count}
      </button>
    </div>
  );
}
```

然后在文章中使用：

```mdx
import MyComponent from '../../components/react/MyComponent';

<MyComponent title="我的组件" client:load />
```

---

## 总结

NovaBlog 提供了灵活的组件系统，让你可以在 Markdown 中嵌入丰富的交互内容。通过 React 组件，你可以实现：

- 🎴 **视觉效果**：悬浮、翻转、渐变等动画
- ⌨️ **动态文字**：打字机、滚动、闪烁效果
- ✨ **背景特效**：粒子、波浪、光效
- 🎮 **交互功能**：计数器、表单、游戏
- 📐 **数学公式**：翻转卡片展示 LaTeX 公式
- 📊 **高级表格**：支持合并单元格的复杂表格

快去尝试创建属于你自己的动效组件吧！ 🚀