React UI: cuboids (#1451)
parent
227ab05e73
commit
bf6f550561
@ -0,0 +1,494 @@
|
|||||||
|
/* eslint-disable func-names */
|
||||||
|
/* eslint-disable no-underscore-dangle */
|
||||||
|
/* eslint-disable curly */
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Intel Corporation
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
import consts from './consts';
|
||||||
|
|
||||||
|
export interface Point {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum Orientation {
|
||||||
|
LEFT = 'left',
|
||||||
|
RIGHT = 'right',
|
||||||
|
}
|
||||||
|
|
||||||
|
function line(p1: Point, p2: Point): number[] {
|
||||||
|
const a = p1.y - p2.y;
|
||||||
|
const b = p2.x - p1.x;
|
||||||
|
const c = b * p1.y + a * p1.x;
|
||||||
|
return [a, b, c];
|
||||||
|
}
|
||||||
|
|
||||||
|
function intersection(
|
||||||
|
p1: Point, p2: Point, p3: Point, p4: Point,
|
||||||
|
): Point | null {
|
||||||
|
const L1 = line(p1, p2);
|
||||||
|
const L2 = line(p3, p4);
|
||||||
|
|
||||||
|
const D = L1[0] * L2[1] - L1[1] * L2[0];
|
||||||
|
const Dx = L1[2] * L2[1] - L1[1] * L2[2];
|
||||||
|
const Dy = L1[0] * L2[2] - L1[2] * L2[0];
|
||||||
|
|
||||||
|
let x = null;
|
||||||
|
let y = null;
|
||||||
|
if (D !== 0) {
|
||||||
|
x = Dx / D;
|
||||||
|
y = Dy / D;
|
||||||
|
return { x, y };
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Equation {
|
||||||
|
private a: number;
|
||||||
|
private b: number;
|
||||||
|
private c: number;
|
||||||
|
|
||||||
|
public constructor(p1: Point, p2: Point) {
|
||||||
|
this.a = p1.y - p2.y;
|
||||||
|
this.b = p2.x - p1.x;
|
||||||
|
this.c = this.b * p1.y + this.a * p1.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the line equation in actual coordinates
|
||||||
|
public getY(x: number): number {
|
||||||
|
return (this.c - this.a * x) / this.b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Figure {
|
||||||
|
private indices: number[];
|
||||||
|
private allPoints: Point[];
|
||||||
|
|
||||||
|
public constructor(indices: number[], points: Point[]) {
|
||||||
|
this.indices = indices;
|
||||||
|
this.allPoints = points;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get points(): Point[] {
|
||||||
|
const points = [];
|
||||||
|
for (const index of this.indices) {
|
||||||
|
points.push(this.allPoints[index]);
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sets the point for a given edge, points must be given in
|
||||||
|
// array form in the same ordering as the getter
|
||||||
|
// if you only need to update a subset of the points,
|
||||||
|
// simply put null for the points you want to keep
|
||||||
|
public set points(newPoints) {
|
||||||
|
const oldPoints = this.allPoints;
|
||||||
|
for (let i = 0; i < newPoints.length; i += 1) {
|
||||||
|
if (newPoints[i] !== null) {
|
||||||
|
oldPoints[this.indices[i]] = { x: newPoints[i].x, y: newPoints[i].y };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Edge extends Figure {
|
||||||
|
public getEquation(): Equation {
|
||||||
|
return new Equation(this.points[0], this.points[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class CuboidModel {
|
||||||
|
public points: Point[];
|
||||||
|
private fr: Edge;
|
||||||
|
private fl: Edge;
|
||||||
|
private dr: Edge;
|
||||||
|
private dl: Edge;
|
||||||
|
private ft: Edge;
|
||||||
|
private rt: Edge;
|
||||||
|
private lt: Edge;
|
||||||
|
private dt: Edge;
|
||||||
|
private fb: Edge;
|
||||||
|
private rb: Edge;
|
||||||
|
private lb: Edge;
|
||||||
|
private db: Edge;
|
||||||
|
public edgeList: Edge[];
|
||||||
|
private front: Figure;
|
||||||
|
private right: Figure;
|
||||||
|
private dorsal: Figure;
|
||||||
|
private left: Figure;
|
||||||
|
private top: Figure;
|
||||||
|
private bot: Figure;
|
||||||
|
public facesList: Figure[];
|
||||||
|
public vpl: Point | null;
|
||||||
|
public vpr: Point | null;
|
||||||
|
public orientation: Orientation;
|
||||||
|
|
||||||
|
public constructor(points?: Point[]) {
|
||||||
|
this.points = points;
|
||||||
|
this.initEdges();
|
||||||
|
this.initFaces();
|
||||||
|
this.updateVanishingPoints(false);
|
||||||
|
this.buildBackEdge(false);
|
||||||
|
this.updatePoints();
|
||||||
|
this.updateOrientation();
|
||||||
|
}
|
||||||
|
|
||||||
|
public getPoints(): Point[] {
|
||||||
|
return this.points;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setPoints(points: (Point | null)[]): void {
|
||||||
|
points.forEach((point: Point | null, i: number): void => {
|
||||||
|
if (point !== null) {
|
||||||
|
this.points[i].x = point.x;
|
||||||
|
this.points[i].y = point.y;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateOrientation(): void {
|
||||||
|
if (this.dl.points[0].x > this.fl.points[0].x) {
|
||||||
|
this.orientation = Orientation.LEFT;
|
||||||
|
} else {
|
||||||
|
this.orientation = Orientation.RIGHT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public updatePoints(): void {
|
||||||
|
// making sure that the edges are vertical
|
||||||
|
this.fr.points[0].x = this.fr.points[1].x;
|
||||||
|
this.fl.points[0].x = this.fl.points[1].x;
|
||||||
|
this.dr.points[0].x = this.dr.points[1].x;
|
||||||
|
this.dl.points[0].x = this.dl.points[1].x;
|
||||||
|
}
|
||||||
|
|
||||||
|
public computeSideEdgeConstraints(edge: any): any {
|
||||||
|
const midLength = this.fr.points[1].y - this.fr.points[0].y - 1;
|
||||||
|
|
||||||
|
const minY = edge.points[1].y - midLength;
|
||||||
|
const maxY = edge.points[0].y + midLength;
|
||||||
|
|
||||||
|
const y1 = edge.points[0].y;
|
||||||
|
const y2 = edge.points[1].y;
|
||||||
|
|
||||||
|
const miny1 = y2 - midLength;
|
||||||
|
const maxy1 = y2 - consts.MIN_EDGE_LENGTH;
|
||||||
|
|
||||||
|
const miny2 = y1 + consts.MIN_EDGE_LENGTH;
|
||||||
|
const maxy2 = y1 + midLength;
|
||||||
|
|
||||||
|
return {
|
||||||
|
constraint: {
|
||||||
|
minY,
|
||||||
|
maxY,
|
||||||
|
},
|
||||||
|
y1Range: {
|
||||||
|
max: maxy1,
|
||||||
|
min: miny1,
|
||||||
|
},
|
||||||
|
y2Range: {
|
||||||
|
max: maxy2,
|
||||||
|
min: miny2,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// boolean value parameter controls which edges should be used to recalculate vanishing points
|
||||||
|
private updateVanishingPoints(buildright: boolean): void {
|
||||||
|
let leftEdge = [];
|
||||||
|
let rightEdge = [];
|
||||||
|
let midEdge = [];
|
||||||
|
if (buildright) {
|
||||||
|
leftEdge = this.fr.points;
|
||||||
|
rightEdge = this.dl.points;
|
||||||
|
midEdge = this.fl.points;
|
||||||
|
} else {
|
||||||
|
leftEdge = this.fl.points;
|
||||||
|
rightEdge = this.dr.points;
|
||||||
|
midEdge = this.fr.points;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.vpl = intersection(leftEdge[0], midEdge[0], leftEdge[1], midEdge[1]);
|
||||||
|
this.vpr = intersection(rightEdge[0], midEdge[0], rightEdge[1], midEdge[1]);
|
||||||
|
if (this.vpl === null) {
|
||||||
|
// shift the edge slightly to avoid edge case
|
||||||
|
leftEdge[0].y -= 0.001;
|
||||||
|
leftEdge[0].x += 0.001;
|
||||||
|
leftEdge[1].x += 0.001;
|
||||||
|
this.vpl = intersection(leftEdge[0], midEdge[0], leftEdge[1], midEdge[1]);
|
||||||
|
}
|
||||||
|
if (this.vpr === null) {
|
||||||
|
// shift the edge slightly to avoid edge case
|
||||||
|
rightEdge[0].y -= 0.001;
|
||||||
|
rightEdge[0].x -= 0.001;
|
||||||
|
rightEdge[1].x -= 0.001;
|
||||||
|
this.vpr = intersection(leftEdge[0], midEdge[0], leftEdge[1], midEdge[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private initEdges(): void {
|
||||||
|
this.fl = new Edge([0, 1], this.points);
|
||||||
|
this.fr = new Edge([2, 3], this.points);
|
||||||
|
this.dr = new Edge([4, 5], this.points);
|
||||||
|
this.dl = new Edge([6, 7], this.points);
|
||||||
|
|
||||||
|
this.ft = new Edge([0, 2], this.points);
|
||||||
|
this.lt = new Edge([0, 6], this.points);
|
||||||
|
this.rt = new Edge([2, 4], this.points);
|
||||||
|
this.dt = new Edge([6, 4], this.points);
|
||||||
|
|
||||||
|
this.fb = new Edge([1, 3], this.points);
|
||||||
|
this.lb = new Edge([1, 7], this.points);
|
||||||
|
this.rb = new Edge([3, 5], this.points);
|
||||||
|
this.db = new Edge([7, 5], this.points);
|
||||||
|
|
||||||
|
this.edgeList = [this.fl, this.fr, this.dl, this.dr, this.ft, this.lt,
|
||||||
|
this.rt, this.dt, this.fb, this.lb, this.rb, this.db];
|
||||||
|
}
|
||||||
|
|
||||||
|
private initFaces(): void {
|
||||||
|
this.front = new Figure([0, 1, 3, 2], this.points);
|
||||||
|
this.right = new Figure([2, 3, 5, 4], this.points);
|
||||||
|
this.dorsal = new Figure([4, 5, 7, 6], this.points);
|
||||||
|
this.left = new Figure([6, 7, 1, 0], this.points);
|
||||||
|
this.top = new Figure([0, 2, 4, 6], this.points);
|
||||||
|
this.bot = new Figure([1, 3, 5, 7], this.points);
|
||||||
|
|
||||||
|
this.facesList = [this.front, this.right, this.dorsal, this.left];
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildBackEdge(buildright: boolean): void {
|
||||||
|
this.updateVanishingPoints(buildright);
|
||||||
|
let leftPoints = [];
|
||||||
|
let rightPoints = [];
|
||||||
|
|
||||||
|
let topIndex = 0;
|
||||||
|
let botIndex = 0;
|
||||||
|
|
||||||
|
if (buildright) {
|
||||||
|
leftPoints = this.dl.points;
|
||||||
|
rightPoints = this.fr.points;
|
||||||
|
topIndex = 4;
|
||||||
|
botIndex = 5;
|
||||||
|
} else {
|
||||||
|
leftPoints = this.dr.points;
|
||||||
|
rightPoints = this.fl.points;
|
||||||
|
topIndex = 6;
|
||||||
|
botIndex = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
const vpLeft = this.vpl;
|
||||||
|
const vpRight = this.vpr;
|
||||||
|
|
||||||
|
let p1 = intersection(vpLeft, leftPoints[0], vpRight, rightPoints[0]);
|
||||||
|
let p2 = intersection(vpLeft, leftPoints[1], vpRight, rightPoints[1]);
|
||||||
|
|
||||||
|
if (p1 === null) {
|
||||||
|
p1 = { x: p2.x, y: vpLeft.y };
|
||||||
|
} else if (p2 === null) {
|
||||||
|
p2 = { x: p1.x, y: vpLeft.y };
|
||||||
|
}
|
||||||
|
|
||||||
|
this.points[topIndex] = { x: p1.x, y: p1.y };
|
||||||
|
this.points[botIndex] = { x: p2.x, y: p2.y };
|
||||||
|
|
||||||
|
// Making sure that the vertical edges stay vertical
|
||||||
|
this.updatePoints();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortPointsClockwise(points: any[]): any[] {
|
||||||
|
points.sort((a, b): number => a.y - b.y);
|
||||||
|
// Get center y
|
||||||
|
const cy = (points[0].y + points[points.length - 1].y) / 2;
|
||||||
|
|
||||||
|
// Sort from right to left
|
||||||
|
points.sort((a, b): number => b.x - a.x);
|
||||||
|
|
||||||
|
// Get center x
|
||||||
|
const cx = (points[0].x + points[points.length - 1].x) / 2;
|
||||||
|
|
||||||
|
// Center point
|
||||||
|
const center = {
|
||||||
|
x: cx,
|
||||||
|
y: cy,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Starting angle used to reference other angles
|
||||||
|
let startAng: number | undefined;
|
||||||
|
points.forEach((point): void => {
|
||||||
|
let ang = Math.atan2(point.y - center.y, point.x - center.x);
|
||||||
|
if (!startAng) {
|
||||||
|
startAng = ang;
|
||||||
|
// ensure that all points are clockwise of the start point
|
||||||
|
} else if (ang < startAng) {
|
||||||
|
ang += Math.PI * 2;
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
point.angle = ang; // add the angle to the point
|
||||||
|
});
|
||||||
|
|
||||||
|
// first sort clockwise
|
||||||
|
points.sort((a, b): number => a.angle - b.angle);
|
||||||
|
return points.reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupCuboidPoints(points: Point[]): any[] {
|
||||||
|
let left;
|
||||||
|
let right;
|
||||||
|
let left2;
|
||||||
|
let right2;
|
||||||
|
let p1;
|
||||||
|
let p2;
|
||||||
|
let p3;
|
||||||
|
let p4;
|
||||||
|
|
||||||
|
const height = Math.abs(points[0].x - points[1].x)
|
||||||
|
< Math.abs(points[1].x - points[2].x)
|
||||||
|
? Math.abs(points[1].y - points[0].y)
|
||||||
|
: Math.abs(points[1].y - points[2].y);
|
||||||
|
|
||||||
|
// seperate into left and right point
|
||||||
|
// we pick the first and third point because we know assume they will be on
|
||||||
|
// opposite corners
|
||||||
|
if (points[0].x < points[2].x) {
|
||||||
|
[left,, right] = points;
|
||||||
|
} else {
|
||||||
|
[right,, left] = points;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get other 2 points using the given height
|
||||||
|
if (left.y < right.y) {
|
||||||
|
left2 = { x: left.x, y: left.y + height };
|
||||||
|
right2 = { x: right.x, y: right.y - height };
|
||||||
|
} else {
|
||||||
|
left2 = { x: left.x, y: left.y - height };
|
||||||
|
right2 = { x: right.x, y: right.y + height };
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the vector for the last point relative to the previous point
|
||||||
|
const vec = {
|
||||||
|
x: points[3].x - points[2].x,
|
||||||
|
y: points[3].y - points[2].y,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (left.y < left2.y) {
|
||||||
|
p1 = left;
|
||||||
|
p2 = left2;
|
||||||
|
} else {
|
||||||
|
p1 = left2;
|
||||||
|
p2 = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (right.y < right2.y) {
|
||||||
|
p3 = right;
|
||||||
|
p4 = right2;
|
||||||
|
} else {
|
||||||
|
p3 = right2;
|
||||||
|
p4 = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
const p5 = { x: p3.x + vec.x, y: p3.y + vec.y + 0.1 };
|
||||||
|
const p6 = { x: p4.x + vec.x, y: p4.y + vec.y - 0.1 };
|
||||||
|
const p7 = { x: p1.x + vec.x, y: p1.y + vec.y + 0.1 };
|
||||||
|
const p8 = { x: p2.x + vec.x, y: p2.y + vec.y - 0.1 };
|
||||||
|
|
||||||
|
p1.y += 0.1;
|
||||||
|
return [p1, p2, p3, p4, p5, p6, p7, p8];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function cuboidFrom4Points(flattenedPoints: any[]): any[] {
|
||||||
|
const points: Point[] = [];
|
||||||
|
for (let i = 0; i < 4; i++) {
|
||||||
|
const [x, y] = flattenedPoints.slice(i * 2, i * 2 + 2);
|
||||||
|
points.push({ x, y });
|
||||||
|
}
|
||||||
|
const unsortedPlanePoints = points.slice(0, 3);
|
||||||
|
function rotate(array: any[], times: number): void{
|
||||||
|
let t = times;
|
||||||
|
while (t--) {
|
||||||
|
const temp = array.shift();
|
||||||
|
array.push(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const plane2 = {
|
||||||
|
p1: points[0],
|
||||||
|
p2: points[0],
|
||||||
|
p3: points[0],
|
||||||
|
p4: points[0],
|
||||||
|
};
|
||||||
|
|
||||||
|
// completing the plane
|
||||||
|
const vector = {
|
||||||
|
x: points[2].x - points[1].x,
|
||||||
|
y: points[2].y - points[1].y,
|
||||||
|
};
|
||||||
|
|
||||||
|
// sorting the first plane
|
||||||
|
unsortedPlanePoints.push({
|
||||||
|
x: points[0].x + vector.x,
|
||||||
|
y: points[0].y + vector.y,
|
||||||
|
});
|
||||||
|
const sortedPlanePoints = sortPointsClockwise(unsortedPlanePoints);
|
||||||
|
let leftIndex = 0;
|
||||||
|
for (let i = 0; i < 4; i++) {
|
||||||
|
leftIndex = sortedPlanePoints[i].x < sortedPlanePoints[leftIndex].x ? i : leftIndex;
|
||||||
|
}
|
||||||
|
rotate(sortedPlanePoints, leftIndex);
|
||||||
|
const plane1 = {
|
||||||
|
p1: sortedPlanePoints[0],
|
||||||
|
p2: sortedPlanePoints[1],
|
||||||
|
p3: sortedPlanePoints[2],
|
||||||
|
p4: sortedPlanePoints[3],
|
||||||
|
};
|
||||||
|
|
||||||
|
const vec = {
|
||||||
|
x: points[3].x - points[2].x,
|
||||||
|
y: points[3].y - points[2].y,
|
||||||
|
};
|
||||||
|
// determine the orientation
|
||||||
|
const angle = Math.atan2(vec.y, vec.x);
|
||||||
|
|
||||||
|
// making the other plane
|
||||||
|
plane2.p1 = { x: plane1.p1.x + vec.x, y: plane1.p1.y + vec.y };
|
||||||
|
plane2.p2 = { x: plane1.p2.x + vec.x, y: plane1.p2.y + vec.y };
|
||||||
|
plane2.p3 = { x: plane1.p3.x + vec.x, y: plane1.p3.y + vec.y };
|
||||||
|
plane2.p4 = { x: plane1.p4.x + vec.x, y: plane1.p4.y + vec.y };
|
||||||
|
|
||||||
|
|
||||||
|
let cuboidPoints;
|
||||||
|
// right
|
||||||
|
if (Math.abs(angle) < Math.PI / 2 - 0.1) {
|
||||||
|
cuboidPoints = setupCuboidPoints(points);
|
||||||
|
// left
|
||||||
|
} else if (Math.abs(angle) > Math.PI / 2 + 0.1) {
|
||||||
|
cuboidPoints = setupCuboidPoints(points);
|
||||||
|
// down
|
||||||
|
} else if (angle > 0) {
|
||||||
|
cuboidPoints = [
|
||||||
|
plane1.p1, plane2.p1, plane1.p2, plane2.p2,
|
||||||
|
plane1.p3, plane2.p3, plane1.p4, plane2.p4,
|
||||||
|
];
|
||||||
|
cuboidPoints[0].y += 0.1;
|
||||||
|
cuboidPoints[4].y += 0.1;
|
||||||
|
// up
|
||||||
|
} else {
|
||||||
|
cuboidPoints = [
|
||||||
|
plane2.p1, plane1.p1, plane2.p2, plane1.p2,
|
||||||
|
plane2.p3, plane1.p3, plane2.p4, plane1.p4,
|
||||||
|
];
|
||||||
|
cuboidPoints[0].y += 0.1;
|
||||||
|
cuboidPoints[4].y += 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cuboidPoints.reduce((arr: number[], point: any): number[] => {
|
||||||
|
arr.push(point.x);
|
||||||
|
arr.push(point.y);
|
||||||
|
return arr;
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M3 13L2.34921 12.2407L2 12.5401V13H3ZM3 33H2V34H3V33ZM30 33V34H30.3699L30.6508 33.7593L30 33ZM37 27L37.6508 27.7593L38 27.4599V27H37ZM37 7H38V6H37V7ZM10 7V6H9.63008L9.34921 6.24074L10 7ZM2 13V33H4V13H2ZM3 34H30V32H3V34ZM30.6508 33.7593L37.6508 27.7593L36.3492 26.2407L29.3492 32.2407L30.6508 33.7593ZM38 27V7H36V27H38ZM36.3492 6.24074L29.3492 12.2407L30.6508 13.7593L37.6508 7.75926L36.3492 6.24074ZM30 12H3V14H30V12ZM31 33V13H29V33H31ZM3.65079 13.7593L10.6508 7.75926L9.34921 6.24074L2.34921 12.2407L3.65079 13.7593ZM10 8H37V6H10V8Z" fill="black"/></svg>
|
||||||
|
After Width: | Height: | Size: 660 B |
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright (C) 2020 Intel Corporation
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import Popover from 'antd/lib/popover';
|
||||||
|
import Icon from 'antd/lib/icon';
|
||||||
|
|
||||||
|
import { Canvas } from 'cvat-canvas';
|
||||||
|
import { ShapeType } from 'reducers/interfaces';
|
||||||
|
|
||||||
|
import { CubeIcon } from 'icons';
|
||||||
|
|
||||||
|
import DrawShapePopoverContainer from 'containers/annotation-page/standard-workspace/controls-side-bar/draw-shape-popover';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
canvasInstance: Canvas;
|
||||||
|
isDrawing: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
function DrawPolygonControl(props: Props): JSX.Element {
|
||||||
|
const {
|
||||||
|
canvasInstance,
|
||||||
|
isDrawing,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const dynamcPopoverPros = isDrawing ? {
|
||||||
|
overlayStyle: {
|
||||||
|
display: 'none',
|
||||||
|
},
|
||||||
|
} : {};
|
||||||
|
|
||||||
|
const dynamicIconProps = isDrawing ? {
|
||||||
|
className: 'cvat-active-canvas-control',
|
||||||
|
onClick: (): void => {
|
||||||
|
canvasInstance.draw({ enabled: false });
|
||||||
|
},
|
||||||
|
} : {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover
|
||||||
|
{...dynamcPopoverPros}
|
||||||
|
overlayClassName='cvat-draw-shape-popover'
|
||||||
|
placement='right'
|
||||||
|
content={(
|
||||||
|
<DrawShapePopoverContainer shapeType={ShapeType.CUBOID} />
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
{...dynamicIconProps}
|
||||||
|
component={CubeIcon}
|
||||||
|
/>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default React.memo(DrawPolygonControl);
|
||||||
Loading…
Reference in New Issue