diff --git a/packages/lb-annotation/src/core/toolOperation/LineToolOperation.ts b/packages/lb-annotation/src/core/toolOperation/LineToolOperation.ts index 34baf5b14..590442efc 100644 --- a/packages/lb-annotation/src/core/toolOperation/LineToolOperation.ts +++ b/packages/lb-annotation/src/core/toolOperation/LineToolOperation.ts @@ -1895,7 +1895,7 @@ class LineToolOperation extends BasicToolOperation { } public renderTextAttribute() { - if (!this.ctx || !this.selectedLine) { + if (!this.ctx || !this.selectedLine || (this.activeLine && this.activeLine?.length < 2)) { return; } diff --git a/packages/lb-annotation/src/core/toolOperation/Selection.ts b/packages/lb-annotation/src/core/toolOperation/Selection.ts index 66db50602..281c66795 100644 --- a/packages/lb-annotation/src/core/toolOperation/Selection.ts +++ b/packages/lb-annotation/src/core/toolOperation/Selection.ts @@ -118,6 +118,9 @@ class Selection { this.toolInstance.render(); } + /** + * Stash data list and pop while paste + */ public toStashDataList() { if (this.selectedIDs.length > 0) { this.stashDataList = _.cloneDeep(this.dataList.filter((i) => this.selectedIDs.includes(i.id))); diff --git a/packages/lb-annotation/src/core/toolOperation/polygonOperation.ts b/packages/lb-annotation/src/core/toolOperation/polygonOperation.ts index 41d1b1e5e..e38db6923 100644 --- a/packages/lb-annotation/src/core/toolOperation/polygonOperation.ts +++ b/packages/lb-annotation/src/core/toolOperation/polygonOperation.ts @@ -1180,90 +1180,39 @@ class PolygonOperation extends BasicToolOperation { return false; } - public moveSelectedPolygons(offset: ICoordinate) { - const newPolygonList = _.cloneDeep(this.polygonList); - const selectedPolygons = _.cloneDeep(this.dragInfo?.selectedPolygons); - - if (selectedPolygons && selectedPolygons?.length > 0) { - newPolygonList.forEach((v) => { - const selectedPolygon = selectedPolygons?.find((s) => v.id === s.id); - - if (selectedPolygon) { - v.pointList = v.pointList.map((p, index) => ({ - ...p, - x: selectedPolygon?.pointList[index].x + offset.x, - y: selectedPolygon?.pointList[index].y + offset.y, - })); - } - - return v; - }); - - this.setPolygonList(newPolygonList); - this.render(); - } - } - /** * Update polygon position while enableDrag is true * @param e {MouseEvent} */ public onDragMove(e: MouseEvent) { - const coordinate = this.getCoordinateUnderZoom(e); - - const { dragTarget, dragPrevCoord, changePointIndex, initPointList, dragStartCoord } = this.dragInfo!; - - this.dragStatus = EDragStatus.Move; + const newPolygonList = this.polygonList.map((v) => { + if (this.selectedIDs.includes(v.id)) { + const selectedPointList = this.dragPolygon(e, v); - if (dragTarget === EDragTarget.Plane) { - const offset = { - x: (coordinate.x - dragStartCoord.x) / this.zoom, - y: (coordinate.y - dragStartCoord.y) / this.zoom, - }; - this.moveSelectedPolygons(offset); - return; - } + if (!selectedPointList) { + return v; + } - const { selectedPolygon } = this; + const newData = { + ...v, + pointList: selectedPointList as IPolygonPoint[], + }; - if (!selectedPolygon) { - return; - } + // 非矩形模式下拖动,矩形模式下生成的框将会转换为非矩形框 + if (v.isRect === true && this.pattern === EPolygonPattern.Normal) { + Object.assign(newData, { isRect: false }); + } - /** - * 矩形拖动 - * 1. 模式匹配 - * 2. 当前选中多边形是否为矩形 - * 3. 是否带有拖动 - * */ - if ( - this.pattern === EPolygonPattern.Rect && - selectedPolygon?.isRect === true && - changePointIndex && - [EDragTarget.Line].includes(dragTarget) - ) { - const firstPointIndex = MathUtils.getArrayIndex(changePointIndex[0] - 2, 4); - const secondPointIndex = MathUtils.getArrayIndex(changePointIndex[0] - 1, 4); - const basicLine: [ICoordinate, ICoordinate] = [initPointList[firstPointIndex], initPointList[secondPointIndex]]; + return newData; + } - const perpendicularOffset = MathUtils.getRectPerpendicularOffset(dragStartCoord, coordinate, basicLine); - return { - x: perpendicularOffset.x / this.zoom, - y: perpendicularOffset.y / this.zoom, - }; - } + return v; + }); - if (this.dragInfo?.dragTarget === EDragTarget.Plane) { - return { - x: (coordinate.x - dragPrevCoord.x) / this.zoom, - y: (coordinate.y - dragPrevCoord.y) / this.zoom, - }; - } + this.dragInfo!.dragPrevCoord = this.getCoordinateUnderZoom(e); - return { - x: (coordinate.x - dragStartCoord.x) / this.zoom, - y: (coordinate.y - dragStartCoord.y) / this.zoom, - }; + this.setPolygonList(newPolygonList); + this.render(); } /** diff --git a/packages/lb-annotation/src/core/toolOperation/rectOperation.ts b/packages/lb-annotation/src/core/toolOperation/rectOperation.ts index d49b42267..43e64cb8b 100644 --- a/packages/lb-annotation/src/core/toolOperation/rectOperation.ts +++ b/packages/lb-annotation/src/core/toolOperation/rectOperation.ts @@ -452,18 +452,87 @@ class RectOperation extends BasicToolOperation { return undefined; } + public appendOffsetRect(rect: IRect, offset: ICoordinate) { + return { + ...rect, + x: rect.x + offset.x / this.zoom, + y: rect.y + offset.y / this.zoom, + }; + } + + public getRectsBoundaries(rects: IRect[], offset: ICoordinate) { + const rectsPoint: ICoordinate[] = rects.reduce((pre: ICoordinate[], next) => { + return pre.concat(...RectUtils.getRectPointList(this.appendOffsetRect(next, offset))); + }, []); + + return MathUtils.calcViewportBoundaries(rectsPoint); + } + + /** + * 判断框是否超过依赖范围 + * @param rects + * @param offset + * @returns + */ + public isRectsOutOfTarget(rects: IRect[], offset: ICoordinate) { + if (this.config.drawOutsideTarget !== false) { + return false; + } + + const rectsBoundaries = this.getRectsBoundaries(rects, offset); + + const selectedRectRange = { + y: rectsBoundaries.top, + x: rectsBoundaries.left, + height: rectsBoundaries.bottom - rectsBoundaries.top, + width: rectsBoundaries.right - rectsBoundaries.left, + }; + + // 多边形判断 + if (this.basicResult?.pointList?.length > 0) { + return RectUtils.isRectNotInPolygon( + selectedRectRange as IRect, + getPolygonPointUnderZoom(this.basicResult.pointList, this.zoom), + ); + } + + // 原图、拉框范围判断 + if (this.basicResult || this.imgInfo) { + const basicRect = this.basicResult + ? this.basicResult + : { x: 0, y: 0, height: this.imgNode?.height, width: this.imgNode?.width }; + + if (basicRect) { + return [ + { x: rectsBoundaries.left, y: rectsBoundaries.top }, + { x: rectsBoundaries.right, y: rectsBoundaries.bottom }, + ].some((i) => { + return !RectUtils.isInRect(i, basicRect); + }); + } + } + + return false; + } + + /** + * Update rect position while dragTarget is equal EDragTarget.Plane + * @param offset + */ public moveRects(offset: ICoordinate) { if (this.dragInfo?.originRectList) { let selectedRects = _.cloneDeep(this.dragInfo.originRectList); - if (this.dragInfo.dragTarget === EDragTarget.Plane) { - selectedRects = this.dragInfo.originRectList!.map((i) => ({ - ...i, - x: i.x + offset.x / this.zoom, - y: i.y + offset.y / this.zoom, - })); + if (this.isRectsOutOfTarget(selectedRects, offset)) { + return; } + selectedRects = this.dragInfo.originRectList!.map((i) => ({ + ...i, + x: i.x + offset.x / this.zoom, + y: i.y + offset.y / this.zoom, + })); + this.setRectList( this.rectList.map((v) => { const updatedRect = selectedRects.find((i) => i.id === v.id); @@ -656,16 +725,14 @@ class RectOperation extends BasicToolOperation { const basicWidth = this.basicResult.width * this.zoom; const basicHeight = this.basicResult.height * this.zoom; - // if ( - // this.dragInfo.dragTarget !== EDragTarget.Plane && - // (selectedRect.x < basicX - 0.01 || - // selectedRect.y < basicY - 0.01 || - // selectedRect.width > basicX + basicWidth - selectedRect.x + 0.01 || - // selectedRect.height > basicY + basicHeight - selectedRect.y + 0.01) - // ) { - // return; - // } - + if ( + selectedRect.x < basicX - 0.01 || + selectedRect.y < basicY - 0.01 || + selectedRect.width > basicX + basicWidth - selectedRect.x + 0.01 || + selectedRect.height > basicY + basicHeight - selectedRect.y + 0.01 + ) { + return; + } if (selectedRect.x < basicX) { selectedRect.x = basicX; }