feat: 添加对图层操作的支持,优化图层粘贴和变换命令,增强组图层遮罩位置更新逻辑
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
import { findObjectById } from "../utils/helper";
|
||||
import { findLayerRecursively } from "../utils/layerHelper";
|
||||
import { restoreFabricObject } from "../utils/objectHelper";
|
||||
import { Command } from "./Command";
|
||||
|
||||
/**
|
||||
@@ -18,6 +21,18 @@ export class TransformCommand extends Command {
|
||||
this.initialState = options.initialState || null;
|
||||
this.finalState = options.finalState || null;
|
||||
this.objectType = options.objectType || "object";
|
||||
this.layerManager = options.layerManager;
|
||||
this.layers = options.layers || null;
|
||||
this.lastSelectLayerId = options.lastSelectLayerId || null; // 最后选择的图层ID
|
||||
|
||||
const targetObject = findObjectById(this.canvas, this.objectId)?.object || null;
|
||||
|
||||
const { layer, parent } = findLayerRecursively(this.layers.value, targetObject?.layerId);
|
||||
|
||||
this.layer = layer;
|
||||
this.parent = parent;
|
||||
|
||||
this.isSginleObject = parent?.id === this.lastSelectLayerId?.value; // 是否需要记录遮罩的变换位置 如果是组图层且组下只有一个图层有对象 且 用户最后点击的是父图层 则记录遮罩变更
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -25,7 +40,7 @@ export class TransformCommand extends Command {
|
||||
* 如果是首次执行,记录初始和最终状态
|
||||
* 如果是重做,应用最终状态
|
||||
*/
|
||||
execute() {
|
||||
async execute() {
|
||||
if (!this.finalState) {
|
||||
console.warn("没有最终状态可应用");
|
||||
return false;
|
||||
@@ -39,7 +54,7 @@ export class TransformCommand extends Command {
|
||||
}
|
||||
|
||||
// 应用最终变换状态
|
||||
this._applyTransform(targetObject, this.finalState);
|
||||
await this._applyTransform(targetObject, this.finalState);
|
||||
|
||||
// 触发画布更新
|
||||
this.canvas.renderAll();
|
||||
@@ -51,7 +66,7 @@ export class TransformCommand extends Command {
|
||||
* 撤销命令
|
||||
* 应用初始状态
|
||||
*/
|
||||
undo() {
|
||||
async undo() {
|
||||
if (!this.initialState) {
|
||||
console.warn("没有初始状态可恢复");
|
||||
return false;
|
||||
@@ -65,7 +80,7 @@ export class TransformCommand extends Command {
|
||||
}
|
||||
|
||||
// 应用初始变换状态
|
||||
this._applyTransform(targetObject, this.initialState);
|
||||
await this._applyTransform(targetObject, this.initialState);
|
||||
|
||||
// 触发画布更新
|
||||
this.canvas.renderAll();
|
||||
@@ -86,8 +101,41 @@ export class TransformCommand extends Command {
|
||||
* 应用变换状态到对象
|
||||
* @private
|
||||
*/
|
||||
_applyTransform(object, transformState) {
|
||||
async _applyTransform(object, transformState) {
|
||||
if (!object || !transformState) return;
|
||||
// 变换遮罩层 - 如果当前图层是组图层,且有遮罩并且组下只有一个图层有对象 则应用遮罩转换
|
||||
if (
|
||||
this.parent &&
|
||||
this.parent?.clippingMask &&
|
||||
this.parent?.children?.length === 1 &&
|
||||
this.isSginleObject
|
||||
) {
|
||||
// 计算对象的变换位置
|
||||
const moveLeft = object.left - transformState.left; // 计算移动的水平距离
|
||||
const moveTop = object.top - transformState.top; // 计算移动的垂直距离
|
||||
|
||||
this.parent.clippingMask.left -= moveLeft;
|
||||
this.parent.clippingMask.top -= moveTop;
|
||||
|
||||
// 重新创建遮罩对象
|
||||
const clippingMaskFabricObject = await restoreFabricObject(
|
||||
this.parent.clippingMask,
|
||||
this.canvas
|
||||
);
|
||||
|
||||
if (clippingMaskFabricObject) {
|
||||
clippingMaskFabricObject.clipPath = null;
|
||||
clippingMaskFabricObject.set({
|
||||
absolutePositioned: true,
|
||||
});
|
||||
|
||||
clippingMaskFabricObject.dirty = true;
|
||||
clippingMaskFabricObject.setCoords();
|
||||
|
||||
const clippingMask = this.parent.clippingMask;
|
||||
object.clipPath = clippingMask;
|
||||
}
|
||||
}
|
||||
|
||||
// 应用变换属性,只设置真正变化的值
|
||||
Object.entries(transformState).forEach(([key, value]) => {
|
||||
|
||||
Reference in New Issue
Block a user