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

***

# Class: FabricTexture

Fabric.js 贴图变形工具类

提供基于 Fabric.js 的图像变形功能，支持：
- 网格化变形：将图像划分为可调整的网格区域
- 交互式编辑：支持鼠标拖拽调整变形效果
- 实时预览：变形效果实时渲染
- 历史记录：支持撤销/重做操作
- 性能优化：自动处理大尺寸图像，优化渲染性能

## Example

```typescript
// 1. 创建 Fabric.js 画布
const canvas = new fabric.Canvas('canvas');

// 2. 初始化贴图工具
const fabricTexture = new FabricTexture(canvas, {
  history: true, // 启用历史记录
});

// 3. 准备需要变形的 fabric 元素对象，不限于图像元素
const image = new fabric.Image(imageElement);
canvas.add(image);

// 4. 进入编辑模式
fabricTexture.enterEditing(image, null, new GridMode());

// 5. 完成编辑后退出
fabricTexture.leaveEditing();
```

## Remarks

使用前请确保已正确安装并引入 fabric.js

## See

 - AbstractMode 查看如何自定义变形模式
 - Texture 了解底层变形实现

## Constructors

### new FabricTexture()

> **new FabricTexture**(`canvas`, `options`?): [`FabricTexture`](FabricTexture.md)

创建 FabricTexture 实例

初始化一个贴图变形工具实例。该实例将与指定的 Fabric.js 画布关联，
用于处理画布上的图像变形操作。

#### Parameters

##### canvas

`Canvas`

Fabric.js 画布实例

##### options?

`Partial`\<`FabricTextureOptions`\> = `{}`

配置选项

#### Returns

[`FabricTexture`](FabricTexture.md)

#### Example

```typescript
const canvas = new fabric.Canvas('canvas');
const texture = new FabricTexture(canvas);
```

#### Remarks

1. 创建实例后，需要调用 enterEditing 方法才能开始编辑
2. 启用历史记录会消耗额外的内存，请根据实际需求选择是否启用

## Properties

### canvas

> **canvas**: `Canvas`

Fabric.js 画布实例 用于渲染和管理变形操作的画布对象

***

### curvePathMap

> **curvePathMap**: `WeakMap`\<`Bezier`, `Path`\>

贝塞尔曲线到路径对象的映射 用于快速查找曲线对应的路径对象

#### Remarks

使用 WeakMap 避免内存泄漏

***

### mode

> **mode**: `null` \| [`AbstractMode`](AbstractMode.md) = `null`

当前激活的变形模式 控制图像变形的交互方式和效果

#### Default

```ts
null
```

***

### options

> **options**: `FabricTextureOptions`

实例配置选项 包含历史记录开关和变化监听器等配置

***

### pathCurveMap

> **pathCurveMap**: `WeakMap`\<`Path`, `Bezier`\>

路径对象到贝塞尔曲线的映射 用于快速查找路径对应的曲线对象

#### Remarks

使用 WeakMap 避免内存泄漏

***

### paths?

> `optional` **paths**: `Path`[]

网格路径元素列表 存储所有网格线的 Fabric.Path 对象

#### Remarks

用于显示变形网格和处理交互

***

### records

> **records**: `object`

变形操作的历史记录 存储变形操作的撤销/重做状态

#### redo

> **redo**: `Omit`\<`TransformData`, `"compressedCoordinates"`\>[]

#### undo

> **undo**: `Omit`\<`TransformData`, `"compressedCoordinates"`\>[]

***

### target

> **target**: `null` \| `Object` = `null`

当前正在编辑的 Fabric 对象 可以是任何 Fabric.js 支持的对象类型（图片、路径等）

#### Default

```ts
null
```

***

### targetCanvas

> **targetCanvas**: `null` \| `HTMLCanvasElement` = `null`

目标对象的画布表示 存储目标对象的原始图像数据

#### Default

```ts
null
```

***

### texture

> **texture**: `null` \| [`Texture`](Texture.md) = `null`

核心变形引擎实例 负责处理底层的图像变形计算

#### Default

```ts
null
```

***

### textureBoundary?

> `optional` **textureBoundary**: `object`

贴图的边界范围 记录变形区域的边界坐标，用于计算位置偏移

#### bottom

> **bottom**: `number`

#### left

> **left**: `number`

#### right

> **right**: `number`

#### top

> **top**: `number`

***

### textureObject?

> `optional` **textureObject**: `Image`

变形后的贴图对象 在画布上显示的实际图像对象

***

### textureScaleX

> **textureScaleX**: `number` = `1`

贴图在水平方向的缩放比例 用于保持变形后的图像与原始尺寸的比例关系

#### Default

```ts
1
```

***

### textureScaleY

> **textureScaleY**: `number` = `1`

贴图在垂直方向的缩放比例 用于保持变形后的图像与原始尺寸的比例关系

#### Default

```ts
1
```

## Methods

### enterEditing()

> **enterEditing**(`object`, `sourceCanvas`?, `mode`?, `beforeFirstRender`?): `void`

进入图像编辑模式

使指定的 Fabric 对象进入变形编辑状态。

#### Parameters

##### object

`Object`

要编辑的 Fabric 对象（如图片、路径等）

##### sourceCanvas?

可选的源画布，用于特殊渲染需求。如果为 null，将使用 object 生成的画布

`null` | `HTMLCanvasElement`

##### mode?

[`AbstractMode`](AbstractMode.md)

变形模式实例，决定了变形的交互方式和效果

##### beforeFirstRender?

(`texture`) => `void`

首次渲染前的回调函数，可用于初始化变形引擎的配置

#### Returns

`void`

#### Example

```typescript
fabricTexture.enterEditing(
  image,
  null,
  new GridMode(),
  (texture) => {
    // 设置显示分割网格线
    texture.setRenderOptions({ showGrid: true });
  }
);
```

#### See

leaveEditing 退出编辑模式

***

### leaveEditing()

> **leaveEditing**(): `void`

退出图像编辑模式

结束当前对象的变形编辑状态。

#### Returns

`void`

#### Example

```typescript
// 完成编辑后退出
fabricTexture.leaveEditing();

// 典型的编辑流程
try {
  // 1. 进入编辑模式
  fabricTexture.enterEditing(image, null, new GridMode());

  // 2. 进行编辑操作...

  // 3. 保存编辑结果
  const result = fabricTexture.serialize();

  // 4. 退出编辑模式
  fabricTexture.leaveEditing();
} catch (error) {
  console.error('编辑过程出错:', error);
  fabricTexture.leaveEditing(); // 确保清理资源
}
```

#### See

enterEditing 进入编辑模式

***

### record()

> **record**(): `void`

记录当前变形状态

将当前的变形状态保存到历史记录中。

#### Returns

`void`

#### Remarks

1. 仅在启用了历史记录功能时生效（options.history = true）
2. 每次记录都会创建状态的深拷贝，注意内存占用

#### See

 - undo 撤销操作
 - redo 重做操作

***

### redo()

> **redo**(): `void`

重做已撤销的变形操作

重新应用之前撤销的变形状态。

#### Returns

`void`

#### Example

```typescript
// 基础用法
fabricTexture.redo();

// 配合快捷键使用
document.addEventListener('keydown', (e) => {
  if (e.ctrlKey && e.key === 'y') {
    fabricTexture.redo();
  }
});
```

#### Remarks

1. 如果重做栈为空，此操作无效
2. 重做操作本身不会产生新的历史记录
3. 执行新的变形操作会清空重做栈

#### See

undo 撤销操作

***

### render()

> **render**(`dirty`?, `options`?): `void`

渲染贴图变形效果

将当前的变形状态渲染到画布上。

#### Parameters

##### dirty?

`boolean` = `true`

是否为脏渲染，脏渲染会导致 _dirtyRenderReturnCallback 回调执行

##### options?

`Partial`\<`RenderOptions`\> = `{}`

渲染配置选项

#### Returns

`void`

#### Example

```typescript
// 普通渲染（仅网格分割点位置变化）
fabricTexture.render(false);

// 脏渲染（网格结构发生变化，如添加或删除了分割点）
fabricTexture.render(true);

// 临时预览渲染（不记录历史）
fabricTexture.render(true, { withoutRecord: true });
```

#### Remarks

1. 脏渲染会重建整个网格结构，性能消耗较大
2. 非脏渲染仅更新现有网格的控制点位置，性能消耗较小
3. 如果不需要记录历史，建议设置 withoutRecord 为 true

#### See

requestRender 性能优化版本的渲染方法

***

### requestRender()

> **requestRender**(`dirty`?, `callback`?, `options`?): `void`

在下一帧渲染贴图变形效果（性能优化版本）

使用 requestAnimationFrame 延迟渲染到下一帧，可以：
1. 避免短时间内的重复渲染
2. 优化连续变形时的性能
3. 保持画面流畅度

#### Parameters

##### dirty?

`boolean` = `true`

是否为脏渲染，脏渲染会导致 _dirtyRenderReturnCallback 回调执行

##### callback?

() => `void`

渲染完成后的回调函数

##### options?

`Partial`\<`RenderOptions`\> = `{}`

渲染配置选项

#### Returns

`void`

#### Example

```typescript
// 基础用法
fabricTexture.requestRender();

// 带回调的用法
fabricTexture.requestRender(true, () => {
  console.log('渲染完成');
});

// 连续变形时的优化用法
function onDragging() {
  fabricTexture.requestRender(false, null, {
    withoutRecord: true // 拖拽过程中不记录历史
  });
}

function onDragEnd() {
  fabricTexture.render(true); // 拖拽结束时记录一次历史
}
```

#### Remarks

1. 此方法会自动取消上一次尚未执行的渲染请求
2. 适合用于处理连续的变形操作，如拖拽控制点
3. 对于关键状态的保存，建议使用同步的 render 方法

#### See

render 同步渲染方法

***

### reset()

> **reset**(`keepHistory`): `void`

重置变形状态

将图像重置到指定状态：
- 当 keepHistory=true 时：清除所有变形效果，但保留操作记录
- 当 keepHistory=false 时：回退到初始状态，并将后续状态移入重做栈

#### Parameters

##### keepHistory

`boolean` = `true`

是否保留历史记录
  - true: 清除变形但保留历史，可用于临时预览原始状态
  - false: 回退到初始状态，后续状态可通过重做恢复

#### Returns

`void`

#### Example

```typescript
// 1. 清除变形但保留历史记录
fabricTexture.reset(true);

// 2. 回退到初始状态，保留重做可能
fabricTexture.reset(false);

// 3. 配合撤销/重做使用
fabricTexture.reset(false);
if (fabricTexture.canRedo()) {
  // 可以通过 redo() 恢复之前的状态
  fabricTexture.redo();
}
```

#### Remarks

1. keepHistory=true 时：
   - 生成新的历史记录
   - 清空重做栈
   - 适合用于临时预览或确定放弃变形

2. keepHistory=false 时：
   - 不生成新的历史记录
   - 保留重做可能性
   - 适合用于需要保留恢复可能的场景

3. 在以下情况下方法无效：
   - 当前不在编辑状态（texture 为 null）
   - 当前已经是初始状态（keepHistory=true 时）

#### See

 - undo 单步撤销操作
 - redo 重做已撤销的操作
 - serialize 保存当前变形状态

***

### serialize()

> **serialize**(): `null` \| \{ `compressedData`: `string`; `data`: `TransformData`; \}

提取当前变形状态的数据

获取当前图像的变形状态数据。

#### Returns

`null` \| \{ `compressedData`: `string`; `data`: `TransformData`; \}

- 如果当前不在编辑状态，返回 null
- 否则返回包含以下属性的对象：
  - data: 原始变形数据
  - compressedData: 压缩后的字符串形式数据

***

### undo()

> **undo**(): `void`

撤销上一步变形操作

将变形状态回退到上一个记录点。

#### Returns

`void`

#### Example

```typescript
// 基础用法
fabricTexture.undo();

// 配合快捷键使用
document.addEventListener('keydown', (e) => {
  if (e.ctrlKey && e.key === 'z') {
    fabricTexture.undo();
  }
});
```

#### Remarks

1. 如果撤销栈为空或只有初始状态，此操作无效
2. 撤销操作本身不会产生新的历史记录

#### See

redo 重做已撤销的操作
