更改不平铺的样式

This commit is contained in:
李志鹏
2026-01-08 15:25:15 +08:00
parent 9d41602320
commit 5bbc71654a
4 changed files with 118 additions and 150 deletions

View File

@@ -52,85 +52,112 @@ export class FillRepeatCommand extends Command {
console.warn("当前对象不能平铺", object.type);
return false;
}
console.log("===========", object.toObject(["id", "layerId", "layerName"]))
this.oldObjects = object;
const img = await new Promise((resolve, reject) => {
if (object.type === "rect") {
let source = object.fill.source;
resolve(source);
} else if (object.type === "image") {
// resolve(object.getElement());
// fabric.Image.fromURL(
// object.src,
// v => resolve(v),
// { crossOrigin: "anonymous" }
// );
const imgElement = object.getElement();
// 创建透明 Canvas
const tcanvas = document.createElement('canvas');
tcanvas.width = imgElement.width;
tcanvas.height = imgElement.height;
const ctx = tcanvas.getContext('2d');
ctx.clearRect(0, 0, tcanvas.width, tcanvas.height);
ctx.drawImage(imgElement, 0, 0);
resolve(tcanvas);
}
});
const fill_ = {
source: FillSourceToBase64(img),
gapX: 0,
gapY: 0,
width: img.width,
height: img.height,
};
const bgObject = this.canvasManager.getBackgroundLayerObject();
const pattern = new fabric.Pattern({
source: img,
repeat: this.fillRepeat,
patternTransform: object.fill?.hasOwnProperty("patternTransform") ? object.fill.patternTransform : createPatternTransform(scale, 0),
offsetX: object.fill?.hasOwnProperty("offsetX") ? object.fill.offsetX : bgObject.width / 2, // 水平偏移
offsetY: object.fill?.hasOwnProperty("offsetY") ? object.fill.offsetY : bgObject.height / 2, // 垂直偏移
});
const rect = new fabric.Rect({
id: object.id,
layerId: object.layerId,
layerName: object.layerName,
fill_,
});
layer.fabricObjects = [rect.toObject(["id", "layerId", "layerName"])];
this.oldLocked = layer.locked;
// this.oldIsDisableUnlock = layer.isDisableUnlock;
// layer.isDisableUnlock = true;
if (this.oldObjects.type === "rect") {
rect.set({
width: object.width,
height: object.height,
top: object.top,
left: object.left,
originX: object.originX,
originY: object.originY,
angle: object.angle,
scaleX: object.scaleX,
scaleY: object.scaleY,
flipX: object.flipX,
flipY: object.flipY,
if (this.fillRepeat === "no-repeat") {
const fill_ = object.fill_;
const image = await new Promise((resolve, reject) => {
fabric.Image.fromURL(
fill_.source,
v => resolve(v),
{ crossOrigin: "anonymous" }
);
});
image.set({
id: object.id,
layerId: object.layerId,
layerName: object.layerName,
...(fill_.originalInfo || {
top: object.top,
left: object.left,
})
});
layer.fabricObjects = [image.toObject(["id", "layerId", "layerName"])];
this.oldLocked = layer.locked;
layer.locked = false;
this.canvas.add(image);
this.canvas.remove(object);
} else {
let scaleX = bgObject.scaleX || 1;
let scaleY = bgObject.scaleY || 1;
rect.set({
width: bgObject.width,
height: bgObject.height,
top: bgObject.top - bgObject.height * scaleY / 2,
left: bgObject.left - bgObject.width * scaleX / 2,
scaleX,
scaleY,
const img = await new Promise((resolve, reject) => {
if (object.type === "rect") {
let source = object.fill.source;
resolve(source);
} else if (object.type === "image") {
const imgElement = object.getElement();
// 创建透明 Canvas
const tcanvas = document.createElement('canvas');
tcanvas.width = imgElement.width;
tcanvas.height = imgElement.height;
const ctx = tcanvas.getContext('2d');
ctx.clearRect(0, 0, tcanvas.width, tcanvas.height);
ctx.drawImage(imgElement, 0, 0);
resolve(tcanvas);
}
});
layer.locked = true;
const fill_ = object.fill_ || {
source: FillSourceToBase64(img),
gapX: 0,
gapY: 0,
width: img.width,
height: img.height,
originalInfo: {
top: object.top,
left: object.left,
scaleX: object.scaleX,
scaleY: object.scaleY,
width: object.width,
height: object.height,
}
};
const bgObject = this.canvasManager.getBackgroundLayerObject();
const pattern = new fabric.Pattern({
source: img,
repeat: this.fillRepeat,
patternTransform: object.fill?.hasOwnProperty("patternTransform") ? object.fill.patternTransform : createPatternTransform(scale, 0),
offsetX: object.fill?.hasOwnProperty("offsetX") ? object.fill.offsetX : bgObject.width / 2, // 水平偏移
offsetY: object.fill?.hasOwnProperty("offsetY") ? object.fill.offsetY : bgObject.height / 2, // 垂直偏移
});
const rect = new fabric.Rect({
id: object.id,
layerId: object.layerId,
layerName: object.layerName,
fill_,
});
layer.fabricObjects = [rect.toObject(["id", "layerId", "layerName"])];
this.oldLocked = layer.locked;
// this.oldIsDisableUnlock = layer.isDisableUnlock;
// layer.isDisableUnlock = true;
if (this.oldObjects.type === "rect") {
rect.set({
width: object.width,
height: object.height,
top: object.top,
left: object.left,
originX: object.originX,
originY: object.originY,
angle: object.angle,
scaleX: object.scaleX,
scaleY: object.scaleY,
flipX: object.flipX,
flipY: object.flipY,
});
} else {
let scaleX = bgObject.scaleX || 1;
let scaleY = bgObject.scaleY || 1;
rect.set({
width: bgObject.width,
height: bgObject.height,
top: bgObject.top - bgObject.height * scaleY / 2,
left: bgObject.left - bgObject.width * scaleX / 2,
scaleX,
scaleY,
});
layer.locked = true;
}
rect.set("fill", pattern);
this.canvas.add(rect);
this.canvas.remove(object);
}
rect.set("fill", pattern);
this.canvas.add(rect);
this.canvas.remove(object);
await this.layerManager?.updateLayersObjectsInteractivity();
await this.layerManager?.sortLayersWithTool?.();
await this.canvasManager.thumbnailManager?.generateLayerThumbnail(

View File

@@ -1162,68 +1162,6 @@ export class CanvasManager {
}
getJSON() {
// // 简化图层数据在loadJSON时要根据id恢复引用
// const simplifyLayers = (layers) => {
// return layers.map((layer) => {
// if (layer?.children?.length) {
// layer.children = layer.children.map((child) => {
// return {
// id: child.id,
// type: child.type,
// layerId: child.layerId,
// layerName: child.layerName,
// isBackground: child.isBackground,
// isLocked: child.isLocked,
// isVisible: child.isVisible,
// isFixed: child.isFixed,
// parentId: child.parentId,
// fabricObject: child.fabricObject
// ? {
// id: child.fabricObject.id,
// type: child.fabricObject.type,
// layerId: child.fabricObject.layerId,
// layerName: child.fabricObject.layerName,
// }
// : {},
// fabricObjects:
// child.fabricObjects?.map((obj) => ({
// id: obj.id,
// type: obj.type,
// layerId: obj.layerId,
// layerName: obj.layerName,
// })) || [],
// };
// });
// }
// return {
// id: layer.id,
// type: layer.type,
// layerId: layer.layerId,
// layerName: layer.layerName,
// isBackground: layer.isBackground,
// isLocked: layer.isLocked,
// isVisible: layer.isVisible,
// isFixed: layer.isFixed,
// parentId: layer.parentId,
// fabricObject: child.fabricObject
// ? {
// id: child.fabricObject.id,
// type: child.fabricObject.type,
// layerId: child.fabricObject.layerId,
// layerName: child.fabricObject.layerName,
// }
// : {},
// fabricObjects:
// child.fabricObjects?.map((obj) => ({
// id: obj.id,
// type: obj.type,
// layerId: obj.layerId,
// layerName: obj.layerName,
// })) || [],
// children: layer.children,
// };
// });
// };
try {
// 清除画布中选中状态
// this.canvas.discardActiveObject();
@@ -1669,18 +1607,19 @@ export class CanvasManager {
})
children.push(layer);
};
if(children.length === 0){
let layer = createLayer({
id: generateId("layer_image_"),
name: t("Canvas.EmptyLayer"),
type: LayerType.BITMAP,
visible: true,
locked: false,
opacity: 1.0,
fabricObjects: [],
})
children.push(layer);
}
// if(children.length === 0){
// let layer = createLayer({
// id: generateId("layer_image_"),
// name: t("Canvas.EmptyLayer"),
// type: LayerType.BITMAP,
// visible: true,
// locked: false,
// opacity: 1.0,
// fabricObjects: [],
// })
// children.push(layer);
// }
if(children.length === 0) return;
const groupRect = new fabric.Rect({});
await this.setObjecCliptInfo(groupRect);
// 插入组图层

View File

@@ -191,6 +191,7 @@ export function createLayer(options = {}) {
generateId("layer_") ||
`layer_${Date.now()}_${Math.floor(Math.random() * 1000)}`;
return {
...options,
id: id,
// 图层基本属性
name: options.name || `图层 ${id.substring(id.lastIndexOf("_") + 1)}`,

View File

@@ -63,9 +63,10 @@ export async function restoreFabricObject(serializedObject, canvas) {
* 获取对象黑白通道画布
* @param {fabric.Object} object - 要处理的 fabric 对象
* @param {ImageData} revData - 相反的ImageData白通道的相同位置是否为透明revData为白色为透明黑色为不透明
* @param {number} diff - 差值,默认 25
* @returns {HTMLCanvasElement|null} 包含黑白通道的画布,或 null 如果失败
*/
export function getObjectAlphaToCanvas(object, revData) {
export function getObjectAlphaToCanvas(object, revData, diff = 30) {
const image = object.getElement();
const { width, height } = image;
if (!width || !height) {
@@ -88,7 +89,7 @@ export function getObjectAlphaToCanvas(object, revData) {
const revB = revData?.data[i + 2] || 0;
const revA = revData?.data[i + 3] || 0;
if (r || g || b || a) {
if (revR || revG || revB || revA) {
if (revR > diff || revG > diff || revB > diff || revA > diff) {
data.data[i + 0] = 0;
data.data[i + 1] = 0;
data.data[i + 2] = 0;