深度画布bug
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { fabric } from 'fabric-with-all'
|
||||
import { OperationType } from '../tools/layerHelper'
|
||||
import { getObjectAlphaToCanvas, traceImageContour, cloneObjects } from '../tools/canvasMethod'
|
||||
import { getObjectAlphaToCanvas, traceImageContour, clipCanvasTransparent, cloneObjects } from '../tools/canvasMethod'
|
||||
import { getSegAnythingImage } from '@/api/depth-canvas'
|
||||
import { useGlobalStore, useUserInfoStore } from '@/stores'
|
||||
|
||||
@@ -256,28 +256,46 @@ export class AISelectboxToolManager {
|
||||
if (!this.demoObject) return
|
||||
const fobject = this.demoObject
|
||||
this.clearDemoObject()
|
||||
const tcanvas = await this.createStaticCanvas(fobject)
|
||||
const canvas = getObjectAlphaToCanvas(tcanvas, null, 0, { r: 255, g: 0, b: 0, a: 255 });
|
||||
const arr = traceImageContour(canvas);
|
||||
const scaleY = fobject.scaleY
|
||||
const scaleX = fobject.scaleX
|
||||
const top = fobject.top
|
||||
const left = fobject.left
|
||||
let minX = fobject.width;
|
||||
let minY = fobject.height;
|
||||
const str = arr.map((v) => {
|
||||
if (v.x < minX) minX = v.x;
|
||||
if (v.y < minY) minY = v.y;
|
||||
return `${v.x} ${v.y}`
|
||||
}).join(" L ");
|
||||
const path = new fabric.Path(`M ${str} z`);
|
||||
const tcanvas = await this.createStaticCanvas(fobject)
|
||||
const canvas = getObjectAlphaToCanvas(tcanvas, null, 0, { r: 255, g: 255, b: 255, a: 255 });
|
||||
|
||||
/** 路径裁剪法 */
|
||||
// const arr = traceImageContour(canvas);
|
||||
// const str = arr.map((v) => {
|
||||
// if (v.x < minX) minX = v.x;
|
||||
// if (v.y < minY) minY = v.y;
|
||||
// return `${v.x} ${v.y}`
|
||||
// }).join(" L ");
|
||||
// const path = new fabric.Path(`M ${str} z`);
|
||||
// path.set({
|
||||
// left: left + minX,
|
||||
// top: top + minY,
|
||||
// scaleX: scaleX,
|
||||
// scaleY: scaleY,
|
||||
// ...this.selectionStyle,
|
||||
// });
|
||||
|
||||
/** 图片裁剪法 */
|
||||
const info = clipCanvasTransparent(canvas)
|
||||
minX = info.minX
|
||||
minY = info.minY
|
||||
const path = new fabric.Image(info.canvas)
|
||||
path.set({
|
||||
left: left + minX,
|
||||
top: top + minY,
|
||||
scaleX: scaleX,
|
||||
scaleY: scaleY,
|
||||
...this.selectionStyle,
|
||||
});
|
||||
absolutePositioned: true,
|
||||
})
|
||||
|
||||
|
||||
// 创建分组层
|
||||
const group = await this.layerManager.createGroupLayer({
|
||||
clipPath: path,
|
||||
top: path.top + path.height / 2,
|
||||
|
||||
@@ -189,16 +189,9 @@ export class CanvasManager {
|
||||
const objects = this.getObjects().filter((v: any) => v.type !== "group" && !!v.info?.id);
|
||||
for (let i = 0; i < objects.length; i++) {
|
||||
let object = objects[i]
|
||||
if (object.clipPath) object.set({ clipPath: null })
|
||||
let group = this.getObjectById(object.info.parentId)
|
||||
if (!group) continue
|
||||
let path = group.clipPath
|
||||
let path = this.getObjectById(object.info.parentId)?.clipPath
|
||||
if (!path) continue
|
||||
let clipPath = await cloneObjects([path]).then((v) => v[0])
|
||||
clipPath.set({
|
||||
absolutePositioned: true,
|
||||
})
|
||||
object.set({ clipPath })
|
||||
object.set({ clipPath: path })
|
||||
}
|
||||
this.renderAll()
|
||||
}
|
||||
|
||||
@@ -32,7 +32,30 @@ export class LayerManager {
|
||||
}
|
||||
}
|
||||
setActiveFirstLayer() {
|
||||
this.setActiveID(this.layers.value[0]?.info?.id || "")
|
||||
const layer = this.layers.value[0]
|
||||
const id = layer.type === "group" ? layer.children[0]?.info?.id : layer.info?.id
|
||||
this.setActiveID(id || "")
|
||||
}
|
||||
|
||||
// 更新图层列表
|
||||
async updateLayers(isSort = false) {
|
||||
const objects = this.canvasManager.getObjects().map(v => v.toObject()).filter(v => !!v.info?.id).reverse()
|
||||
objects.forEach(v => {
|
||||
if (v.type === "group") {
|
||||
if (!v.children) v.children = []
|
||||
return;
|
||||
}
|
||||
const parentId = v.info?.parentId
|
||||
if (!parentId) return
|
||||
objects.forEach((obj: any) => {
|
||||
if (obj.info?.id !== parentId) return
|
||||
if (!obj.children) obj.children = []
|
||||
obj.children.push(v)
|
||||
})
|
||||
})
|
||||
const layers = objects.filter(v => !v.info?.parentId)
|
||||
this.layers.value = layers
|
||||
if (isSort) await this.sortLayers()
|
||||
}
|
||||
|
||||
getActiveLayer() {
|
||||
@@ -168,26 +191,6 @@ export class LayerManager {
|
||||
}
|
||||
}
|
||||
|
||||
// 更新图层列表
|
||||
async updateLayers(isSort = false) {
|
||||
const objects = this.canvasManager.getObjects().map(v => v.toObject()).filter(v => !!v.info?.id).reverse()
|
||||
objects.forEach(v => {
|
||||
if (v.type === "group") {
|
||||
if (!v.children) v.children = []
|
||||
return;
|
||||
}
|
||||
const parentId = v.info?.parentId
|
||||
if (!parentId) return
|
||||
objects.forEach((obj: any) => {
|
||||
if (obj.info?.id !== parentId) return
|
||||
if (!obj.children) obj.children = []
|
||||
obj.children.push(v)
|
||||
})
|
||||
})
|
||||
const layers = objects.filter(v => !v.info?.parentId)
|
||||
this.layers.value = layers
|
||||
if (isSort) await this.sortLayers()
|
||||
}
|
||||
|
||||
/** 设置图层位置-不设置默认居中 */
|
||||
setLayerPosition(object, options?: any) {
|
||||
@@ -455,7 +458,7 @@ export class LayerManager {
|
||||
const objects = this.canvasManager.getObjects()
|
||||
objects.forEach((item: any) => {
|
||||
item.set({
|
||||
erasable: (item.info.id === this.activeID.value && item.type !== "group")
|
||||
erasable: (item?.info?.id === this.activeID.value && item.type !== "group")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -117,6 +117,7 @@ export class ToolManager {
|
||||
setTool(value: string) {
|
||||
const tool = this.tools.find((t) => t.name === value)
|
||||
if (!tool) return console.warn(`工具${tool}不存在`)
|
||||
this.brushManager?.handleToolChange(tool.name)
|
||||
const oldTool = this.currentTool.value
|
||||
this.currentTool.value = tool.name
|
||||
this.canvasManager.canvas.defaultCursor = tool.cursor
|
||||
@@ -124,7 +125,6 @@ export class ToolManager {
|
||||
this.canvasManager.canvas.isDrawingMode = !!tool.isDrawingMode;// 绘制模式
|
||||
if (!tool.isDrawingMode) this._disableBrushIndicator()// 非绘制模式,禁用笔刷指示器
|
||||
|
||||
|
||||
if (tool.setup) tool.setup()
|
||||
|
||||
this.stateManager?.aiSelectboxToolManager?.handleToolChange?.(oldTool, tool.name)
|
||||
@@ -160,16 +160,13 @@ export class ToolManager {
|
||||
const brushStore = this.brushManager?.brushStore
|
||||
if (brushStore) {
|
||||
// 同步基本属性
|
||||
// this.brushManager.setBrushSize(brushStore.state.size);
|
||||
// this.brushManager.setBrushColor(brushStore.state.color);
|
||||
// this.brushManager.setBrushOpacity(brushStore.state.opacity);
|
||||
this.brushManager.setBrushSize(brushStore.state.size);
|
||||
this.brushManager.setBrushColor(brushStore.state.color);
|
||||
this.brushManager.setBrushOpacity(brushStore.state.opacity);
|
||||
|
||||
// 同步笔刷类型 - 修复方法名,使用正确的setBrushType方法
|
||||
this.brushManager.setBrushType("pencil");
|
||||
}
|
||||
this.brushManager.setBrushSize(5);
|
||||
this.brushManager.setBrushColor("#000");
|
||||
this.brushManager.setBrushOpacity(1);
|
||||
|
||||
// 更新应用到画布
|
||||
this.brushManager.updateBrush();
|
||||
@@ -185,11 +182,12 @@ export class ToolManager {
|
||||
if (!this.canvasManager.canvas) return;
|
||||
|
||||
// 确保有笔刷管理器
|
||||
if (this.brushManager) {
|
||||
const brushStore = this.brushManager?.brushStore
|
||||
if (brushStore) {
|
||||
this.brushManager.createEraser();
|
||||
this.brushManager.setBrushSize(brushStore.state.size);
|
||||
}
|
||||
|
||||
this.brushManager.setBrushSize(5);
|
||||
this.stateManager.layerManager.setActiveObjectErasable()
|
||||
// 启用笔刷指示器
|
||||
this._enableBrushIndicator();
|
||||
@@ -206,10 +204,16 @@ export class ToolManager {
|
||||
console.warn("画笔正在更新中,请稍候...");
|
||||
return;
|
||||
}
|
||||
this.brushManager.setBrushSize(5);
|
||||
this.brushManager.setBrushColor("rgb(255, 0, 0)");
|
||||
this.brushManager.setBrushOpacity(0.5);
|
||||
this.brushManager.setBrushType("pencil");
|
||||
const brushStore = this.brushManager?.brushStore
|
||||
if (brushStore) {
|
||||
// 同步基本属性
|
||||
this.brushManager.setBrushSize(brushStore.state.size);
|
||||
this.brushManager.setBrushColor(brushStore.state.color);
|
||||
this.brushManager.setBrushOpacity(brushStore.state.opacity);
|
||||
|
||||
// 同步笔刷类型 - 修复方法名,使用正确的setBrushType方法
|
||||
this.brushManager.setBrushType("pencil");
|
||||
}
|
||||
// 更新应用到画布
|
||||
this.brushManager.updateBrush();
|
||||
}
|
||||
@@ -222,9 +226,10 @@ export class ToolManager {
|
||||
if (!this.canvasManager.canvas) return;
|
||||
|
||||
// 确保有笔刷管理器
|
||||
if (this.brushManager) {
|
||||
const brushStore = this.brushManager?.brushStore
|
||||
if (brushStore) {
|
||||
this.brushManager.createEraser();
|
||||
this.brushManager.setBrushSize(5);
|
||||
this.brushManager.setBrushSize(brushStore.state.size);
|
||||
}
|
||||
|
||||
this.stateManager.layerManager.setAllObjectsErasable(false)
|
||||
|
||||
@@ -3,13 +3,13 @@ import { reactive, readonly } from "vue";
|
||||
class texturePresetManager { }
|
||||
|
||||
export class BrushState {
|
||||
constructor(options) {
|
||||
constructor(options = {}) {
|
||||
this.state = reactive({
|
||||
// 笔刷基础属性
|
||||
size: 5, // 笔刷大小
|
||||
color: "#000000", // 笔刷颜色
|
||||
opacity: 1, // 笔刷透明度
|
||||
type: "pencil", // 当前笔刷类型
|
||||
size: options.size || 5, // 笔刷大小
|
||||
color: options.color || "#000000", // 笔刷颜色
|
||||
opacity: options.opacity || 1, // 笔刷透明度
|
||||
type: options.type || "pencil", // 当前笔刷类型
|
||||
|
||||
// 阴影相关属性
|
||||
shadowEnabled: false, // 是否启用阴影
|
||||
|
||||
@@ -21,6 +21,8 @@ import { EraserStateManager } from "../EraserStateManager.js";
|
||||
import { SprayBrush } from "./types/SprayBrush";
|
||||
// import { SketchyBrush } from "./types/SketchyBrush";
|
||||
// import { SpraypaintBrush } from "./types/SpraypaintBrush";
|
||||
import { OperationType } from '../../tools/layerHelper'
|
||||
|
||||
|
||||
/**
|
||||
* 笔刷管理器
|
||||
@@ -37,7 +39,17 @@ export class BrushManager {
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
this.canvas = options.canvas;
|
||||
this.brushStore = new BrushState();
|
||||
this.brushStoreList = {
|
||||
[OperationType.DRAW]: new BrushState(),
|
||||
[OperationType.ERASER]: new BrushState(),
|
||||
[OperationType.AISELECT_DRAW]: new BrushState({
|
||||
color: "rgb(255, 0, 0)",
|
||||
opacity: 0.5,
|
||||
}),
|
||||
[OperationType.AISELECT_ERASER]: new BrushState(),
|
||||
}
|
||||
this.brushStore = this.brushStoreList[OperationType.DRAW];
|
||||
|
||||
this.layerManager = options.layerManager; // 添加图层管理器引用
|
||||
this.brushIndicator = options.brushIndicator; // 添加笔刷指示器引用
|
||||
// this.t = options.t
|
||||
@@ -55,7 +67,15 @@ export class BrushManager {
|
||||
this.isErasingActive = false;
|
||||
this.currentErasedObjects = []; // 当前擦除会话中被影响的对象
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换工具时,更新当前活动笔刷
|
||||
* @param {string} toolName 当前工具名称
|
||||
*/
|
||||
handleToolChange(toolName) {
|
||||
const store = this.brushStoreList[toolName];
|
||||
if (!store) return;
|
||||
this.brushStore = store;
|
||||
}
|
||||
/**
|
||||
* 注册默认笔刷
|
||||
* @private
|
||||
|
||||
@@ -11,7 +11,6 @@ export class KeyEventManager {
|
||||
/** 处理键盘事件 */
|
||||
_handleKeyDown: any
|
||||
handleKeyDown(event: any) {
|
||||
event.preventDefault()
|
||||
const activeID = this.stateManager.layerManager.activeID.value
|
||||
const ctrl = event.ctrlKey ? 'ctrl-' : "";
|
||||
const shift = event.shiftKey ? 'shift-' : "";
|
||||
@@ -24,6 +23,7 @@ export class KeyEventManager {
|
||||
{ key: "ctrl-s", handler: () => this.onWorkbench() },
|
||||
{ key: "ctrl-shift-z", handler: () => this.stateManager.redoState() },
|
||||
]
|
||||
if (list.some((v) => reg.test(v.key))) event.preventDefault()
|
||||
list.forEach((v: any) => {
|
||||
if (reg.test(v.key)) v.handler(event)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user