Merge branch 'dev_vite' of http://18.167.251.121:10003/aidlab/aida_front into dev_vite
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { Command, FunctionCommand } from "./Command";
|
||||
import { getLiquifyReferenceManager } from "../managers/LiquifyReferenceManager";
|
||||
import { optimizeCanvasRendering } from "../utils/helper";
|
||||
import { fabric } from "fabric-with-all";
|
||||
|
||||
/**
|
||||
* 液化命令基类
|
||||
@@ -129,6 +130,7 @@ export class LiquifyCommand extends Command {
|
||||
|
||||
/**
|
||||
* 使用变形结果更新对象
|
||||
* 优化:直接使用 setElement 更新现有对象,避免创建新对象和替换操作
|
||||
* @private
|
||||
*/
|
||||
async _updateObjectWithResult() {
|
||||
@@ -144,16 +146,27 @@ export class LiquifyCommand extends Command {
|
||||
|
||||
// 使用优化渲染工具,避免图层闪烁
|
||||
await optimizeCanvasRendering(this.canvas, async () => {
|
||||
// 预先加载图像,确保完全加载后再替换
|
||||
await new Promise((resolve, reject) => {
|
||||
fabric.Image.fromURL(tempCanvas.toDataURL(), (img) => {
|
||||
if (!img) {
|
||||
reject(new Error("图像加载失败"));
|
||||
return;
|
||||
}
|
||||
// 预加载图像元素,确保完全加载后再更新
|
||||
await this._updateObjectElementDirectly(tempCanvas.toDataURL());
|
||||
});
|
||||
|
||||
// 保留原对象的属性
|
||||
img.set({
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接更新对象的图像元素,避免对象替换造成的图层闪烁
|
||||
* @param {String} imageDataURL 图像数据的 DataURL
|
||||
* @private
|
||||
*/
|
||||
async _updateObjectElementDirectly(imageDataURL) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 创建 HTMLImageElement 并预加载
|
||||
const imgElement = new Image();
|
||||
|
||||
imgElement.onload = () => {
|
||||
try {
|
||||
// 保存当前对象状态(非图像属性)
|
||||
const currentState = {
|
||||
left: this.targetObject.left,
|
||||
top: this.targetObject.top,
|
||||
scaleX: this.targetObject.scaleX,
|
||||
@@ -162,31 +175,41 @@ export class LiquifyCommand extends Command {
|
||||
flipX: this.targetObject.flipX,
|
||||
flipY: this.targetObject.flipY,
|
||||
opacity: this.targetObject.opacity,
|
||||
});
|
||||
};
|
||||
|
||||
// 确保图像已完全加载(通过检查元素)
|
||||
if (img._element && img._element.complete) {
|
||||
this._replaceObjectSafely(img);
|
||||
resolve();
|
||||
} else {
|
||||
// 如果图像还未加载完成,等待加载
|
||||
img.on("loaded", () => {
|
||||
this._replaceObjectSafely(img);
|
||||
resolve();
|
||||
});
|
||||
img.on("error", (error) => {
|
||||
reject(error || new Error("图像加载失败"));
|
||||
});
|
||||
// 直接更新现有对象的图像元素,保持对象引用不变
|
||||
if (this.targetObject.setElement) {
|
||||
this.targetObject.setElement(imgElement);
|
||||
} else if (this.targetObject._element) {
|
||||
this.targetObject._element = imgElement;
|
||||
this.targetObject._originalElement = imgElement;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return true;
|
||||
// 恢复对象属性(setElement 可能会重置一些属性)
|
||||
this.targetObject.set(currentState);
|
||||
|
||||
// 标记对象需要重新渲染
|
||||
this.targetObject.dirty = true;
|
||||
this.targetObject.setCoords();
|
||||
|
||||
resolve();
|
||||
} catch (error) {
|
||||
console.error("更新对象元素失败:", error);
|
||||
reject(error);
|
||||
}
|
||||
};
|
||||
|
||||
imgElement.onerror = () => {
|
||||
reject(new Error("图像加载失败"));
|
||||
};
|
||||
|
||||
// 开始加载图像
|
||||
imgElement.src = imageDataURL;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全地替换对象,避免图层闪烁
|
||||
* 安全地替换对象,避免图层闪烁(保留作为备用方法)
|
||||
* @param {Object} newImg 新的fabric图像对象
|
||||
* @private
|
||||
*/
|
||||
@@ -323,6 +346,7 @@ export class LiquifyDeformCommand extends LiquifyCommand {
|
||||
|
||||
/**
|
||||
* 使用图像数据更新对象
|
||||
* 优化:直接使用 setElement 更新现有对象,避免创建新对象和替换操作
|
||||
* @param {ImageData} imageData 图像数据
|
||||
* @private
|
||||
*/
|
||||
@@ -336,47 +360,13 @@ export class LiquifyDeformCommand extends LiquifyCommand {
|
||||
|
||||
// 使用优化渲染工具,避免图层闪烁
|
||||
await optimizeCanvasRendering(this.canvas, async () => {
|
||||
// 预先加载图像,确保完全加载后再替换
|
||||
await new Promise((resolve, reject) => {
|
||||
fabric.Image.fromURL(tempCanvas.toDataURL(), (img) => {
|
||||
if (!img) {
|
||||
reject(new Error("图像加载失败"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 保留原对象的变换属性
|
||||
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,
|
||||
});
|
||||
|
||||
// 确保图像已完全加载
|
||||
if (img._element && img._element.complete) {
|
||||
this._replaceDeformObjectSafely(img);
|
||||
resolve();
|
||||
} else {
|
||||
// 如果图像还未加载完成,等待加载
|
||||
img.on("loaded", () => {
|
||||
this._replaceDeformObjectSafely(img);
|
||||
resolve();
|
||||
});
|
||||
img.on("error", (error) => {
|
||||
reject(error || new Error("图像加载失败"));
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
// 直接更新对象元素,避免对象替换
|
||||
await this._updateObjectElementDirectly(tempCanvas.toDataURL());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全地替换变形对象,避免图层闪烁
|
||||
* 安全地替换变形对象,避免图层闪烁(保留作为备用方法)
|
||||
* @param {Object} newImg 新的fabric图像对象
|
||||
* @private
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user