Merge branch 'main' of ssh://18.167.251.121:10002/aidlab/FiDA_Front

This commit is contained in:
X1627315083@163.com
2026-03-24 13:58:38 +08:00
15 changed files with 95 additions and 22 deletions

View File

@@ -1,23 +1,25 @@
<template>
<transition name="fade">
<div v-if="show" class="ai-selectbox-panel">
<div>
<span class="icon"><svg-icon name="dc-add" size="16" /></span>
<span class="label">Add</span>
</div>
<div>
<span class="icon"><svg-icon name="dc-remove" size="16" /></span>
<span class="label">Remove</span>
<div
v-for="item in list"
:key="item.type"
:class="{ active: item.name === props.currentTool }"
>
<span class="icon"><svg-icon :name="item.name" size="16" /></span>
<span class="label">{{ item.label }}</span>
</div>
<button>创建</button>
</div>
</transition>
<brush-control-panel :currentTool="show ? 'draw' : ''" style="top: 14rem" />
</template>
<script setup lang="ts">
import { ref, inject, computed, watch } from 'vue'
import depthSlider from './tools/depth-slider.vue'
import { OperationType } from '../tools/layerHelper'
import { OperationType, AI_SELECTBOX_TYPE } from '../tools/layerHelper'
const props = defineProps({
currentTool: { required: true, type: [String, null] }
})
@@ -25,6 +27,28 @@
const toolManager = inject('toolManager') as any
const showTools = [OperationType.SELECTBOX]
const show = computed(() => showTools.includes(props.currentTool))
const list = ref([
{
type: AI_SELECTBOX_TYPE.ADD,
name: 'dc-add_sb',
label: 'Add'
},
{
type: AI_SELECTBOX_TYPE.REMOVE,
name: 'dc-remove_sb',
label: 'Remove'
},
{
type: AI_SELECTBOX_TYPE.DRAW,
name: 'dc-brush_sb',
label: 'Brush'
},
{
type: AI_SELECTBOX_TYPE.ERASER,
name: 'dc-erase_sb',
label: 'Erase'
}
])
</script>
<style lang="less" scoped>
// 淡入淡出动画

View File

@@ -46,6 +46,10 @@
watch(brushState, (value) => {
if (value) updateBrushState()
})
watch(
() => props.currentTool,
(value) => updateBrushState()
)
const brushSize = ref(40)
const brushOpacity = ref(100)
const brushColor = ref('#000000')

View File

@@ -1,5 +1,5 @@
import { fabric } from 'fabric-with-all'
import { OperationType } from '../tools/layerHelper'
import { OperationType, AI_SELECTBOX_TYPE } from '../tools/layerHelper'
import { getObjectAlphaToCanvas, traceImageContour } from '../tools/canvasMethod'
/** 智能框选工具管理器 */
@@ -20,6 +20,15 @@ export class AISelectboxToolManager {
this.layerManager = options.layerManager
this.toolManager = options.toolManager
}
/** 处理切换工具 */
handleToolChange(oldTool: string, newTool: string) {
if (newTool === OperationType.SELECTBOX) {
// 切换到智能框选工具
} else {
// 切换到普通框选工具
}
}
mouseDownEvent(e) {
this.isDragging = true
this.startX = e.absolutePointer.x
@@ -65,7 +74,7 @@ export class AISelectboxToolManager {
this.canvasManager.canvas.remove(this.demoObject)
this.canvasManager.canvas.renderAll()
this.createSelectbox()
// this.createSelectbox()
}

View File

@@ -142,9 +142,9 @@ export class CanvasManager {
this.resetZoom(false, true)// 画布居中
this.stateManager.toolManager.setTool(OperationType.SELECT)
this.layerManager.updateLayers()
this.stateManager.recordState()
// this.stateManager.toolManager.setTool(OperationType.RECTANGLE)
}
/** 画布添加对象 */
async add(obj: any, isRecord = true) {
@@ -293,7 +293,7 @@ export class CanvasManager {
async handleDrawImage(fabricImage: fabric.Object) {
const activeID = this.stateManager.layerManager.activeID.value
const activeLayer = this.getObjectById(activeID)
if (activeLayer) {
if (activeLayer && activeLayer.fill?.repeat !== "repeat") {
this.layerManager.imageMergeToLayer(activeLayer, fabricImage)
} else {
const emptyLayer = await this.layerManager.createEmptyLayer(false);

View File

@@ -2,7 +2,7 @@ import { ref } from 'vue'
import { fabric } from 'fabric-with-all'
import { createId } from '../../tools/tools'
import { exportObjectsToImage, exportObjectToThumbnail } from '../tools/exportMethod'
import { OperationType } from '../tools/layerHelper'
import { OperationType, BlendMode } from '../tools/layerHelper'
import { getArrowPath, cloneObjects, getStarArr } from '../tools/canvasMethod'
export class LayerManager {
@@ -18,7 +18,12 @@ export class LayerManager {
}
onMounted() { }
setActiveID(id: string, isActive = true) {
this.activeID.value = id
const layer = this.getLayerById(id)
if (layer?.type === "group") {
this.activeID.value = ""
} else {
this.activeID.value = id
}
if (isActive) {
this.canvasManager.setActiveObjectById(id)
this.stateManager.toolManager.setTool(OperationType.SELECT)
@@ -399,9 +404,15 @@ export class LayerManager {
})
const index = this.canvasManager.getObjects().indexOf(targetLayer);
this.deleteLayerById(targetLayer.info.id, false)
this.setActiveID(mergedImage.info.id, false)
const nid = mergedImage.info.id
await this.canvasManager.add(mergedImage, false);
this.setActiveID(nid, false)
this.canvasManager.canvas.moveTo(mergedImage, index);
// this.stateManager.objectManager.setBlendMode(nid, BlendMode.MULTIPLY)
// this.stateManager.objectManager.setFillRepeat(nid, false)
this.canvasManager.renderAll()
this.updateLayers()
this.stateManager.recordState()

View File

@@ -87,7 +87,7 @@ export class ObjectManager {
}
/** 设置平铺状态 */
setFillRepeat(id: string) {
setFillRepeat(id: string, isRecord = true) {
const object = this.canvasManager.getObjectById(id)
if (!object) return console.warn('设置平铺状态失败对象不存在ID:', id)
if (object.type !== 'image') return console.warn('设置平铺状态失败,对象不是图片类型:', id)
@@ -133,7 +133,7 @@ export class ObjectManager {
});
rect.set("fill", pattern)
this.canvasManager.canvas.remove(object)
this.canvasManager.add(rect)
this.canvasManager.add(rect, isRecord)
}
/** 获取填充对象 */
getFillRepeatObject(id: string) {

View File

@@ -38,6 +38,7 @@ export class StateManager {
brushManager: any
keyEventManager: any
objectManager: any
aiSelectboxToolManager: any
// 设置管理器
setManager(options) {
options.eventManager && (this.eventManager = options.eventManager)
@@ -47,6 +48,7 @@ export class StateManager {
options.brushManager && (this.brushManager = options.brushManager)
options.keyEventManager && (this.keyEventManager = options.keyEventManager)
options.objectManager && (this.objectManager = options.objectManager)
options.aiSelectboxToolManager && (this.aiSelectboxToolManager = options.aiSelectboxToolManager)
}
constructor(options) {
this.mxHistory = ref(50)

View File

@@ -101,6 +101,7 @@ export class ToolManager {
setTool(value: string) {
const tool = this.tools.find((t) => t.name === value)
if (!tool) return console.warn(`工具${tool}不存在`)
const oldTool = this.currentTool.value
this.currentTool.value = tool.name
this.canvasManager.canvas.defaultCursor = tool.cursor
this.setCanvasEvented(!!tool.selection)
@@ -110,6 +111,7 @@ export class ToolManager {
if (tool.setup) tool.setup()
this.stateManager?.aiSelectboxToolManager?.handleToolChange?.(oldTool, tool.name)
setTimeout(() => {
this.canvasManager.renderAll()
});
@@ -142,13 +144,16 @@ 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();
@@ -168,6 +173,7 @@ export class ToolManager {
this.brushManager.createEraser();
}
this.brushManager.setBrushSize(5);
this.stateManager.layerManager.setActiveObjectErasable()
// 启用笔刷指示器
this._enableBrushIndicator();

View File

@@ -34,6 +34,7 @@ export class CanvasEventManager {
}
this.shapeToolManager = new ShapeToolManager(managers)
this.aiSelectboxToolManager = new AISelectboxToolManager(managers)
this.stateManager.setManager({ aiSelectboxToolManager: this.aiSelectboxToolManager })
// 初始化所有事件
this.initEvents();

View File

@@ -68,3 +68,11 @@ export const BlendMode = {
DESTINATION_IN: "destination-in", // 目标内
DESTINATION_OUT: "destination-out", // 目标外
};
/** 智能框选工具类型枚举 */
export const AI_SELECTBOX_TYPE = {
ADD: "add", // 添加模式
REMOVE: "remove", // 删除模式
DRAW: "draw", // 绘画模式
ERASER: "eraser", // 橡皮擦模式
}