Skip to content

Commit

Permalink
React UI: Added shortcuts (#1230)
Browse files Browse the repository at this point in the history
  • Loading branch information
bsekachev authored Mar 5, 2020
1 parent 8afb5dd commit 78dad73
Show file tree
Hide file tree
Showing 27 changed files with 1,349 additions and 213 deletions.
124 changes: 64 additions & 60 deletions cvat-canvas/src/typescript/drawHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export class DrawHandlerImpl implements DrawHandler {
private onDrawDone: (data: object, continueDraw?: boolean) => void;
private canvas: SVG.Container;
private text: SVG.Container;
private cursorPosition: {
x: number;
y: number;
};
private crosshair: {
x: SVG.Line;
y: SVG.Line;
Expand Down Expand Up @@ -96,12 +100,13 @@ export class DrawHandlerImpl implements DrawHandler {
}

private addCrosshair(): void {
const { x, y } = this.cursorPosition;
this.crosshair = {
x: this.canvas.line(0, 0, this.canvas.node.clientWidth, 0).attr({
x: this.canvas.line(0, y, this.canvas.node.clientWidth, y).attr({
'stroke-width': consts.BASE_STROKE_WIDTH / (2 * this.geometry.scale),
zOrder: Number.MAX_SAFE_INTEGER,
}).addClass('cvat_canvas_crosshair'),
y: this.canvas.line(0, 0, 0, this.canvas.node.clientHeight).attr({
y: this.canvas.line(x, 0, x, this.canvas.node.clientHeight).attr({
'stroke-width': consts.BASE_STROKE_WIDTH / (2 * this.geometry.scale),
zOrder: Number.MAX_SAFE_INTEGER,
}).addClass('cvat_canvas_crosshair'),
Expand Down Expand Up @@ -181,7 +186,6 @@ export class DrawHandlerImpl implements DrawHandler {
this.shapeSizeElement.update(this.drawInstance);
}).addClass('cvat_canvas_shape_drawing').attr({
'stroke-width': consts.BASE_STROKE_WIDTH / this.geometry.scale,
z_order: Number.MAX_SAFE_INTEGER,
});
}

Expand Down Expand Up @@ -222,10 +226,6 @@ export class DrawHandlerImpl implements DrawHandler {
}

private drawPolyshape(): void {
this.drawInstance.attr({
z_order: Number.MAX_SAFE_INTEGER,
});

let size = this.drawData.numberOfPoints;
const sizeDecrement = function sizeDecrement(): void {
if (!--size) {
Expand Down Expand Up @@ -371,18 +371,17 @@ export class DrawHandlerImpl implements DrawHandler {

// Common settings for rectangle and polyshapes
private pasteShape(): void {
this.drawInstance.attr({
z_order: Number.MAX_SAFE_INTEGER,
});
function moveShape(shape: SVG.Shape, x: number, y: number): void {
const bbox = shape.bbox();
shape.move(x - bbox.width / 2, y - bbox.height / 2);
}

this.canvas.on('mousemove.draw', (e: MouseEvent): void => {
const [x, y] = translateToSVG(
this.canvas.node as any as SVGSVGElement,
[e.clientX, e.clientY],
);
const { x: initialX, y: initialY } = this.cursorPosition;
moveShape(this.drawInstance, initialX, initialY);

const bbox = this.drawInstance.bbox();
this.drawInstance.move(x - bbox.width / 2, y - bbox.height / 2);
this.canvas.on('mousemove.draw', (): void => {
const { x, y } = this.cursorPosition; // was computer in another callback
moveShape(this.drawInstance, x, y);
});
}

Expand Down Expand Up @@ -429,45 +428,53 @@ export class DrawHandlerImpl implements DrawHandler {
this.pastePolyshape();
}

private pastePoints(points: string): void {
this.drawInstance = (this.canvas as any).polyline(points)
private pastePoints(initialPoints: string): void {
function moveShape(
shape: SVG.PolyLine,
group: SVG.G,
x: number,
y: number,
scale: number,
): void {
const bbox = shape.bbox();
shape.move(x - bbox.width / 2, y - bbox.height / 2);

const points = shape.attr('points').split(' ');
const radius = consts.BASE_POINT_SIZE / scale;

group.children().forEach((child: SVG.Element, idx: number): void => {
const [px, py] = points[idx].split(',');
child.move(px - radius / 2, py - radius / 2);
});
}

const { x: initialX, y: initialY } = this.cursorPosition;
this.pointsGroup = this.canvas.group();
this.drawInstance = (this.canvas as any).polyline(initialPoints)
.addClass('cvat_canvas_shape_drawing').style({
'stroke-width': 0,
});

this.pointsGroup = this.canvas.group();
for (const point of points.split(' ')) {
let numOfPoints = initialPoints.split(' ').length;
while (numOfPoints) {
numOfPoints--;
const radius = consts.BASE_POINT_SIZE / this.geometry.scale;
const stroke = consts.POINTS_STROKE_WIDTH / this.geometry.scale;
const [x, y] = point.split(',').map((coord: string): number => +coord);
this.pointsGroup.circle().move(x - radius / 2, y - radius / 2)
.fill('white').stroke('black').attr({
r: radius,
'stroke-width': stroke,
});
this.pointsGroup.circle().fill('white').stroke('black').attr({
r: radius,
'stroke-width': stroke,
});
}

this.pointsGroup.attr({
z_order: Number.MAX_SAFE_INTEGER,
});
moveShape(
this.drawInstance, this.pointsGroup, initialX, initialY, this.geometry.scale,
);

this.canvas.on('mousemove.draw', (e: MouseEvent): void => {
const [x, y] = translateToSVG(
this.canvas.node as any as SVGSVGElement,
[e.clientX, e.clientY],
this.canvas.on('mousemove.draw', (): void => {
const { x, y } = this.cursorPosition; // was computer in another callback
moveShape(
this.drawInstance, this.pointsGroup, x, y, this.geometry.scale,
);

const bbox = this.drawInstance.bbox();
this.drawInstance.move(x - bbox.width / 2, y - bbox.height / 2);
const radius = consts.BASE_POINT_SIZE / this.geometry.scale;
const newPoints = this.drawInstance.attr('points').split(' ');
if (this.pointsGroup) {
this.pointsGroup.children()
.forEach((child: SVG.Element, idx: number): void => {
const [px, py] = newPoints[idx].split(',');
child.move(px - radius / 2, py - radius / 2);
});
}
});

this.pastePolyshape();
Expand Down Expand Up @@ -593,23 +600,20 @@ export class DrawHandlerImpl implements DrawHandler {
this.crosshair = null;
this.drawInstance = null;
this.pointsGroup = null;
this.cursorPosition = {
x: 0,
y: 0,
};

this.canvas.on('mousemove.crosshair', (e: MouseEvent): void => {
const [x, y] = translateToSVG(
this.canvas.node as any as SVGSVGElement,
[e.clientX, e.clientY],
);
this.cursorPosition = { x, y };
if (this.crosshair) {
const [x, y] = translateToSVG(
this.canvas.node as any as SVGSVGElement,
[e.clientX, e.clientY],
);

this.crosshair.x.attr({
y1: y,
y2: y,
});

this.crosshair.y.attr({
x1: x,
x2: x,
});
this.crosshair.x.attr({ y1: y, y2: y });
this.crosshair.y.attr({ x1: x, x2: x });
}
});
}
Expand Down
7 changes: 5 additions & 2 deletions cvat-core/src/annotations-collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@
: (frame) => frame - 1;
for (let frame = frameFrom; predicate(frame); frame = update(frame)) {
// First prepare all data for the frame
// Consider all shapes, tags, and tracks that have keyframe here
// Consider all shapes, tags, and not outside tracks that have keyframe here
// In particular consider first and last frame as keyframes for all frames
const statesData = [].concat(
(frame in this.shapes ? this.shapes[frame] : [])
Expand All @@ -876,7 +876,10 @@
|| frame === frameFrom
|| frame === frameTo
));
statesData.push(...tracks.map((track) => track.get(frame)));
statesData.push(
...tracks.map((track) => track.get(frame))
.filter((state) => !state.outside),
);

// Nothing to filtering, go to the next iteration
if (!statesData.length) {
Expand Down
4 changes: 2 additions & 2 deletions cvat-core/src/session.js
Original file line number Diff line number Diff line change
Expand Up @@ -1343,7 +1343,7 @@
return annotationsData;
};

Job.prototype.annotations.search.implementation = async function (filters, frameFrom, frameTo) {
Job.prototype.annotations.search.implementation = function (filters, frameFrom, frameTo) {
if (!Array.isArray(filters) || filters.some((filter) => typeof (filter) !== 'string')) {
throw new ArgumentError(
'The filters argument must be an array of strings',
Expand Down Expand Up @@ -1555,7 +1555,7 @@
return result;
};

Job.prototype.annotations.search.implementation = async function (filters, frameFrom, frameTo) {
Task.prototype.annotations.search.implementation = function (filters, frameFrom, frameTo) {
if (!Array.isArray(filters) || filters.some((filter) => typeof (filter) !== 'string')) {
throw new ArgumentError(
'The filters argument must be an array of strings',
Expand Down
10 changes: 9 additions & 1 deletion cvat-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cvat-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"prop-types": "^15.7.2",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-hotkeys": "^2.0.0",
"react-redux": "^7.1.1",
"react-router": "^5.1.0",
"react-router-dom": "^5.1.0",
Expand Down
Loading

0 comments on commit 78dad73

Please sign in to comment.