更改不平铺的样式

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); console.warn("当前对象不能平铺", object.type);
return false; return false;
} }
console.log("===========", object.toObject(["id", "layerId", "layerName"]))
this.oldObjects = object; this.oldObjects = object;
const img = await new Promise((resolve, reject) => { if (this.fillRepeat === "no-repeat") {
if (object.type === "rect") { const fill_ = object.fill_;
let source = object.fill.source; const image = await new Promise((resolve, reject) => {
resolve(source); fabric.Image.fromURL(
} else if (object.type === "image") { fill_.source,
// resolve(object.getElement()); v => resolve(v),
// fabric.Image.fromURL( { crossOrigin: "anonymous" }
// 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,
}); });
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 { } else {
let scaleX = bgObject.scaleX || 1; const img = await new Promise((resolve, reject) => {
let scaleY = bgObject.scaleY || 1; if (object.type === "rect") {
rect.set({ let source = object.fill.source;
width: bgObject.width, resolve(source);
height: bgObject.height, } else if (object.type === "image") {
top: bgObject.top - bgObject.height * scaleY / 2, const imgElement = object.getElement();
left: bgObject.left - bgObject.width * scaleX / 2, // 创建透明 Canvas
scaleX, const tcanvas = document.createElement('canvas');
scaleY, 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?.updateLayersObjectsInteractivity();
await this.layerManager?.sortLayersWithTool?.(); await this.layerManager?.sortLayersWithTool?.();
await this.canvasManager.thumbnailManager?.generateLayerThumbnail( await this.canvasManager.thumbnailManager?.generateLayerThumbnail(

View File

@@ -1162,68 +1162,6 @@ export class CanvasManager {
} }
getJSON() { 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 { try {
// 清除画布中选中状态 // 清除画布中选中状态
// this.canvas.discardActiveObject(); // this.canvas.discardActiveObject();
@@ -1669,18 +1607,19 @@ export class CanvasManager {
}) })
children.push(layer); children.push(layer);
}; };
if(children.length === 0){ // if(children.length === 0){
let layer = createLayer({ // let layer = createLayer({
id: generateId("layer_image_"), // id: generateId("layer_image_"),
name: t("Canvas.EmptyLayer"), // name: t("Canvas.EmptyLayer"),
type: LayerType.BITMAP, // type: LayerType.BITMAP,
visible: true, // visible: true,
locked: false, // locked: false,
opacity: 1.0, // opacity: 1.0,
fabricObjects: [], // fabricObjects: [],
}) // })
children.push(layer); // children.push(layer);
} // }
if(children.length === 0) return;
const groupRect = new fabric.Rect({}); const groupRect = new fabric.Rect({});
await this.setObjecCliptInfo(groupRect); await this.setObjecCliptInfo(groupRect);
// 插入组图层 // 插入组图层

View File

@@ -191,6 +191,7 @@ export function createLayer(options = {}) {
generateId("layer_") || generateId("layer_") ||
`layer_${Date.now()}_${Math.floor(Math.random() * 1000)}`; `layer_${Date.now()}_${Math.floor(Math.random() * 1000)}`;
return { return {
...options,
id: id, id: id,
// 图层基本属性 // 图层基本属性
name: options.name || `图层 ${id.substring(id.lastIndexOf("_") + 1)}`, 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 {fabric.Object} object - 要处理的 fabric 对象
* @param {ImageData} revData - 相反的ImageData白通道的相同位置是否为透明revData为白色为透明黑色为不透明 * @param {ImageData} revData - 相反的ImageData白通道的相同位置是否为透明revData为白色为透明黑色为不透明
* @param {number} diff - 差值,默认 25
* @returns {HTMLCanvasElement|null} 包含黑白通道的画布,或 null 如果失败 * @returns {HTMLCanvasElement|null} 包含黑白通道的画布,或 null 如果失败
*/ */
export function getObjectAlphaToCanvas(object, revData) { export function getObjectAlphaToCanvas(object, revData, diff = 30) {
const image = object.getElement(); const image = object.getElement();
const { width, height } = image; const { width, height } = image;
if (!width || !height) { if (!width || !height) {
@@ -88,7 +89,7 @@ export function getObjectAlphaToCanvas(object, revData) {
const revB = revData?.data[i + 2] || 0; const revB = revData?.data[i + 2] || 0;
const revA = revData?.data[i + 3] || 0; const revA = revData?.data[i + 3] || 0;
if (r || g || b || a) { 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 + 0] = 0;
data.data[i + 1] = 0; data.data[i + 1] = 0;
data.data[i + 2] = 0; data.data[i + 2] = 0;