diff --git a/cvat-canvas/src/typescript/canvasView.ts b/cvat-canvas/src/typescript/canvasView.ts index ebda629c183b..3d661f3d6ae9 100644 --- a/cvat-canvas/src/typescript/canvasView.ts +++ b/cvat-canvas/src/typescript/canvasView.ts @@ -464,9 +464,10 @@ export class CanvasViewImpl implements CanvasView, Listener { const circle: SVG.Circle = this.nested .circle(this.options.pointSize) .stroke('black') - .fill(shape.node.getAttribute('fill') || 'inherit') + .fill('inherit') .center(cx, cy) .attr({ + 'fill-opacity': 1, 'stroke-width': consts.POINTS_STROKE_WIDTH / self.geometry.scale, }); @@ -496,6 +497,11 @@ export class CanvasViewImpl implements CanvasView, Listener { deepSelect: true, }); } + + const handler = shape.remember('_selectHandler'); + if (handler && handler.nested) { + handler.nested.fill(shape.attr('fill')); + } } public constructor(model: CanvasModel & Master, controller: CanvasController) { @@ -1314,10 +1320,7 @@ export class CanvasViewImpl implements CanvasView, Listener { .addClass('cvat_canvas_shape').attr({ clientID: state.clientID, id: `cvat_canvas_shape_${state.clientID}`, - fill: state.color, 'data-z-order': state.zOrder, - }).style({ - 'fill-opacity': 1, }); group.bbox = basicPolyline.bbox.bind(basicPolyline); diff --git a/cvat-core/src/annotations-objects.js b/cvat-core/src/annotations-objects.js index e5de9685e3a9..deb16aea26b0 100644 --- a/cvat-core/src/annotations-objects.js +++ b/cvat-core/src/annotations-objects.js @@ -345,7 +345,7 @@ if (updated.color) { checkObjectType('color', data.color, 'string', null); - if (/^#[0-9A-F]{6}$/i.test(data.color)) { + if (!/^#[0-9A-F]{6}$/i.test(data.color)) { throw new ArgumentError( `Got invalid color value: "${data.color}"`, ); diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx index e7a08656f3e1..3bcf6a596e4d 100644 --- a/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx +++ b/cvat-ui/src/components/annotation-page/standard-workspace/canvas-wrapper.tsx @@ -302,15 +302,12 @@ export default class CanvasWrapperComponent extends React.PureComponent { // TODO: In this approach CVAT-UI know details of implementations CVAT-CANVAS (svg.js) const shapeView = window.document.getElementById(`cvat_canvas_shape_${state.clientID}`); if (shapeView) { - if (['rect', 'polygon', 'polyline'].includes(shapeView.tagName)) { - (shapeView as any).instance.fill({ color: shapeColor, opacity: opacity / 100 }); - (shapeView as any).instance.stroke({ color: blackBorders ? 'black' : shapeColor }); - } else { - // group of points - for (const child of (shapeView as any).instance.children()) { - child.fill({ color: shapeColor }); - } + const handler = (shapeView as any).instance.remember('_selectHandler'); + if (handler && handler.nested) { + handler.nested.fill({ color: shapeColor }); } + (shapeView as any).instance.fill({ color: shapeColor, opacity: opacity / 100 }); + (shapeView as any).instance.stroke({ color: blackBorders ? 'black' : shapeColor }); } } } diff --git a/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/color-changer.tsx b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/color-changer.tsx new file mode 100644 index 000000000000..1a96ff32bdd2 --- /dev/null +++ b/cvat-ui/src/components/annotation-page/standard-workspace/objects-side-bar/color-changer.tsx @@ -0,0 +1,56 @@ +import React from 'react'; + +import { + Row, + Col, + Button, +} from 'antd'; + +interface Props { + colors: string[]; + onChange(color: string): void; +} + +function ColorChanger(props: Props): JSX.Element { + const { + colors, + onChange, + } = props; + + const cols = 6; + const rows = Math.ceil(colors.length / cols); + + const antdRows = []; + for (let row = 0; row < rows; row++) { + const antdCols = []; + for (let col = 0; col < cols; col++) { + const idx = row * cols + col; + if (idx >= colors.length) { + break; + } + const color = colors[idx]; + antdCols.push( + +