579 lines
16 KiB
JavaScript
579 lines
16 KiB
JavaScript
|
|
import { Command, FunctionCommand } from "./Command";
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 液化命令基类
|
|||
|
|
* 所有液化相关命令的基类
|
|||
|
|
*/
|
|||
|
|
export class LiquifyCommand extends Command {
|
|||
|
|
/**
|
|||
|
|
* 创建液化命令
|
|||
|
|
* @param {Object} options 配置选项
|
|||
|
|
* @param {Object} options.canvas Fabric.js画布实例
|
|||
|
|
* @param {Object} options.layerManager 图层管理器实例
|
|||
|
|
* @param {Object} options.liquifyManager 液化管理器实例
|
|||
|
|
* @param {String} options.mode 液化模式
|
|||
|
|
* @param {Object} options.params 液化参数
|
|||
|
|
* @param {Object} options.targetObject 目标对象
|
|||
|
|
* @param {ImageData} options.originalData 原始图像数据
|
|||
|
|
* @param {ImageData} options.resultData 变形后图像数据
|
|||
|
|
*/
|
|||
|
|
constructor(options) {
|
|||
|
|
super({
|
|||
|
|
name: options.name || `液化操作: ${options.mode || "未知模式"}`,
|
|||
|
|
description:
|
|||
|
|
options.description ||
|
|||
|
|
`使用${options.mode || "未知模式"}模式进行液化操作`,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
this.canvas = options.canvas;
|
|||
|
|
this.layerManager = options.layerManager;
|
|||
|
|
this.liquifyManager = options.liquifyManager;
|
|||
|
|
this.mode = options.mode;
|
|||
|
|
this.params = options.params || {};
|
|||
|
|
this.targetObject = options.targetObject;
|
|||
|
|
this.targetLayerId = options.targetLayerId;
|
|||
|
|
this.originalData = options.originalData; // 操作前的图像数据
|
|||
|
|
this.resultData = options.resultData; // 操作后的图像数据
|
|||
|
|
this.savedState = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 执行液化操作
|
|||
|
|
* @returns {Promise} 执行结果
|
|||
|
|
*/
|
|||
|
|
async execute() {
|
|||
|
|
if (!this.canvas || !this.targetObject) {
|
|||
|
|
throw new Error("液化命令缺少必要的画布或目标对象");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!this.resultData) {
|
|||
|
|
// 如果没有预先计算的结果数据,现场执行变形
|
|||
|
|
this.resultData = await this.liquifyManager.applyLiquify(
|
|||
|
|
this.targetObject,
|
|||
|
|
this.mode,
|
|||
|
|
this.params
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 保存执行前的状态
|
|||
|
|
this.savedState = await this._saveObjectState();
|
|||
|
|
|
|||
|
|
// 更新画布上的对象
|
|||
|
|
await this._updateObjectWithResult();
|
|||
|
|
|
|||
|
|
// 刷新Canvas
|
|||
|
|
this.canvas.renderAll();
|
|||
|
|
|
|||
|
|
return this.resultData;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 撤销液化操作
|
|||
|
|
* @returns {Promise} 撤销结果
|
|||
|
|
*/
|
|||
|
|
async undo() {
|
|||
|
|
if (!this.canvas || !this.targetObject || !this.savedState) {
|
|||
|
|
throw new Error("无法撤销:缺少必要的状态信息");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 恢复对象到原始状态
|
|||
|
|
await this._restoreObjectState();
|
|||
|
|
|
|||
|
|
// 刷新Canvas
|
|||
|
|
this.canvas.renderAll();
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 保存对象状态
|
|||
|
|
* @private
|
|||
|
|
*/
|
|||
|
|
async _saveObjectState() {
|
|||
|
|
if (!this.targetObject) return null;
|
|||
|
|
|
|||
|
|
// 对于图像对象,我们需要保存src和元数据
|
|||
|
|
const state = {
|
|||
|
|
src: this.targetObject.getSrc ? this.targetObject.getSrc() : null,
|
|||
|
|
element: this.targetObject._element
|
|||
|
|
? this.targetObject._element.cloneNode(true)
|
|||
|
|
: null,
|
|||
|
|
filters: this.targetObject.filters ? [...this.targetObject.filters] : [],
|
|||
|
|
originalData: this.originalData,
|
|||
|
|
targetLayerId: this.targetLayerId,
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return state;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 恢复对象状态
|
|||
|
|
* @private
|
|||
|
|
*/
|
|||
|
|
async _restoreObjectState() {
|
|||
|
|
if (!this.targetObject || !this.savedState) return false;
|
|||
|
|
|
|||
|
|
// 获取当前图层对象
|
|||
|
|
const layer = this.layerManager.getLayerById(this.savedState.targetLayerId);
|
|||
|
|
if (!layer) return false;
|
|||
|
|
|
|||
|
|
// 恢复原始图像
|
|||
|
|
if (this.savedState.element && this.targetObject.setElement) {
|
|||
|
|
this.targetObject.setElement(this.savedState.element);
|
|||
|
|
|
|||
|
|
// 恢复滤镜
|
|||
|
|
if (this.savedState.filters) {
|
|||
|
|
this.targetObject.filters = [...this.savedState.filters];
|
|||
|
|
this.targetObject.applyFilters();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 使用变形结果更新对象
|
|||
|
|
* @private
|
|||
|
|
*/
|
|||
|
|
async _updateObjectWithResult() {
|
|||
|
|
if (!this.targetObject || !this.resultData) return false;
|
|||
|
|
|
|||
|
|
// 创建临时canvas来渲染结果数据
|
|||
|
|
const tempCanvas = document.createElement("canvas");
|
|||
|
|
tempCanvas.width = this.resultData.width;
|
|||
|
|
tempCanvas.height = this.resultData.height;
|
|||
|
|
const tempCtx = tempCanvas.getContext("2d");
|
|||
|
|
tempCtx.putImageData(this.resultData, 0, 0);
|
|||
|
|
console.log("临时Canvas创建成功 _updateObjectWithResult", this.resultData);
|
|||
|
|
// 更新Fabric图像
|
|||
|
|
await new Promise((resolve) => {
|
|||
|
|
fabric.Image.fromURL(tempCanvas.toDataURL(), (img) => {
|
|||
|
|
// 保留原对象的属性
|
|||
|
|
img.set({
|
|||
|
|
left: this.targetObject.left,
|
|||
|
|
top: this.targetObject.top,
|
|||
|
|
scaleX: this.targetObject.scaleX,
|
|||
|
|
scaleY: this.targetObject.scaleY,
|
|||
|
|
angle: this.targetObject.angle,
|
|||
|
|
flipX: this.targetObject.flipX,
|
|||
|
|
flipY: this.targetObject.flipY,
|
|||
|
|
opacity: this.targetObject.opacity,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 替换Canvas上的对象
|
|||
|
|
const index = this.canvas.getObjects().indexOf(this.targetObject);
|
|||
|
|
if (index !== -1) {
|
|||
|
|
this.canvas.remove(this.targetObject);
|
|||
|
|
this.canvas.insertAt(img, index);
|
|||
|
|
this.targetObject = img;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 确保图层引用更新
|
|||
|
|
const layer = this.layerManager.getLayerById(this.targetLayerId);
|
|||
|
|
if (layer) {
|
|||
|
|
if (
|
|||
|
|
layer.type === "background" &&
|
|||
|
|
layer.fabricObject === this.targetObject
|
|||
|
|
) {
|
|||
|
|
layer.fabricObject = img;
|
|||
|
|
} else if (layer.fabricObjects) {
|
|||
|
|
const objIndex = layer.fabricObjects.indexOf(this.targetObject);
|
|||
|
|
if (objIndex !== -1) {
|
|||
|
|
layer.fabricObjects[objIndex] = img;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
resolve();
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 图层栅格化命令
|
|||
|
|
* 用于将复杂图层栅格化为单一图像,以便进行液化操作
|
|||
|
|
*/
|
|||
|
|
export class RasterizeForLiquifyCommand extends Command {
|
|||
|
|
/**
|
|||
|
|
* 创建栅格化命令
|
|||
|
|
* @param {Object} options 配置选项
|
|||
|
|
* @param {Object} options.canvas Fabric.js画布实例
|
|||
|
|
* @param {Object} options.layerManager 图层管理器实例
|
|||
|
|
* @param {String} options.layerId 需要栅格化的图层ID
|
|||
|
|
*/
|
|||
|
|
constructor(options) {
|
|||
|
|
super({
|
|||
|
|
name: options.name || "栅格化图层",
|
|||
|
|
description: options.description || "将图层栅格化为单一图像以便液化操作",
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
this.canvas = options.canvas;
|
|||
|
|
this.layerManager = options.layerManager;
|
|||
|
|
this.layerId = options.layerId;
|
|||
|
|
this.originalLayer = null;
|
|||
|
|
this.rasterizedImageObj = null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 执行栅格化操作
|
|||
|
|
* @returns {Promise<Object>} 栅格化后的图像对象
|
|||
|
|
*/
|
|||
|
|
async execute() {
|
|||
|
|
if (!this.canvas || !this.layerManager || !this.layerId) {
|
|||
|
|
throw new Error("栅格化命令缺少必要参数");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 保存原始图层信息
|
|||
|
|
this.originalLayer = this.layerManager.getLayerById(this.layerId);
|
|||
|
|
if (!this.originalLayer) {
|
|||
|
|
throw new Error(`图层ID不存在: ${this.layerId}`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 栅格化图层
|
|||
|
|
const rasterizedImage = await this.layerManager.rasterizeLayer(
|
|||
|
|
this.layerId
|
|||
|
|
);
|
|||
|
|
if (!rasterizedImage) {
|
|||
|
|
throw new Error("栅格化图层失败");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
this.rasterizedImageObj = rasterizedImage;
|
|||
|
|
return rasterizedImage;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 撤销栅格化操作
|
|||
|
|
* 注意:完整撤销栅格化是复杂的,这里提供近似还原
|
|||
|
|
* @returns {Promise<boolean>} 撤销结果
|
|||
|
|
*/
|
|||
|
|
async undo() {
|
|||
|
|
if (!this.canvas || !this.layerManager || !this.originalLayer) {
|
|||
|
|
throw new Error("无法撤销:缺少必要的状态信息");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 恢复图层为原始状态是复杂的,这里可能需要与LayerManager协作
|
|||
|
|
// 这个实现可能需要根据实际的LayerManager功能来调整
|
|||
|
|
const restored = await this.layerManager.restoreLayerFromBackup(
|
|||
|
|
this.layerId
|
|||
|
|
);
|
|||
|
|
if (!restored) {
|
|||
|
|
console.warn("无法完全还原栅格化前的图层状态");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 液化工具初始化命令
|
|||
|
|
* 用于初始化液化工具的状态,不执行实际操作
|
|||
|
|
*/
|
|||
|
|
export class InitLiquifyToolCommand extends Command {
|
|||
|
|
constructor(options) {
|
|||
|
|
super({
|
|||
|
|
name: "初始化液化工具",
|
|||
|
|
description: "准备液化工具工作环境",
|
|||
|
|
undoable: false, // 这个命令不需要撤销
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
this.canvas = options.canvas;
|
|||
|
|
this.layerManager = options.layerManager;
|
|||
|
|
this.liquifyManager = options.liquifyManager;
|
|||
|
|
this.toolManager = options.toolManager;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 执行初始化
|
|||
|
|
*/
|
|||
|
|
execute() {
|
|||
|
|
if (this.liquifyManager) {
|
|||
|
|
this.liquifyManager.initialize({
|
|||
|
|
canvas: this.canvas,
|
|||
|
|
layerManager: this.layerManager,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 通知各管理器进入液化模式
|
|||
|
|
this.toolManager?.notifyObservers("LIQUIFY");
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
undo() {
|
|||
|
|
// 不需要撤销初始化
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 液化操作命令 - 针对单次变形操作
|
|||
|
|
* 用于实现可撤销的单次液化变形
|
|||
|
|
*/
|
|||
|
|
export class LiquifyDeformCommand extends LiquifyCommand {
|
|||
|
|
/**
|
|||
|
|
* 创建液化变形命令
|
|||
|
|
* @param {Object} options 配置选项
|
|||
|
|
* @param {Number} options.x 变形中心X坐标
|
|||
|
|
* @param {Number} options.y 变形中心Y坐标
|
|||
|
|
* @param {ImageData} options.beforeData 变形前的图像数据
|
|||
|
|
* @param {ImageData} options.afterData 变形后的图像数据
|
|||
|
|
*/
|
|||
|
|
constructor(options) {
|
|||
|
|
super({
|
|||
|
|
...options,
|
|||
|
|
name: `液化变形: ${options.mode || "未知模式"}`,
|
|||
|
|
description: `在(${options.x}, ${options.y})应用${
|
|||
|
|
options.mode || "未知模式"
|
|||
|
|
}变形`,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
this.x = options.x;
|
|||
|
|
this.y = options.y;
|
|||
|
|
this.beforeData = options.beforeData;
|
|||
|
|
this.afterData = options.afterData;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async execute() {
|
|||
|
|
if (!this.afterData) {
|
|||
|
|
// 如果没有预计算的结果,实时计算
|
|||
|
|
await this.liquifyManager.prepareForLiquify(this.targetObject);
|
|||
|
|
this.afterData = await this.liquifyManager.applyLiquify(
|
|||
|
|
this.targetObject,
|
|||
|
|
this.mode,
|
|||
|
|
this.params,
|
|||
|
|
this.x,
|
|||
|
|
this.y
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 保存当前状态
|
|||
|
|
this.savedState = await this._saveObjectState();
|
|||
|
|
|
|||
|
|
// 应用变形结果
|
|||
|
|
await this._updateObjectWithImageData(this.afterData);
|
|||
|
|
|
|||
|
|
this.canvas.renderAll();
|
|||
|
|
return this.afterData;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async undo() {
|
|||
|
|
if (!this.beforeData) {
|
|||
|
|
throw new Error("无法撤销:缺少变形前的数据");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 恢复到变形前的状态
|
|||
|
|
await this._updateObjectWithImageData(this.beforeData);
|
|||
|
|
|
|||
|
|
this.canvas.renderAll();
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 使用图像数据更新对象
|
|||
|
|
* @param {ImageData} imageData 图像数据
|
|||
|
|
* @private
|
|||
|
|
*/
|
|||
|
|
async _updateObjectWithImageData(imageData) {
|
|||
|
|
return new Promise((resolve) => {
|
|||
|
|
// 创建临时canvas
|
|||
|
|
const tempCanvas = document.createElement("canvas");
|
|||
|
|
tempCanvas.width = imageData.width;
|
|||
|
|
tempCanvas.height = imageData.height;
|
|||
|
|
const tempCtx = tempCanvas.getContext("2d");
|
|||
|
|
tempCtx.putImageData(imageData, 0, 0);
|
|||
|
|
|
|||
|
|
// 从canvas创建新的fabric图像
|
|||
|
|
fabric.Image.fromURL(tempCanvas.toDataURL(), (img) => {
|
|||
|
|
// 保留原对象的变换属性
|
|||
|
|
img.set({
|
|||
|
|
left: this.targetObject.left,
|
|||
|
|
top: this.targetObject.top,
|
|||
|
|
scaleX: this.targetObject.scaleX,
|
|||
|
|
scaleY: this.targetObject.scaleY,
|
|||
|
|
angle: this.targetObject.angle,
|
|||
|
|
flipX: this.targetObject.flipX,
|
|||
|
|
flipY: this.targetObject.flipY,
|
|||
|
|
opacity: this.targetObject.opacity,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
// 替换canvas上的对象
|
|||
|
|
const index = this.canvas.getObjects().indexOf(this.targetObject);
|
|||
|
|
if (index !== -1) {
|
|||
|
|
this.canvas.remove(this.targetObject);
|
|||
|
|
this.canvas.insertAt(img, index);
|
|||
|
|
this.targetObject = img;
|
|||
|
|
|
|||
|
|
// 更新图层引用
|
|||
|
|
const layer = this.layerManager.getLayerById(this.targetLayerId);
|
|||
|
|
if (layer) {
|
|||
|
|
if (
|
|||
|
|
layer.type === "background" &&
|
|||
|
|
(layer.fabricObject === this.savedState?.originalObject ||
|
|||
|
|
layer.fabricObject === this.targetObject)
|
|||
|
|
) {
|
|||
|
|
layer.fabricObject = img;
|
|||
|
|
} else if (layer.fabricObjects) {
|
|||
|
|
const objIndex = layer.fabricObjects.findIndex(
|
|||
|
|
(obj) =>
|
|||
|
|
obj === this.savedState?.originalObject ||
|
|||
|
|
obj === this.targetObject
|
|||
|
|
);
|
|||
|
|
if (objIndex !== -1) {
|
|||
|
|
layer.fabricObjects[objIndex] = img;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
resolve();
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 复合液化命令 - 用于组合多个液化操作
|
|||
|
|
* 支持一次撤销多个相关的液化变形
|
|||
|
|
*/
|
|||
|
|
export class CompositeLiquifyCommand extends Command {
|
|||
|
|
/**
|
|||
|
|
* 创建复合液化命令
|
|||
|
|
* @param {Object} options 配置选项
|
|||
|
|
* @param {Array} options.commands 子命令列表
|
|||
|
|
* @param {String} options.name 命令名称
|
|||
|
|
*/
|
|||
|
|
constructor(options) {
|
|||
|
|
super({
|
|||
|
|
name: options.name || "液化操作组合",
|
|||
|
|
description:
|
|||
|
|
options.description || `包含${options.commands?.length || 0}个液化操作`,
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
this.commands = options.commands || [];
|
|||
|
|
this.canvas = options.canvas;
|
|||
|
|
this.layerManager = options.layerManager;
|
|||
|
|
this.liquifyManager = options.liquifyManager;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 添加子命令
|
|||
|
|
* @param {Command} command 要添加的命令
|
|||
|
|
*/
|
|||
|
|
addCommand(command) {
|
|||
|
|
this.commands.push(command);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async execute() {
|
|||
|
|
const results = [];
|
|||
|
|
|
|||
|
|
for (const command of this.commands) {
|
|||
|
|
try {
|
|||
|
|
const result = await command.execute();
|
|||
|
|
results.push(result);
|
|||
|
|
} catch (error) {
|
|||
|
|
// 如果有命令失败,尝试回滚已执行的命令
|
|||
|
|
console.error("复合液化命令执行失败:", error);
|
|||
|
|
await this.undo();
|
|||
|
|
throw error;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return results;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async undo() {
|
|||
|
|
// 逆序撤销所有子命令
|
|||
|
|
const errors = [];
|
|||
|
|
|
|||
|
|
for (let i = this.commands.length - 1; i >= 0; i--) {
|
|||
|
|
try {
|
|||
|
|
await this.commands[i].undo();
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error(`撤销子命令${i}失败:`, error);
|
|||
|
|
errors.push(error);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (errors.length > 0) {
|
|||
|
|
throw new Error(`复合命令撤销部分失败: ${errors.length}个错误`);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 检查命令是否可以执行
|
|||
|
|
* @returns {Boolean} 是否可执行
|
|||
|
|
*/
|
|||
|
|
canExecute() {
|
|||
|
|
return (
|
|||
|
|
this.commands.length > 0 &&
|
|||
|
|
this.commands.every((cmd) => (cmd.canExecute ? cmd.canExecute() : true))
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 液化重置命令 - 将图像恢复到原始状态
|
|||
|
|
*/
|
|||
|
|
export class LiquifyResetCommand extends LiquifyCommand {
|
|||
|
|
constructor(options) {
|
|||
|
|
super({
|
|||
|
|
...options,
|
|||
|
|
name: "重置液化",
|
|||
|
|
description: "将图像恢复到液化前的原始状态",
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async execute() {
|
|||
|
|
if (!this.liquifyManager || !this.targetObject) {
|
|||
|
|
throw new Error("无法重置:缺少必要的管理器或目标对象");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 保存当前状态
|
|||
|
|
this.savedState = await this._saveObjectState();
|
|||
|
|
|
|||
|
|
// 重置液化管理器
|
|||
|
|
const resetData = this.liquifyManager.reset();
|
|||
|
|
if (!resetData) {
|
|||
|
|
throw new Error("重置失败:没有原始数据");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 应用重置结果
|
|||
|
|
await this._updateObjectWithResult();
|
|||
|
|
|
|||
|
|
this.canvas.renderAll();
|
|||
|
|
return resetData;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 辅助函数:创建液化重置命令
|
|||
|
|
* @param {Object} options 配置选项
|
|||
|
|
* @returns {LiquifyResetCommand} 重置命令实例
|
|||
|
|
*/
|
|||
|
|
export function createLiquifyResetCommand(options) {
|
|||
|
|
return new LiquifyResetCommand(options);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 辅助函数:创建液化变形命令
|
|||
|
|
* @param {Object} options 配置选项
|
|||
|
|
* @returns {LiquifyDeformCommand} 变形命令实例
|
|||
|
|
*/
|
|||
|
|
export function createLiquifyDeformCommand(options) {
|
|||
|
|
return new LiquifyDeformCommand(options);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 辅助函数:创建复合液化命令
|
|||
|
|
* @param {Object} options 配置选项
|
|||
|
|
* @returns {CompositeLiquifyCommand} 复合命令实例
|
|||
|
|
*/
|
|||
|
|
export function createCompositeLiquifyCommand(options) {
|
|||
|
|
return new CompositeLiquifyCommand(options);
|
|||
|
|
}
|