UNPKG

fabric-texture

Version:

This JavaScript library enables fast and efficient image distortion transformations using Canvas 2D.

305 lines (304 loc) 9.59 kB
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;