# 图片裁剪组件

基于 `react-easy-crop` 的功能强大的图片裁剪组件，支持多种裁剪模式和自定义配置。

## 功能特性

- ✅ 支持拖拽、缩放和旋转操作
- ✅ 矩形和圆形裁剪形状
- ✅ 自定义裁剪比例 (16:9, 4:3, 1:1, 自由裁剪)
- ✅ 多种输出格式 (JPEG, PNG, WebP)
- ✅ 可调节输出质量
- ✅ 响应式设计，支持移动端
- ✅ 内置控制面板 (缩放、旋转滑块)
- ✅ 预设配置 (头像、封面、缩略图等)
- ✅ 支持弹窗和内联模式

## 基础用法

### 1. 基础裁剪组件

```tsx
import { ImageCrop } from '@/components/ui/image-crop'

function MyComponent() {
  const handleCropComplete = (croppedArea, croppedAreaPixels) => {
    console.log('裁剪区域:', croppedArea, croppedAreaPixels)
  }

  const handleSave = (croppedBlob) => {
    if (croppedBlob) {
      // 处理裁剪后的图片
      console.log('裁剪完成:', croppedBlob)
    }
  }

  return (
    <ImageCrop
      image="/path/to/image.jpg"
      aspect={16 / 9}
      onCropComplete={handleCropComplete}
      onSave={handleSave}
    />
  )
}
```

### 2. 使用预设配置

```tsx
import { ImageCrop, CropPresets } from '@/components/ui/image-crop'

function AvatarCrop() {
  return (
    <ImageCrop
      image={imageFile}
      {...CropPresets.avatar} // 圆形头像裁剪
      onSave={handleSave}
    />
  )
}
```

### 3. 弹窗模式

```tsx
import { ImageCropModal } from '@/components/ui/image-crop-modal'

function MyComponent() {
  const [showCrop, setShowCrop] = useState(false)
  const [selectedImage, setSelectedImage] = useState(null)

  return (
    <>
      <button onClick={() => setShowCrop(true)}>打开裁剪器</button>

      <ImageCropModal
        isOpen={showCrop}
        onClose={() => setShowCrop(false)}
        image={selectedImage}
        onSave={(croppedImageUrl) => {
          console.log('裁剪完成:', croppedImageUrl)
          setShowCrop(false)
        }}
        preset="avatar"
      />
    </>
  )
}
```

### 4. 内联模式

```tsx
import { InlineImageCrop } from '@/components/ui/image-crop-modal'

function MyComponent() {
  return (
    <InlineImageCrop
      image={imageFile}
      preset="cover"
      onSave={(croppedImageUrl) => {
        console.log('裁剪完成:', croppedImageUrl)
      }}
      className="h-96"
    />
  )
}
```

## 组件 API

### ImageCrop Props

| 属性             | 类型                                          | 默认值         | 说明                                                |
| ---------------- | --------------------------------------------- | -------------- | --------------------------------------------------- |
| `image`          | `string \| File`                              | -              | 必需。图片URL或File对象                             |
| `aspect`         | `number`                                      | `undefined`    | 裁剪比例，如 16/9, 1 (正方形)，undefined 为自由裁剪 |
| `cropShape`      | `"rect" \| "round"`                           | `"rect"`       | 裁剪形状                                            |
| `minZoom`        | `number`                                      | `1`            | 最小缩放比例                                        |
| `maxZoom`        | `number`                                      | `3`            | 最大缩放比例                                        |
| `showGrid`       | `boolean`                                     | `true`         | 是否显示网格线                                      |
| `showControls`   | `boolean`                                     | `true`         | 是否显示控制面板                                    |
| `outputFormat`   | `"image/jpeg" \| "image/png" \| "image/webp"` | `"image/jpeg"` | 输出格式                                            |
| `outputQuality`  | `number`                                      | `0.8`          | 输出质量 (0-1)                                      |
| `onCropComplete` | `function`                                    | -              | 裁剪完成回调                                        |
| `onSave`         | `function`                                    | -              | 保存回调                                            |
| `onCancel`       | `function`                                    | -              | 取消回调                                            |

### 预设配置

```tsx
// 可用的预设配置
CropPresets.avatar // 头像 (1:1 圆形)
CropPresets.cover // 封面 (16:9 矩形)
CropPresets.thumbnail // 缩略图 (4:3 矩形)
CropPresets.free // 自由裁剪
```

## 工具函数

### downloadCroppedImage

下载裁剪后的图片：

```tsx
import { downloadCroppedImage } from '@/components/ui/image-crop'

// 下载图片
downloadCroppedImage(croppedBlob, 'my-cropped-image')
```

### blobToBase64

将Blob转换为base64：

```tsx
import { blobToBase64 } from '@/components/ui/image-crop'

const base64Url = await blobToBase64(croppedBlob)
```

## 样式自定义

组件支持通过className属性自定义样式：

```tsx
<ImageCrop
  image={image}
  className="my-custom-crop"
  containerClassName="my-crop-container"
  cropAreaClassName="my-crop-area"
  controlsClassName="my-controls"
/>
```

## 完整示例

查看 `/test-image-crop` 路由获取完整的使用示例和测试页面。

## 注意事项

1. **图片格式支持**: 支持常见的图片格式 (JPEG, PNG, GIF, WebP)
2. **文件大小**: 建议图片文件不超过 10MB
3. **浏览器兼容性**: 支持现代浏览器，需要 Canvas API 支持
4. **移动端**: 支持触摸操作，包括双指缩放
5. **CORS**: 如果裁剪外部图片，需要确保图片服务器支持 CORS

## 依赖

- `react-easy-crop`: 核心裁剪功能
- `react`: React 组件
- `@radix-ui/react-alert-dialog`: 弹窗组件 (可选)
