import { fabric } from "fabric-with-all"; /** * 将序列化对象恢复为 fabric 对象 * @param {Object} serializedObject - toObject() 生成的对象 * @param {fabric.Canvas} canvas - 目标画布 * @returns {Promise} 恢复的 fabric 对象 */ export async function restoreFabricObject(serializedObject, canvas) { return new Promise((resolve, reject) => { const objectType = serializedObject.type; // 定义恢复后的处理函数 const handleRestoredObject = (fabricObject) => { if (!fabricObject) { reject(new Error(`无法恢复 ${objectType} 类型的对象`)); return; } // 恢复自定义属性 if (serializedObject.id) fabricObject.id = serializedObject.id; if (serializedObject.layerId) fabricObject.layerId = serializedObject.layerId; if (serializedObject.layerName) fabricObject.layerName = serializedObject.layerName; // 更新坐标 fabricObject.setCoords(); // 添加到画布 // canvas.add(fabricObject); resolve(fabricObject); }; // 根据类型选择恢复方法 switch (objectType) { case "rect": fabric.Rect.fromObject(serializedObject, handleRestoredObject); break; case "circle": fabric.Circle.fromObject(serializedObject, handleRestoredObject); break; case "path": fabric.Path.fromObject(serializedObject, handleRestoredObject); break; case "image": fabric.Image.fromObject(serializedObject, handleRestoredObject); break; case "group": fabric.Group.fromObject(serializedObject, handleRestoredObject); break; default: // 使用通用方法 fabric.util.enlivenObjects([serializedObject], (objects) => { if (objects && objects[0]) { handleRestoredObject(objects[0]); } else { reject(new Error("对象恢复失败")); } }); } }); } /** * 获取对象黑白通道画布 * @param {fabric.Object} object - 要处理的 fabric 对象 * @param {ImageData} revData - 相反的ImageData,白通道的相同位置是否为透明,revData为白色为透明,黑色为不透明 * @param {number} diff - 差值,默认 25 * @param {Object} rgba - 自定义 rgba 值,默认 { r: 255, g: 255, b: 255, a: 255 } * @returns {HTMLCanvasElement|null} 包含黑白通道的画布,或 null 如果失败 */ export function getObjectAlphaToCanvas(object, revData, diff = 30, rgba = { r: 255, g: 255, b: 255, a: 255 }) { const image = object.getElement(); const { width, height } = image; if (!width || !height) { console.warn("对象没有元素"); return null; } const canvas = document.createElement("canvas"); canvas.width = width; canvas.height = height; const ctx = canvas.getContext("2d"); ctx.drawImage(image, 0, 0, width, height); const data = ctx.getImageData(0, 0, width, height); for (let i = 0; i < data.data.length; i += 4) { const r = data.data[i + 0]; const g = data.data[i + 1]; const b = data.data[i + 2]; const a = data.data[i + 3]; const revR = revData?.data[i + 0] || 0; const revG = revData?.data[i + 1] || 0; const revB = revData?.data[i + 2] || 0; const revA = revData?.data[i + 3] || 0; if (r || g || b || a) { if (revR > diff || revG > diff || revB > diff || revA > diff) { data.data[i + 0] = 0; data.data[i + 1] = 0; data.data[i + 2] = 0; data.data[i + 3] = 0; } else { data.data[i + 0] = rgba.r; data.data[i + 1] = rgba.g; data.data[i + 2] = rgba.b; data.data[i + 3] = rgba.a; } } else { data.data[i + 0] = 0; data.data[i + 1] = 0; data.data[i + 2] = 0; data.data[i + 3] = 0; } } ctx.clearRect(0, 0, width, height); ctx.putImageData(data, 0, 0); return canvas; }