fabric-texture
Version:
This JavaScript library enables fast and efficient image distortion transformations using Canvas 2D.
675 lines (401 loc) • 11.7 kB
Markdown
[**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 重做已撤销的操作