fabric-texture
Version:
This JavaScript library enables fast and efficient image distortion transformations using Canvas 2D.
305 lines (304 loc) • 9.59 kB
TypeScript
import { fabric } from 'fabric';
import type { FabricTexture } from '../fabric-texture.class';
import type { Texture } from '../texture.class';
import BaseMode from './base.class';
/**
* 贴图变形区域的顶点类型枚举
*
* 用于标识变形区域四个角的位置。
*
* @enum {string}
*/
export declare enum VertexType {
/** 左上角顶点 */
TOP_LEFT = "tl",
/** 右上角顶点 */
TOP_RIGHT = "tr",
/** 左下角顶点 */
BOTTOM_LEFT = "bl",
/** 右下角顶点 */
BOTTOM_RIGHT = "br"
}
/**
* 透视模式配置
*/
interface PerspectiveOptions {
/**
* 是否启用空白区域拖拽调整功能
*
* 启用后:
* - 可以在画布空白处拖拽来调整变形区域
* - 最小拖拽区域为 50x50 像素
*
* @default true
*/
enableDragResize?: boolean;
/**
* 是否启用 Shift 键移动约束
*
* 启用后:
* - 移动控点时按住 Shift 键可限制移动方向为水平或垂直
* - 移动方向取决于拖拽距离较大的方向
*
* @default true
*/
enableShiftConstraint?: boolean;
}
/**
* 透视变形模式
*
* 提供图像的透视变形功能,通过四个顶点控制点实现自由透视效果。
*
* 主要功能:
* - 通过拖拽四个角点调整透视效果
* - 自动计算透视网格分割点
* - 支持自定义控制点样式
* - 防止无效透视变形
*
* @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
* - {@link BaseMode} 变形模式基类
* - {@link FabricTexture} 主要功能类
*/
declare class Perspective extends BaseMode<{
/**
* 可配置顶点控制点的方法
* @param object - 默认的控制点对象
* @returns 作为控制点对象的fabric元素对象,可使用默认对象以外的新对象
*/
control: (object: fabric.Object) => fabric.Object;
}> {
/**
* 变形模式的唯一标识名称
*/
name: string;
/**
* 模式配置
*/
options: Required<PerspectiveOptions>;
/**
* 控制点映射表
*
* 存储控制点与其相关数据的映射关系,包括:
* - curve: 控制点所在的贝塞尔曲线
* - targetPointIdx: 控制点在曲线上的索引位置
* - rowIndex: 控制点所在的网格行索引
* - colIndex: 控制点所在的网格列索引
* - vertexType: 控制点的顶点类型(如左上、右上等)
*
* @internal 仅供内部使用
*/
private _objectControlMap;
/**
* 样式设置器集合
*
* 用于自定义透视变形模式中各种元素的样式:
* - texture: 配置变形后的贴图样式
* - path: 配置网格边界线的样式
* - control: 配置顶点控制点的样式
*
* @example
* ```typescript
* perspective.setStyleSetters({
* // 自定义控制点样式
* control: (control) => {
* control.set({
* radius: 10,
* fill: 'blue',
* stroke: 'white'
* });
* return control;
* }
* });
* ```
*
* @protected 仅供子类访问和修改
*/
protected _styleSetters: {
texture: () => void;
path: () => void;
control: (control: fabric.Object) => fabric.Object;
};
/**
* 创建透视变形模式实例
*
* 初始化一个透视变形模式,可以通过参数自定义主题色系。
* 主题色系用于控制交互界面的视觉效果:
* - 主题色:用于控制点的填充色
* - 副主题色:用于控制点的交互状态
*
* @param themeColor - 主题色,默认为 '#44A08D'(清新绿)
* @param subThemeColor - 副主题色,默认为 '#324346'(深灰绿)
*/
constructor(themeColor?: string, subThemeColor?: string, options?: PerspectiveOptions);
/**
* 计算透视变形的网格分割点
*
* 该方法实现了透视变形的核心算法,主要功能:
* 1. 计算透视网格的分割点坐标
* 2. 确保透视效果的有效性
* 3. 处理透视消失点
*
* 算法步骤:
* 1. 验证四个顶点形成的透视是否有效
* 2. 计算水平和垂直方向的消失点
* 3. 根据消失点计算网格线的交点
* 4. 生成最终的分割点数组
*
* @param texture - 需要进行透视变形的贴图对象
* @returns 返回三维数组,表示网格的分割点坐标:
* - 第一维:行索引
* - 第二维:列索引
* - 第三维:点的坐标 {x, y}
*
* @throws {Error} 当四个顶点形成无效的透视形状时抛出错误
*
* @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. 当线条平行时会使用默认点代替交点
*/
static execute(texture: Texture): Coord[][][];
/**
* 创建默认的控制点视觉对象
*
* 创建一个圆形的控制点,用于拖拽调整透视效果。默认样式:
* - 圆形控制点(半径:7px)
* - 白色边框(宽度:2px)
* - 使用主题色填充
* - 无法调整大小
* - 无边界框
* - 居中定位(originX/Y: center)
*
* @param themeColor - 控制点的填充颜色,通常从构造函数传入
* @returns {fabric.Circle} 返回一个 fabric.Circle 实例作为控制点
*
* @example
* ```typescript
* // 创建自定义颜色的控制点
* const control = Perspective.createDefaultControl('#FF0000');
* ```
*
* @see
* - {@link fabric.Circle} Fabric.js 圆形对象文档
* - {@link constructor} 主题色设置
*/
static createDefaultControl(themeColor: string): fabric.Circle;
/**
* 获取当前所有的控制点对象
*
* 返回当前透视变形模式中的所有控制点对象。常用于:
* - 批量修改控制点样式
* - 控制点的显示/隐藏
* - 获取控制点位置信息
* - 控制点层级管理
*
* @returns {fabric.Object[]} 返回所有控制点对象的数组
*
* @example
* ```typescript
* // 隐藏所有控制点
* perspective.controlObjects.forEach(control => {
* control.set({ visible: false });
* });
* canvas.renderAll();
*
* // 将所有控制点移到最上层
* perspective.controlObjects.forEach(control => {
* canvas.bringToFront(control);
* });
* ```
*/
get controlObjects(): fabric.Object[];
/**
* 执行透视变形计算
*
* 代理方法,调用静态方法 {@link Perspective.execute} 进行实际的透视变形计算。
*
* @param texture - 需要进行透视变形的贴图对象
* @returns 返回计算后的网格分割点坐标数组
* @see {@link Perspective.execute} 具体实现细节
*/
execute(texture: Texture): Coord[][][];
/**
* 渲染透视变形的交互控制界面
*
* 在画布上创建并管理透视变形的交互控制界面,包括:
* 1. 四个角点的控制点
* 2. 拖拽调整功能
* 3. 实时预览效果
* 4. 自动记录变换历史
*
* 交互方式:
* - 拖拽控制点:调整单个角点位置
* - 空白处拖拽:快速调整矩形区域
* - 左键点击:仅响应鼠标左键操作
*
* 安全特性:
* - 自动防止无效的透视变形
* - 控制点始终保持在最上层
* - 自动记录可撤销的操作历史
*
* @param fabricTexture - FabricTexture 实例,提供画布和贴图操作接口
* @returns 返回清理函数,用于移除所有控制点和事件监听器
*
* @example
* ```typescript
* // 进入透视编辑模式
* const cleanup = perspective.dirtyRender(fabricTexture);
*
* // 退出编辑模式时清理
* cleanup();
* ```
*
* @remarks
* 1. 控制点的样式可通过 setStyleSetters 方法自定义
* 2. 拖拽区域小于 50x50 像素时不会在新的区域触发变形
* 3. 无效的透视变形会自动回退到上一个有效状态
*/
dirtyRender(fabricTexture: FabricTexture): (() => void) | undefined;
}
export default Perspective;