feat: 裁剪组裁剪跟随选择组移动

This commit is contained in:
bighuixiang
2025-07-14 01:00:23 +08:00
parent 96e13cb22a
commit 24e9ba8ae5
80 changed files with 2052 additions and 4292 deletions

View File

@@ -22,9 +22,7 @@ export class CreateBackgroundLayerCommand extends Command {
execute() {
// 检查是否已经存在背景图层
const existingBgLayer = this.layers.value.find(
(layer) => layer.isBackground
);
const existingBgLayer = this.layers.value.find((layer) => layer.isBackground);
if (existingBgLayer) {
console.warn("已存在背景层,不重复创建");
return existingBgLayer.id;
@@ -34,11 +32,7 @@ export class CreateBackgroundLayerCommand extends Command {
const bgObject = this._createBackgroundObject();
// 将背景对象添加到图层中
this.backgroundLayer.fabricObject = bgObject.toObject([
"id",
"layerId",
"type",
]);
this.backgroundLayer.fabricObject = bgObject.toObject(["id", "layerId", "type"]);
// 添加图层到最底部
this.layers.value.push(this.backgroundLayer);
@@ -54,9 +48,7 @@ export class CreateBackgroundLayerCommand extends Command {
undo() {
// 从图层列表中删除背景图层
const bgLayerIndex = this.layers.value.findIndex(
(layer) => layer.isBackground
);
const bgLayerIndex = this.layers.value.findIndex((layer) => layer.isBackground);
if (bgLayerIndex !== -1) {
this.layers.value.splice(bgLayerIndex, 1);
}
@@ -82,8 +74,7 @@ export class CreateBackgroundLayerCommand extends Command {
// 确保背景色为白色,如果没有设置或者是透明的话
const backgroundColor =
this.backgroundLayer.backgroundColor &&
this.backgroundLayer.backgroundColor !== "transparent"
this.backgroundLayer.backgroundColor && this.backgroundLayer.backgroundColor !== "transparent"
? this.backgroundLayer.backgroundColor
: "#ffffff";
@@ -139,10 +130,7 @@ export class UpdateBackgroundCommand extends Command {
// 查找背景图层
this.bgLayer = this.layers.value.find((layer) => layer.isBackground);
this.oldBackgroundColor = this.oldColor;
this.backgroundObject = findObjectById(
this.canvas,
this.bgLayer.fabricObject.id
).object;
this.backgroundObject = findObjectById(this.canvas, this.bgLayer.fabricObject.id).object;
}
execute() {
@@ -163,9 +151,7 @@ export class UpdateBackgroundCommand extends Command {
this.backgroundColorValue.value = this.backgroundColor; // 设置背景颜色
// 生成缩略图
this.canvasManager?.thumbnailManager?.generateLayerThumbnail?.(
this.bgLayer.id
);
this.canvasManager?.thumbnailManager?.generateLayerThumbnail?.(this.bgLayer.id);
return true;
}
@@ -186,9 +172,7 @@ export class UpdateBackgroundCommand extends Command {
this.backgroundColorValue.value = this.oldBackgroundColor; // 恢复背景颜色
// 生成缩略图
this.canvasManager?.thumbnailManager?.generateLayerThumbnail?.(
this.bgLayer.id
);
this.canvasManager?.thumbnailManager?.generateLayerThumbnail?.(this.bgLayer.id);
// 如果有旧颜色,恢复到旧颜色
return true;
}
@@ -223,10 +207,7 @@ export class BackgroundSizeCommand extends Command {
this.bgLayer = this.layers.value.find((layer) => layer.isBackground);
// 记录原尺寸
this.backgroundObject = findObjectById(
this.canvas,
this.bgLayer.fabricObject.id
).object;
this.backgroundObject = findObjectById(this.canvas, this.bgLayer.fabricObject.id).object;
this.oldWidth = this.backgroundObject.width;
this.oldHeight = this.backgroundObject.height;
@@ -255,8 +236,7 @@ export class BackgroundSizeCommand extends Command {
// 调整背景对象大小
if (this.bgLayer && this.backgroundObject) {
// 保持原有的背景颜色,如果没有设置则使用白色
const currentFill =
this.backgroundObject.fill || this.bgLayer.backgroundColor || "#ffffff";
const currentFill = this.backgroundObject.fill || this.bgLayer.backgroundColor || "#ffffff";
this.backgroundObject.set({
width: this.newWidth,
@@ -343,10 +323,7 @@ export class BackgroundSizeWithScaleCommand extends Command {
// 查找背景图层
this.bgLayer = this.layers.value.find((layer) => layer.isBackground);
this.backgroundObject = findObjectById(
this.canvas,
this.bgLayer.fabricObject.id
).object;
this.backgroundObject = findObjectById(this.canvas, this.bgLayer.fabricObject.id).object;
// 计算缩放比例
const scaleXRatio = this.newWidth / this.oldWidth;
@@ -409,24 +386,21 @@ export class BackgroundSizeWithScaleCommand extends Command {
// 统一缩放:使用平均值,保持相对比例的同时允许适度的形变
this.uniformScale = Math.sqrt(scaleXRatio * scaleYRatio);
this.offsetX = (this.newWidth - this.oldWidth * this.uniformScale) / 2;
this.offsetY =
(this.newHeight - this.oldHeight * this.uniformScale) / 2;
this.offsetY = (this.newHeight - this.oldHeight * this.uniformScale) / 2;
break;
case "fit":
// 适应模式:使用较小值,确保所有内容都在画布内,可能有留白
this.uniformScale = Math.min(scaleXRatio, scaleYRatio);
this.offsetX = (this.newWidth - this.oldWidth * this.uniformScale) / 2;
this.offsetY =
(this.newHeight - this.oldHeight * this.uniformScale) / 2;
this.offsetY = (this.newHeight - this.oldHeight * this.uniformScale) / 2;
break;
case "fill":
// 填充模式:使用较大值,填满画布,可能有部分内容被裁切
this.uniformScale = Math.max(scaleXRatio, scaleYRatio);
this.offsetX = (this.newWidth - this.oldWidth * this.uniformScale) / 2;
this.offsetY =
(this.newHeight - this.oldHeight * this.uniformScale) / 2;
this.offsetY = (this.newHeight - this.oldHeight * this.uniformScale) / 2;
break;
case "stretch":
@@ -441,8 +415,7 @@ export class BackgroundSizeWithScaleCommand extends Command {
// 默认使用uniform模式
this.uniformScale = Math.sqrt(scaleXRatio * scaleYRatio);
this.offsetX = (this.newWidth - this.oldWidth * this.uniformScale) / 2;
this.offsetY =
(this.newHeight - this.oldHeight * this.uniformScale) / 2;
this.offsetY = (this.newHeight - this.oldHeight * this.uniformScale) / 2;
}
}
@@ -462,8 +435,7 @@ export class BackgroundSizeWithScaleCommand extends Command {
// 调整背景对象大小和位置
if (this.bgLayer && this.backgroundObject) {
// 保持原有的背景颜色,如果没有设置则使用白色
const currentFill =
this.backgroundObject.fill || this.bgLayer.backgroundColor || "#ffffff";
const currentFill = this.backgroundObject.fill || this.bgLayer.backgroundColor || "#ffffff";
this.backgroundObject.set({
width: this.newWidth,
@@ -480,12 +452,10 @@ export class BackgroundSizeWithScaleCommand extends Command {
// 计算基于原始画布的缩放比例
const baseScaleX =
this.newWidth /
this.objectStates[0]?.obj._originalState?.baseCanvasWidth ||
this.newWidth / this.objectStates[0]?.obj._originalState?.baseCanvasWidth ||
this.newWidth / this.oldWidth;
const baseScaleY =
this.newHeight /
this.objectStates[0]?.obj._originalState?.baseCanvasHeight ||
this.newHeight / this.objectStates[0]?.obj._originalState?.baseCanvasHeight ||
this.newHeight / this.oldHeight;
// 根据策略缩放所有非背景对象
@@ -505,13 +475,11 @@ export class BackgroundSizeWithScaleCommand extends Command {
const baseUniformScale = Math.sqrt(baseScaleX * baseScaleY);
const baseOffsetX =
(this.newWidth -
(obj._originalState?.baseCanvasWidth || this.oldWidth) *
baseUniformScale) /
(obj._originalState?.baseCanvasWidth || this.oldWidth) * baseUniformScale) /
2;
const baseOffsetY =
(this.newHeight -
(obj._originalState?.baseCanvasHeight || this.oldHeight) *
baseUniformScale) /
(obj._originalState?.baseCanvasHeight || this.oldHeight) * baseUniformScale) /
2;
obj.set({
@@ -537,10 +505,7 @@ export class BackgroundSizeWithScaleCommand extends Command {
this.canvas.setHeight(this.oldHeight);
// 如果使用 CanvasManager通知它画布大小恢复
if (
this.canvasManager &&
typeof this.canvasManager.updateCanvasSize === "function"
) {
if (this.canvasManager && typeof this.canvasManager.updateCanvasSize === "function") {
this.canvasManager.updateCanvasSize(this.oldWidth, this.oldHeight);
}
@@ -568,12 +533,9 @@ export class BackgroundSizeWithScaleCommand extends Command {
const baseScaleX = this.oldWidth / originalState.baseCanvasWidth;
const baseScaleY = this.oldHeight / originalState.baseCanvasHeight;
const baseUniformScale = Math.sqrt(baseScaleX * baseScaleY);
const baseOffsetX =
(this.oldWidth - originalState.baseCanvasWidth * baseUniformScale) /
2;
const baseOffsetX = (this.oldWidth - originalState.baseCanvasWidth * baseUniformScale) / 2;
const baseOffsetY =
(this.oldHeight - originalState.baseCanvasHeight * baseUniformScale) /
2;
(this.oldHeight - originalState.baseCanvasHeight * baseUniformScale) / 2;
obj.set({
left: originalState.left * baseUniformScale + baseOffsetX,