diff --git a/apps/frontend/src/pages/tasks.[id].edit/partials/InputData/imagePreAnnotationJson.schema.json b/apps/frontend/src/pages/tasks.[id].edit/partials/InputData/imagePreAnnotationJson.schema.json index 295afef8e..fcf48c9f6 100644 --- a/apps/frontend/src/pages/tasks.[id].edit/partials/InputData/imagePreAnnotationJson.schema.json +++ b/apps/frontend/src/pages/tasks.[id].edit/partials/InputData/imagePreAnnotationJson.schema.json @@ -47,6 +47,9 @@ { "$ref": "#/definitions/PolygonTool" }, + { + "$ref": "#/definitions/RelationTool" + }, { "$ref": "#/definitions/CuboidTool" }, @@ -323,6 +326,55 @@ }, "required": ["toolName", "result"] }, + "RelationTool": { + "type": "object", + "properties": { + "toolName": { + "type": "string", + "const": "relationTool" + }, + "result": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "唯一标识" + }, + "sourceId": { + "type": "string", + "description": "起始标注id" + }, + "targetId": { + "type": "string", + "description": "目标标注id" + }, + "visible": { + "type": "boolean", + "description": "是否可见", + "default": true + }, + "attributes": { + "$ref": "#/definitions/Attribute" + }, + "order": { + "type": "integer", + "description": "标注顺序", + "minimum": 0 + }, + "label": { + "type": "string", + "description": "标注标签", + "default": "none" + } + }, + "required": ["sourceId", "targetId", "id", "order", "label"] + } + } + }, + "required": ["toolName", "result"] + }, "RectTool": { "type": "object", "properties": { diff --git a/apps/frontend/src/pages/tasks.[id].edit/partials/InputData/imagePreAnnotationJsonl.schema.json b/apps/frontend/src/pages/tasks.[id].edit/partials/InputData/imagePreAnnotationJsonl.schema.json index 774d2ed24..49b39b914 100644 --- a/apps/frontend/src/pages/tasks.[id].edit/partials/InputData/imagePreAnnotationJsonl.schema.json +++ b/apps/frontend/src/pages/tasks.[id].edit/partials/InputData/imagePreAnnotationJsonl.schema.json @@ -33,6 +33,12 @@ "$ref": "#/definitions/LabelItem" } }, + "relationTool": { + "type": "array", + "items": { + "$ref": "#/definitions/LabelItem" + } + }, "cuboidTool": { "type": "array", "items": { @@ -161,6 +167,24 @@ }, "required": ["toolName", "result"] }, + "relationTool": { + "type": "object", + "properties": { + "toolName": { + "type": "string", + "const": "relationTool", + "default": "relationTool" + }, + "result": { + "description": "标注结果", + "type": "array", + "items": { + "$ref": "#/definitions/RelationTool" + } + } + }, + "required": ["toolName", "result"] + }, "textTool": { "type": "object", "properties": { @@ -608,6 +632,55 @@ }, "required": ["direction", "front", "back", "x", "y", "width", "height", "id", "order", "label"] }, + "RelationTool": { + "type": "object", + "properties": { + "toolName": { + "type": "string", + "const": "relationTool" + }, + "result": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "唯一标识" + }, + "sourceId": { + "type": "string", + "description": "起始标注id" + }, + "targetId": { + "type": "string", + "description": "目标标注id" + }, + "visible": { + "type": "boolean", + "description": "是否可见", + "default": true + }, + "attributes": { + "$ref": "#/definitions/Attribute" + }, + "order": { + "type": "integer", + "description": "标注顺序", + "minimum": 0 + }, + "label": { + "type": "string", + "description": "标注标签", + "default": "none" + } + }, + "required": ["sourceId", "targetId", "id", "order", "label"] + } + } + }, + "required": ["toolName", "result"] + }, "TextTool": { "type": "array", "items": { diff --git a/apps/frontend/src/pages/tasks.[id].samples.[id]/index.tsx b/apps/frontend/src/pages/tasks.[id].samples.[id]/index.tsx index afb9c685f..ccc00aef3 100644 --- a/apps/frontend/src/pages/tasks.[id].samples.[id]/index.tsx +++ b/apps/frontend/src/pages/tasks.[id].samples.[id]/index.tsx @@ -38,6 +38,9 @@ export const imageAnnotationRef = createRef(); export const videoAnnotationRef = createRef(); export const audioAnnotationRef = createRef(); +const PREVIEW_OFFSET_TOP = 102; +const OFFSET_TOP = 158; + const AnnotationPage = () => { const routeParams = useParams(); const { task } = useRouteLoaderData('task') as TaskLoaderResult; @@ -308,7 +311,7 @@ const AnnotationPage = () => { ref={imageAnnotationRef} onError={onError} // windows platform pixel issue - offsetTop={configFromParent ? 100 : 158} + offsetTop={configFromParent ? PREVIEW_OFFSET_TOP : OFFSET_TOP} editingSample={editingSample} config={config} disabled={disabled} @@ -326,7 +329,7 @@ const AnnotationPage = () => { { - + + + + diff --git a/packages/image/src/annotations/Annotation.ts b/packages/image/src/annotations/Annotation.ts index 4b1d65da1..73e23cbd1 100644 --- a/packages/image/src/annotations/Annotation.ts +++ b/packages/image/src/annotations/Annotation.ts @@ -94,7 +94,13 @@ export class Annotation { return { x, y, rotate: finalRotate }; } - static createTextDomPortal(content: string, isAboveLine: boolean, order: number, bindShape: Line): DomPortal { + static createTextDomPortal( + content: string, + isAboveLine: boolean, + order: number, + bindShape: Line, + style?: Record, + ): DomPortal { return new DomPortal({ content, getPosition: (shape, container) => @@ -102,6 +108,7 @@ export class Annotation { order, preventPointerEvents: true, bindShape, + style, }); } diff --git a/packages/image/src/annotations/Cuboid.annotation.ts b/packages/image/src/annotations/Cuboid.annotation.ts index 75d57dfd7..60de119fc 100644 --- a/packages/image/src/annotations/Cuboid.annotation.ts +++ b/packages/image/src/annotations/Cuboid.annotation.ts @@ -241,6 +241,9 @@ export class AnnotationCuboid extends Annotation { order: data.order, preventPointerEvents: true, bindShape: backShape, + style: { + display: visible ? 'block' : 'none', + }, }), ); @@ -255,6 +258,9 @@ export class AnnotationCuboid extends Annotation { order: data.order, preventPointerEvents: true, bindShape: frontShape, + style: { + display: visible ? 'block' : 'none', + }, }), ); } diff --git a/packages/image/src/annotations/Line.annotation.ts b/packages/image/src/annotations/Line.annotation.ts index 1ca366ecf..ad36e4102 100644 --- a/packages/image/src/annotations/Line.annotation.ts +++ b/packages/image/src/annotations/Line.annotation.ts @@ -143,6 +143,9 @@ export class AnnotationLine extends Annotation { order: data.order, preventPointerEvents: true, bindShape: group.shapes[0] as Line, + style: { + display: visible ? 'block' : 'none', + }, }), ); @@ -157,6 +160,9 @@ export class AnnotationLine extends Annotation { order: data.order, preventPointerEvents: true, bindShape: group.shapes[0], + style: { + display: visible ? 'block' : 'none', + }, }), ); } diff --git a/packages/image/src/annotations/Point.annotation.ts b/packages/image/src/annotations/Point.annotation.ts index 03212a732..e06aa85be 100644 --- a/packages/image/src/annotations/Point.annotation.ts +++ b/packages/image/src/annotations/Point.annotation.ts @@ -76,6 +76,9 @@ export class AnnotationPoint extends Annotation { order: data.order, preventPointerEvents: true, bindShape: group.shapes[0], + style: { + display: visible ? 'block' : 'none', + }, }), ); @@ -90,6 +93,9 @@ export class AnnotationPoint extends Annotation { order: data.order, preventPointerEvents: true, bindShape: group.shapes[0], + style: { + display: visible ? 'block' : 'none', + }, }), ); } diff --git a/packages/image/src/annotations/Polygon.annotation.ts b/packages/image/src/annotations/Polygon.annotation.ts index f202e9edd..4f998a774 100644 --- a/packages/image/src/annotations/Polygon.annotation.ts +++ b/packages/image/src/annotations/Polygon.annotation.ts @@ -126,6 +126,9 @@ export class AnnotationPolygon extends Annotation { order: data.order, preventPointerEvents: true, bindShape: group.shapes[0], + style: { + display: visible ? 'block' : 'none', + }, }), ); @@ -151,6 +154,9 @@ export class AnnotationPolygon extends Annotation { order: data.order, preventPointerEvents: true, bindShape: group.shapes[0], + style: { + display: visible ? 'block' : 'none', + }, }), ); } diff --git a/packages/image/src/annotations/Rect.annotation.ts b/packages/image/src/annotations/Rect.annotation.ts index 4d7c7a1bb..edbbc17e2 100644 --- a/packages/image/src/annotations/Rect.annotation.ts +++ b/packages/image/src/annotations/Rect.annotation.ts @@ -81,6 +81,9 @@ export class AnnotationRect extends Annotation { order: data.order, preventPointerEvents: true, bindShape: group.shapes[0] as Rect, + style: { + display: visible ? 'block' : 'none', + }, }), ); @@ -95,6 +98,9 @@ export class AnnotationRect extends Annotation { order: data.order, preventPointerEvents: true, bindShape: group.shapes[0] as Rect, + style: { + display: visible ? 'block' : 'none', + }, }), ); } diff --git a/packages/image/src/annotations/Relation.annotation.ts b/packages/image/src/annotations/Relation.annotation.ts index 5a7acec58..bbca8bcb7 100644 --- a/packages/image/src/annotations/Relation.annotation.ts +++ b/packages/image/src/annotations/Relation.annotation.ts @@ -164,6 +164,9 @@ export class AnnotationRelation extends Annotation { false, // 标签文本在线条下方 data.order, group.shapes[0] as Line, + { + display: visible ? 'block' : 'none', + }, ), ); @@ -175,6 +178,9 @@ export class AnnotationRelation extends Annotation { true, // 属性文本在线条上方 data.order, group.shapes[0] as Line, + { + display: visible ? 'block' : 'none', + }, ), ); } diff --git a/packages/image/src/core/DomPortal.ts b/packages/image/src/core/DomPortal.ts index 9a9e4b7b2..1cf76f7e6 100644 --- a/packages/image/src/core/DomPortal.ts +++ b/packages/image/src/core/DomPortal.ts @@ -15,6 +15,7 @@ export interface DomPortalParams { content: HTMLElement | string; bindShape: AllShape; preventPointerEvents?: boolean; + style?: Record; } export class DomPortal { @@ -48,6 +49,7 @@ export class DomPortal { order = 2, rotate = 0, getPosition, + style, }: DomPortalParams) { this._content = content; this._shape = bindShape; @@ -100,6 +102,10 @@ export class DomPortal { this._container.appendChild(this._wrapper); this._setupElementStyle(); + + if (style) { + Object.assign(this._wrapper.style, style); + } } private _setupElementStyle() { @@ -154,10 +160,6 @@ export class DomPortal { this._wrapper.style.display = 'none'; } - public setOpacity(opacity: number) { - this._wrapper.style.opacity = `${opacity}`; - } - public toTop() { this._wrapper.style.zIndex = '1049'; } diff --git a/packages/image/src/drafts/ControllerEdge.ts b/packages/image/src/drafts/ControllerEdge.ts index f00ea2a7e..64cd4d37a 100644 --- a/packages/image/src/drafts/ControllerEdge.ts +++ b/packages/image/src/drafts/ControllerEdge.ts @@ -137,6 +137,14 @@ export class ControllerEdge extends Line { eventEmitter.emit('change'); }; + public set disabled(disabled: boolean) { + this._disabled = disabled; + } + + public get disabled() { + return this._disabled; + } + public onMove(handler: EdgeHandler) { this._onMoveHandlers.push(handler); } diff --git a/packages/image/src/drafts/ControllerPoint.ts b/packages/image/src/drafts/ControllerPoint.ts index ff92ace7e..601e75a11 100644 --- a/packages/image/src/drafts/ControllerPoint.ts +++ b/packages/image/src/drafts/ControllerPoint.ts @@ -156,6 +156,14 @@ export class ControllerPoint extends Point { eventEmitter.emit('change'); }; + public set disabled(disabled: boolean) { + this._disabled = disabled; + } + + public get disabled() { + return this._disabled; + } + public clone() { return new ControllerPoint({ id: this.id, diff --git a/packages/image/src/tools/Tool.decorator.ts b/packages/image/src/tools/Tool.decorator.ts index c693bb33a..363ac882c 100644 --- a/packages/image/src/tools/Tool.decorator.ts +++ b/packages/image/src/tools/Tool.decorator.ts @@ -1,5 +1,8 @@ import cloneDeep from 'lodash.clonedeep'; +import { ControllerPoint } from '@/drafts/ControllerPoint'; +import { ControllerEdge } from '@/drafts/ControllerEdge'; + import { axis, eventEmitter, monitor } from '../singletons'; import { EInternalEvent } from '../enums'; import type { BasicImageAnnotation } from '../interface'; @@ -176,6 +179,13 @@ export function ToolWrapper< if (this.draft && ids.includes(this.draft.id)) { this.draft.data.visible = visible; + + for (const shape of this.draft.group.shapes) { + if (shape instanceof ControllerPoint || shape instanceof ControllerEdge) { + shape.disabled = !visible; + } + } + this.draft.group.updateStyle({ opacity: visible ? 1 : 0, } as any);