import { fabric } from 'fabric-with-all' import { OperationType } from '../tools/layerHelper' import { getObjectAlphaToCanvas, traceImageContour } from '../tools/canvasMethod' /** 智能框选工具管理器 */ export class AISelectboxToolManager { // 管理器 canvasManager: any stateManager: any layerManager: any toolManager: any isDragging: boolean = false startX: number = 0 startY: number = 0 demoObject: any constructor(options) { this.canvasManager = options.canvasManager this.stateManager = options.stateManager this.layerManager = options.layerManager this.toolManager = options.toolManager } mouseDownEvent(e) { this.isDragging = true this.startX = e.absolutePointer.x this.startY = e.absolutePointer.y const rect = new fabric.Rect({ left: this.startX, top: this.startY, width: 0, height: 0, fill: 'transparent', stroke: '#000', strokeWidth: 1, evented: false, }) this.demoObject = rect this.canvasManager.canvas.add(rect) this.canvasManager.canvas.renderAll() } mouseMoveEvent(e) { if (!this.isDragging) return; var width = e.absolutePointer.x - this.startX var height = e.absolutePointer.y - this.startY var left = this.startX var top = this.startY if (width < 0) { left += width width = -width } if (height < 0) { top += height height = -height } this.demoObject.set({ width, height, left, top }) this.canvasManager.canvas.renderAll() } mouseUpEvent(e) { if (!this.isDragging) return; this.isDragging = false; const object = this.demoObject.toJSON("evented") if (object.width === 0) object.width = 100 if (object.height === 0) object.height = 100 // console.log(object) this.canvasManager.canvas.remove(this.demoObject) this.canvasManager.canvas.renderAll() this.createSelectbox() } loadImageToObject(url) { return new Promise((resolve, reject) => { fabric.Image.fromURL(url, (img) => { resolve(img); }, { crossOrigin: "anonymous" });// 防止污染 }); } rgba = { r: 0, g: 255, b: 0, a: 200 }; selectionStyle = { stroke: "rgba(255, 77, 71, 1)", strokeWidth: 1.5, strokeDashArray: [4, 4], fill: "transparent", strokeUniform: true, // 保持描边宽度不随缩放改变 selectable: false, evented: false, absolutePositioned: true, }; async createSelectbox() { const url = "http://118.31.39.42:3000/falls/1a48ed3a-1faa-4fcd-bf07-765dba1702c5.png" const image = await this.loadImageToObject(url) const canvas = getObjectAlphaToCanvas(image, null, 0, this.rgba); const fobject = this.canvasManager.canvas.clipPath // const top = fobject.top - fobject.height * scaleY / 2; // const left = fobject.left - fobject.width * scaleX / 2; const scaleY = fobject.scaleY const scaleX = fobject.scaleX const top = fobject.top const left = fobject.left const arr = traceImageContour(canvas); 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`); path.set({ left: left + minX, top: top + minY, scaleX: scaleX, scaleY: scaleY, ...this.selectionStyle, }); const group = await this.layerManager.createGroupLayer({ clipPath: path, }, false, false) const rect = await this.layerManager.createRectLayer({ width: path.width, height: path.height, left: left + minX, top: top + minY, fill: "rgba(255, 186, 186, 0.5)", info: { parentId: group.info.id }, }, false, true) await this.canvasManager.updateSubLayerClipPath() await this.layerManager.updateLayerThumbnailsById(rect.info.id, "", false) await this.layerManager.updateLayerThumbnailsById(group.info.id, rect.thumbnail) this.stateManager.recordState() this.toolManager.setTool(OperationType.SELECT) } dispose() { } }