diff --git a/public/ico/scale.png b/public/ico/scale.png new file mode 100644 index 00000000..b4228a2d Binary files /dev/null and b/public/ico/scale.png differ diff --git a/src/data/enums/CustomCursorStyle.ts b/src/data/enums/CustomCursorStyle.ts index 4cc591fa..a5dd484a 100644 --- a/src/data/enums/CustomCursorStyle.ts +++ b/src/data/enums/CustomCursorStyle.ts @@ -6,5 +6,6 @@ export enum CustomCursorStyle { CANCEL = "CANCEL", CLOSE = "CLOSE", GRAB = "GRAB", - GRABBING = "GRABBING" + GRABBING = "GRABBING", + DRAG = "DRAG" } \ No newline at end of file diff --git a/src/logic/actions/LabelActions.ts b/src/logic/actions/LabelActions.ts index 4dfd69fa..646b7608 100644 --- a/src/logic/actions/LabelActions.ts +++ b/src/logic/actions/LabelActions.ts @@ -23,6 +23,9 @@ export class LabelActions { case LabelType.POLYGON: LabelActions.deletePolygonLabelById(imageId, labelId); break; + case LabelType.LINE: + LabelActions.deleteLineLabelById(imageId, labelId); + break; } } diff --git a/src/logic/render/RectRenderEngine.ts b/src/logic/render/RectRenderEngine.ts index b02f22ab..a6529cd7 100644 --- a/src/logic/render/RectRenderEngine.ts +++ b/src/logic/render/RectRenderEngine.ts @@ -34,6 +34,8 @@ export class RectRenderEngine extends BaseRenderEngine { private startCreateRectPoint: IPoint; private startResizeRectAnchor: RectAnchor; + private startDragRectPoint: IPoint; + private DraggingRect: IRect; public constructor(canvas: HTMLCanvasElement) { super(canvas); @@ -58,8 +60,7 @@ export class RectRenderEngine extends BaseRenderEngine { } else { if (!!LabelsSelector.getHighlightedLabelId()) store.dispatch(updateActiveLabelId(LabelsSelector.getHighlightedLabelId())); - else - this.startRectCreation(data.mousePositionOnViewPortContent); + this.startDragRect(data.mousePositionOnViewPortContent, RectUtil.translate(rect, data.viewPortContentImageRect)) } } else if (isMouseOverImage) { @@ -105,6 +106,31 @@ export class RectRenderEngine extends BaseRenderEngine { }); store.dispatch(updateImageDataById(imageData.id, imageData)); } + + if (!!this.startDragRectPoint && !!this.DraggingRect && !!activeLabelRect) { + const rect: IRect = this.calculateRectRelativeToActiveImage(activeLabelRect.rect, data); + const startPosition: IPoint = { + x: this.startDragRectPoint.x, + y: this.startDragRectPoint.y + }; + const delta: IPoint = PointUtil.subtract(mousePositionSnapped, startPosition); + const removeRect: IRect = RectUtil.moveRect(rect, delta); + const scale: number = RenderEngineUtil.calculateImageScale(data); + const scaledRect: IRect = RectUtil.scaleRect(removeRect, scale); + const imageData = LabelsSelector.getActiveImageData(); + imageData.labelRects = imageData.labelRects.map((labelRect: LabelRect) => { + if (labelRect.id === activeLabelRect.id) { + return { + ...labelRect, + rect: scaledRect + }; + } + return labelRect; + }); + store.dispatch(updateImageDataById(imageData.id, imageData)); + } + + } this.endRectTransformation() }; @@ -157,6 +183,17 @@ export class RectRenderEngine extends BaseRenderEngine { }; const activeRectBetweenPixels = RenderEngineUtil.setRectBetweenPixels(activeRect); DrawUtil.drawRect(this.canvas, activeRectBetweenPixels, this.config.lineActiveColor, this.config.lineThickness); + } + if (!!this.startDragRectPoint && !!this.DraggingRect) { + const mousePositionSnapped: IPoint = RectUtil.snapPointToRect(mousePosition, imageRect); + const activeRect: IRect = { + x: this.DraggingRect.x + (mousePositionSnapped.x - this.startDragRectPoint.x), + y: this.DraggingRect.y + (mousePositionSnapped.y - this.startDragRectPoint.y), + width: this.DraggingRect.width, + height: this.DraggingRect.height + }; + const activeRectBetweenPixels = RenderEngineUtil.setRectBetweenPixels(activeRect); + DrawUtil.drawRect(this.canvas, activeRectBetweenPixels, this.config.lineActiveColor, this.config.lineThickness); } } @@ -197,10 +234,15 @@ export class RectRenderEngine extends BaseRenderEngine { if (!!this.canvas && !!data.mousePositionOnViewPortContent && !GeneralSelector.getImageDragModeStatus()) { const rectUnderMouse: LabelRect = this.getRectUnderMouse(data); const rectAnchorUnderMouse: RectAnchor = this.getAnchorUnderMouse(data); - if ((!!rectAnchorUnderMouse && rectUnderMouse && rectUnderMouse.status === LabelStatus.ACCEPTED) || !!this.startResizeRectAnchor) { - store.dispatch(updateCustomCursorStyle(CustomCursorStyle.MOVE)); + if(rectUnderMouse){ + if ((!!rectAnchorUnderMouse && rectUnderMouse.status === LabelStatus.ACCEPTED) || !!this.startResizeRectAnchor) { + store.dispatch(updateCustomCursorStyle(CustomCursorStyle.MOVE)); + }else if(rectUnderMouse.status === LabelStatus.ACCEPTED || !!this.startDragRectPoint) { + store.dispatch(updateCustomCursorStyle(CustomCursorStyle.DRAG)); + } return; } + else if (RenderEngineUtil.isMouseOverCanvas(data)) { if (!RenderEngineUtil.isMouseOverImage(data) && !!this.startCreateRectPoint) store.dispatch(updateCustomCursorStyle(CustomCursorStyle.MOVE)); @@ -303,9 +345,17 @@ export class RectRenderEngine extends BaseRenderEngine { EditorActions.setViewPortActionsDisabledStatus(true); } + private startDragRect(mousePosition: IPoint, rect: IRect) { + this.startDragRectPoint = mousePosition; + this.DraggingRect = rect + EditorActions.setViewPortActionsDisabledStatus(true); + } + private endRectTransformation() { this.startCreateRectPoint = null; this.startResizeRectAnchor = null; + this.startDragRectPoint = null; + this.DraggingRect = null; EditorActions.setViewPortActionsDisabledStatus(false); } } \ No newline at end of file diff --git a/src/utils/EditorUtil.ts b/src/utils/EditorUtil.ts index d03dc41d..cb92acea 100644 --- a/src/utils/EditorUtil.ts +++ b/src/utils/EditorUtil.ts @@ -12,6 +12,8 @@ export class EditorUtil { return "ico/close.png"; case CustomCursorStyle.MOVE: return "ico/move.png"; + case CustomCursorStyle.DRAG: + return "ico/move.png"; case CustomCursorStyle.CANCEL: return "ico/cancel.png"; case CustomCursorStyle.GRAB: @@ -32,7 +34,8 @@ export class EditorUtil { "close": cursorStyle === CustomCursorStyle.CLOSE, "cancel": cursorStyle === CustomCursorStyle.CANCEL, "grab": cursorStyle === CustomCursorStyle.GRAB, - "grabbing": cursorStyle === CustomCursorStyle.GRABBING + "grabbing": cursorStyle === CustomCursorStyle.GRABBING, + "drag": cursorStyle === CustomCursorStyle.DRAG } ); }; diff --git a/src/utils/RectUtil.ts b/src/utils/RectUtil.ts index af034209..c51cf88a 100644 --- a/src/utils/RectUtil.ts +++ b/src/utils/RectUtil.ts @@ -114,6 +114,15 @@ export class RectUtil { return rect; } + public static moveRect(inputRect: IRect, delta): IRect { + const rect: IRect = { ...inputRect }; + return { + ...rect, + x: rect.x + delta.x, + y: rect.y + delta.y + } + } + public static translate(rect: IRect, delta: IPoint): IRect { return { ...rect, diff --git a/src/views/EditorView/Editor/Editor.scss b/src/views/EditorView/Editor/Editor.scss index a0c97f76..1e539aa4 100644 --- a/src/views/EditorView/Editor/Editor.scss +++ b/src/views/EditorView/Editor/Editor.scss @@ -77,7 +77,7 @@ border: 2px solid transparent; } - &.move, &.add, &.resize, &.close, &.cancel, &.grab, &.grabbing { + &.drag, &.move, &.add, &.resize, &.close, &.cancel, &.grab, &.grabbing { > img { display: block; }