[**fabric-texture**](../../README.md)

***

# Class: Perspective

透视变形模式

提供图像的透视变形功能，通过四个顶点控制点实现自由透视效果。

主要功能：
- 通过拖拽四个角点调整透视效果
- 自动计算透视网格分割点
- 支持自定义控制点样式
- 防止无效透视变形

## Example

```typescript
// 1. 基础用法
const canvas = new fabric.Canvas('canvas');
const fabricTexture = new FabricTexture(canvas);

// 创建透视模式并应用到图像
const perspective = new Perspective('#FF0000');  // 使用红色主题
fabricTexture.enterEditing(image, null, perspective);

// 2. 自定义控制点样式
const perspective = new Perspective()
  .setStyleSetters({
    control: (control) => {
      control.set({
        radius: 10,
        fill: 'blue',
        stroke: 'white'
      });
      return control;
    }
  });

// 3. 隐藏原始对象（可选）
image.set({ visible: false });
canvas.renderAll();
```

## Remarks

使用注意：
1. 四个控制点不能形成三角形，这会导致无效的透视效果
2. 原始对象默认保持可见，需要手动隐藏

## See

- BaseMode 变形模式基类
- [FabricTexture](../../index/classes/FabricTexture.md) 主要功能类

## Extends

- `BaseMode`\<\{ `control`: (`object`) => `fabric.Object`; \}\>

## Constructors

### new Perspective()

> **new Perspective**(`themeColor`, `subThemeColor`, `options`): [`Perspective`](Perspective.md)

创建透视变形模式实例

初始化一个透视变形模式，可以通过参数自定义主题色系。
主题色系用于控制交互界面的视觉效果：
- 主题色：用于控制点的填充色
- 副主题色：用于控制点的交互状态

#### Parameters

##### themeColor

`string` = `THEME_COLOR`

主题色，默认为 '#44A08D'（清新绿）

##### subThemeColor

`string` = `SUB_THEME_COLOR`

副主题色，默认为 '#324346'（深灰绿）

##### options

`PerspectiveOptions` = `{}`

#### Returns

[`Perspective`](Perspective.md)

#### Overrides

`BaseMode<{ /** * 可配置顶点控制点的方法 * @param object - 默认的控制点对象 * @returns 作为控制点对象的fabric元素对象，可使用默认对象以外的新对象 */ control: (object: fabric.Object) => fabric.Object; }>.constructor`

## Properties

### name

> **name**: `string` = `'Perspective'`

变形模式的唯一标识名称

#### Overrides

`BaseMode.name`

***

### options

> **options**: `Required`\<`PerspectiveOptions`\>

模式配置

***

### subThemeColor

> **subThemeColor**: `string` = `SUB_THEME_COLOR`

副主题色

决定交互控件交互时的变化色，应与主题色形成合适的搭配

#### Default

```ts
SUB_THEME_COLOR ('#324346')
```

#### See

SUB_THEME_COLOR 默认副主题色常量

#### Inherited from

`BaseMode.subThemeColor`

***

### themeColor

> **themeColor**: `string` = `THEME_COLOR`

主题色

决定交互控件的颜色

#### Default

```ts
THEME_COLOR ('#44A08D')
```

#### See

THEME_COLOR 默认主题色常量

#### Inherited from

`BaseMode.themeColor`

## Accessors

### controlObjects

#### Get Signature

> **get** **controlObjects**(): `Object`[]

获取当前所有的控制点对象

返回当前透视变形模式中的所有控制点对象。常用于：
- 批量修改控制点样式
- 控制点的显示/隐藏
- 获取控制点位置信息
- 控制点层级管理

##### Example

```typescript
// 隐藏所有控制点
perspective.controlObjects.forEach(control => {
  control.set({ visible: false });
});
canvas.renderAll();

// 将所有控制点移到最上层
perspective.controlObjects.forEach(control => {
  canvas.bringToFront(control);
});
```

##### Returns

`Object`[]

返回所有控制点对象的数组

## Methods

### dirtyRender()

> **dirtyRender**(`fabricTexture`): `undefined` \| () => `void`

渲染透视变形的交互控制界面

在画布上创建并管理透视变形的交互控制界面，包括：
1. 四个角点的控制点
2. 拖拽调整功能
3. 实时预览效果
4. 自动记录变换历史

交互方式：
- 拖拽控制点：调整单个角点位置
- 空白处拖拽：快速调整矩形区域
- 左键点击：仅响应鼠标左键操作

安全特性：
- 自动防止无效的透视变形
- 控制点始终保持在最上层
- 自动记录可撤销的操作历史

#### Parameters

##### fabricTexture

[`FabricTexture`](../../index/classes/FabricTexture.md)

FabricTexture 实例，提供画布和贴图操作接口

#### Returns

`undefined` \| () => `void`

返回清理函数，用于移除所有控制点和事件监听器

#### Example

```typescript
// 进入透视编辑模式
const cleanup = perspective.dirtyRender(fabricTexture);

// 退出编辑模式时清理
cleanup();
```

#### Remarks

1. 控制点的样式可通过 setStyleSetters 方法自定义
2. 拖拽区域小于 50x50 像素时不会在新的区域触发变形
3. 无效的透视变形会自动回退到上一个有效状态

#### Overrides

`BaseMode.dirtyRender`

***

### execute()

> **execute**(`texture`): `Coord`[][][]

执行透视变形计算

代理方法，调用静态方法 [Perspective.execute](Perspective.md#execute-2) 进行实际的透视变形计算。

#### Parameters

##### texture

[`Texture`](../../index/classes/Texture.md)

需要进行透视变形的贴图对象

#### Returns

`Coord`[][][]

返回计算后的网格分割点坐标数组

#### See

[Perspective.execute](Perspective.md#execute-2) 具体实现细节

#### Overrides

`BaseMode.execute`

***

### render()

> **render**(`fabricTexture`): `undefined` \| () => `void`

渲染变形效果到画布

将变形后的贴图和网格边界线渲染到 Fabric.js 画布上。

#### Parameters

##### fabricTexture

[`FabricTexture`](../../index/classes/FabricTexture.md)

Fabric 变形工具实例，包含画布和变形状态

#### Returns

`undefined` \| () => `void`

清理函数，用于移除渲染的元素

#### Example

```typescript
class CustomMode extends BaseMode {
  render(fabricTexture: FabricTexture) {
    // 调用基类渲染方法
    const cleanup = super.render(fabricTexture);

    // 添加自定义渲染逻辑
    const customElements = this.renderCustomElements();

    // 返回组合的清理函数
    return () => {
      cleanup();
      this.cleanupCustomElements(customElements);
    };
  }
}
```

#### Remarks

1. 返回的清理函数会在下次渲染前或离开编辑模式时自动调用
2. 子类可以通过 super.render() 复用基类的渲染逻辑
3. 渲染的元素样式可通过 setStyleSetters 配置

#### Inherited from

`BaseMode.render`

***

### setStyleSetters()

> **setStyleSetters**(`styleSetters`): [`Perspective`](Perspective.md)

配置变形模式中各元素的样式

通过样式设置器自定义变形模式中各种元素的外观，支持：
- 变形后的贴图样式
- 网格边界线样式
- 通过泛型扩展的自定义元素样式

#### Parameters

##### styleSetters

`Partial`\<`BaseStyleSetters`\<`Record`\<`string`, (...`rgs`) => `Object`\>\>\>

样式设置器配置对象

#### Returns

[`Perspective`](Perspective.md)

当前实例，支持链式调用

#### Example

```typescript
mode.setStyleSetters({
  texture: (image) => {
    image.set({ opacity: 0.8 });
  }
});
```

#### Remarks

1. 新的样式设置会与现有设置合并，而不是完全替换
2. 对于同名设置器，新的会覆盖旧的
3. 样式会在下一次渲染时生效

#### Inherited from

`BaseMode.setStyleSetters`

***

### createDefaultControl()

> `static` **createDefaultControl**(`themeColor`): `Circle`

创建默认的控制点视觉对象

创建一个圆形的控制点，用于拖拽调整透视效果。默认样式：
- 圆形控制点（半径：7px）
- 白色边框（宽度：2px）
- 使用主题色填充
- 无法调整大小
- 无边界框
- 居中定位（originX/Y: center）

#### Parameters

##### themeColor

`string`

控制点的填充颜色，通常从构造函数传入

#### Returns

`Circle`

返回一个 fabric.Circle 实例作为控制点

#### Example

```typescript
// 创建自定义颜色的控制点
const control = Perspective.createDefaultControl('#FF0000');
```

#### See

- fabric.Circle Fabric.js 圆形对象文档
- [constructor](Perspective.md#constructors) 主题色设置

***

### execute()

> `static` **execute**(`texture`): `Coord`[][][]

计算透视变形的网格分割点

该方法实现了透视变形的核心算法，主要功能：
1. 计算透视网格的分割点坐标
2. 确保透视效果的有效性
3. 处理透视消失点

算法步骤：
1. 验证四个顶点形成的透视是否有效
2. 计算水平和垂直方向的消失点
3. 根据消失点计算网格线的交点
4. 生成最终的分割点数组

#### Parameters

##### texture

[`Texture`](../../index/classes/Texture.md)

需要进行透视变形的贴图对象

#### Returns

`Coord`[][][]

返回三维数组，表示网格的分割点坐标：
- 第一维：行索引
- 第二维：列索引
- 第三维：点的坐标 {x, y}

#### Throws

当四个顶点形成无效的透视形状时抛出错误

#### Example

```typescript
const texture = new Texture(image);
try {
  const points = Perspective.execute(texture);
  // points[0][0][0] 表示左上角第一个分割点的坐标
} catch (error) {
  console.error('透视形状无效:', error);
}
```

#### Remarks

1. 确保四个顶点不会形成三角形
2. 顶点的移动范围会受到透视有效性的限制
3. 当线条平行时会使用默认点代替交点
