画布印花合成

This commit is contained in:
李志鹏
2026-01-05 11:47:36 +08:00
parent 780270882e
commit 73aca07391
13 changed files with 198 additions and 41 deletions

View File

@@ -13,6 +13,7 @@ import {
createLayer,
LayerType,
SpecialLayerId,
BlendMode,
} from "../utils/layerHelper";
import { ObjectMoveCommand } from "../commands/ObjectCommands";
import { AnimationManager } from "./animation/AnimationManager";
@@ -30,6 +31,7 @@ import {
fillToCssStyle,
calculateRotatedTopLeftDeg,
createPatternTransform,
base64ToCanvas,
} from "../utils/helper";
import { ChangeFixedImageCommand } from "../commands/ObjectLayerCommands";
import { isFunction } from "lodash-es";
@@ -564,15 +566,14 @@ export class CanvasManager {
}
// 更新颜色层信息
const fixedLayerObj = this.getFixedLayerObject();
const colorObject = this.getLayerObjectById(SpecialLayerId.COLOR);
if(colorObject && fixedLayerObj){
await this.setColorObjectInfo(colorObject, fixedLayerObj);
}
// const colorObject = this.getLayerObjectById(SpecialLayerId.COLOR);
// if(colorObject){
// await this.setObjecCliptInfo(colorObject);
// }
const groupLayer = this.layerManager.getLayerById(SpecialLayerId.SPECIAL_GROUP);
if(groupLayer && fixedLayerObj){
if(groupLayer){
const groupRect = new fabric.Rect({});
await this.setColorObjectInfo(groupRect, fixedLayerObj);
await this.setObjecCliptInfo(groupRect);
groupLayer.clippingMask = groupRect.toObject();
}
@@ -908,6 +909,7 @@ export class CanvasManager {
* @param {Object} options 导出选项
* @param {Boolean} options.isContainBg 是否包含背景图层
* @param {Boolean} options.isContainFixed 是否包含固定图层
* @param {Boolean} options.isContainFixedOther 是否包含其他固定图层
* @param {String} options.layerId 导出具体图层ID
* @param {Array} options.layerIdArray 导出多个图层ID数组
* @param {String} options.expPicType 导出图片类型 (png/jpg/svg)
@@ -948,7 +950,7 @@ export class CanvasManager {
const normalLayerIds =
this.layers?.value
?.filter(
(layer) => !layer.isBackground && !layer.isFixed && layer.visible
(layer) => !layer.isBackground && !layer.isFixed && !layer.isFixedOther && layer.visible
)
?.map((layer) => layer.id) || [];
@@ -1233,7 +1235,7 @@ export class CanvasManager {
// console.log("图层关联验证结果:", isValidate);
// 排序
// 使用LayerSort工具重新排列画布对象如果可用
await this?.layerManager?.layerSort?.rearrangeObjects();
// await this?.layerManager?.layerSort?.rearrangeObjects();
this.layerManager.activeLayerId.value = this.layers.value[0]
.children?.length
@@ -1304,10 +1306,15 @@ export class CanvasManager {
})
await this.createPrintTrimsLayers(printTrimsLayers, singleLayers);
}
await this.changeCanvas();
}
async setColorObjectInfo(colorRect, fixedLayerObj){
colorRect.set({
// 设置画布对象的裁剪信息
async setObjecCliptInfo(tagObject, data){
const fixedLayerObj = this.getFixedLayerObject();
if(!fixedLayerObj) return console.warn("固定图层为空");
tagObject.set({
top: fixedLayerObj.top,
left: fixedLayerObj.left,
width: fixedLayerObj.width,
@@ -1322,7 +1329,7 @@ export class CanvasManager {
if(imageUrl){
object = await new Promise((resolve, reject) => {
fabric.Image.fromURL(imageUrl, (imgObject) => {
colorRect.set({
tagObject.set({
width: imgObject.width,
height: imgObject.height,
});
@@ -1330,14 +1337,14 @@ export class CanvasManager {
}, { crossOrigin: "anonymous" });
});
}
const canvas = getObjectAlphaToCanvas(object);
const canvas = getObjectAlphaToCanvas(object, data);
const transparentMask = new fabric.Image(canvas, {
top: 0,
left: 0,
originX: fixedLayerObj.originX,
originY: fixedLayerObj.originY,
});
colorRect.set('clipPath', transparentMask);
tagObject.set('clipPath', transparentMask);
}
async createColorLayer(color){
if(!color) return console.warn("颜色为空不需要添加");
@@ -1351,8 +1358,9 @@ export class CanvasManager {
layerName: t("Canvas.color"),
isVisible: true,
isLocked: true,
globalCompositeOperation: BlendMode.MULTIPLY,
});
await this.setColorObjectInfo(colorRect, fixedLayerObj);
// await this.setObjecCliptInfo(colorRect);
const gradientObj = palletToFill(color);
const gradient = new fabric.Gradient({
type: 'linear',
@@ -1370,6 +1378,7 @@ export class CanvasManager {
locked: colorRect.isLocked,
opacity: 1.0,
isFixedOther: true,
blendMode: BlendMode.MULTIPLY,
fabricObjects: [colorRect.toObject(["id", "layerId", "layerName"])],
})
const groupIndex = this.layers.value.findIndex(layer => layer.isFixed || layer.isBackground);
@@ -1503,7 +1512,7 @@ export class CanvasManager {
children.push(layer);
}
const groupRect = new fabric.Rect({});
await this.setColorObjectInfo(groupRect, fixedLayerObj);
await this.setObjecCliptInfo(groupRect);
// 插入组图层
const groupIndex = this.layers.value.findIndex(layer => layer.isFixedOther || layer.isFixed || layer.isBackground);
const groupLayer = createLayer({
@@ -1521,6 +1530,34 @@ export class CanvasManager {
this.layers.value.splice(groupIndex, 0, groupLayer);
}
/**
*
*/
async changeCanvas(){
const fixedLayerObj = this.getFixedLayerObject();
if(!fixedLayerObj) return console.warn("固定图层对象不存在", fixedLayerObj)
const colorObject = this.getLayerObjectById(SpecialLayerId.COLOR);
if(colorObject){
const ids = this.layerManager.getBlendModeLayerIds(SpecialLayerId.SPECIAL_GROUP);
if(ids.length === 0){
ids.unshift(SpecialLayerId.SPECIAL_GROUP);
await this.setObjecCliptInfo(colorObject);
return;
}
const base64 = await this.exportManager.exportImage({layerIdArray2: ids, isEnhanceImg: true});
if(!base64) return console.warn("导出图片失败", base64)
const canvas = await base64ToCanvas(base64, fixedLayerObj.scaleX * 2, true);
const ctx = canvas.getContext('2d');
const width = fixedLayerObj.width;
const height = fixedLayerObj.height;
const x = (canvas.width - width) / 2;
const y = (canvas.height - height) / 2;
const data = ctx.getImageData(x, y, width, height);
await this.setObjecCliptInfo(colorObject, data);
this.canvas.renderAll();
}
}
/**
* 缩放红绿图模式内容以适应当前画布大小
* 确保衣服底图和红绿图永远在画布内可见