Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React UI: Player in annotation view & settings page #1018

Merged
merged 21 commits into from
Jan 13, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Improved cvat-canvas integration
  • Loading branch information
bsekachev committed Dec 30, 2019
commit 4cdfd4863f702d57d46cc7f8b7d92b6b17e1e3a8
1 change: 1 addition & 0 deletions cvat-canvas/src/typescript/canvasView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,7 @@ export class CanvasViewImpl implements CanvasView, Listener {
width: this.canvas.clientWidth,
};


this.controller.geometry = geometry;
this.geometry = geometry;
}
Expand Down
49 changes: 24 additions & 25 deletions cvat-core/src/annotations-objects.js
Original file line number Diff line number Diff line change
Expand Up @@ -480,20 +480,18 @@
// Method is used to construct ObjectState objects
get(frame) {
if (!(frame in this.cache)) {
const interpolation = Object.assign(
{}, this.getPosition(frame),
{
attributes: this.getAttributes(frame),
group: this.group,
objectType: ObjectType.TRACK,
shapeType: this.shapeType,
clientID: this.clientID,
serverID: this.serverID,
lock: this.lock,
color: this.color,
visibility: this.visibility,
},
);
const interpolation = {
...this.getPosition(frame),
attributes: this.getAttributes(frame),
group: this.group,
objectType: ObjectType.TRACK,
shapeType: this.shapeType,
clientID: this.clientID,
serverID: this.serverID,
lock: this.lock,
color: this.color,
visibility: this.visibility,
};

this.cache[frame] = interpolation;
}
Expand All @@ -504,7 +502,7 @@
}

neighborsFrames(targetFrame) {
const frames = Object.keys(this.shapes).map(frame => +frame);
const frames = Object.keys(this.shapes).map((frame) => +frame);
let lDiff = Number.MAX_SAFE_INTEGER;
let rDiff = Number.MAX_SAFE_INTEGER;

Expand Down Expand Up @@ -773,13 +771,14 @@
}

if (rightPosition && leftPosition) {
return Object.assign({}, this.interpolatePosition(
leftPosition,
rightPosition,
(targetFrame - leftFrame) / (rightFrame - leftFrame),
), {
return {
...this.interpolatePosition(
leftPosition,
rightPosition,
(targetFrame - leftFrame) / (rightFrame - leftFrame),
),
keyframe: false,
});
};
}

if (rightPosition) {
Expand Down Expand Up @@ -858,7 +857,7 @@
clientID: this.clientID,
serverID: this.serverID,
lock: this.lock,
attributes: Object.assign({}, this.attributes),
attributes: { ...this.attributes },
label: this.label,
group: this.group,
};
Expand Down Expand Up @@ -888,7 +887,7 @@

if (updated.attributes) {
const labelAttributes = copy.label
.attributes.map(attr => `${attr.id}`);
.attributes.map((attr) => `${attr.id}`);

for (const attrID of Object.keys(data.attributes)) {
if (labelAttributes.includes(attrID)) {
Expand Down Expand Up @@ -1399,8 +1398,8 @@
// some points from source and target can absent in mapping
// source, target - arrays of points. Target array size >= sourse array size
appendMapping(mapping, source, target) {
const targetMatched = Object.values(mapping).map(x => +x);
const sourceMatched = Object.keys(mapping).map(x => +x);
const targetMatched = Object.values(mapping).map((x) => +x);
const sourceMatched = Object.keys(mapping).map((x) => +x);
const orderForReceive = [];

function findNeighbors(point) {
Expand Down
5 changes: 3 additions & 2 deletions cvat-core/src/frames.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,9 @@

async function getFrame(taskID, mode, frame) {
if (!(taskID in frameDataCache)) {
frameDataCache[taskID] = {};
frameDataCache[taskID].meta = await serverProxy.frames.getMeta(taskID);
frameDataCache[taskID] = {
meta: await serverProxy.frames.getMeta(taskID),
};

frameCache[taskID] = {};
}
Expand Down
2 changes: 1 addition & 1 deletion cvat-core/src/labels.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@
toJSON() {
const object = {
name: this.name,
attributes: [...this.attributes.map(el => el.toJSON())],
attributes: [...this.attributes.map((el) => el.toJSON())],
};

if (typeof (this.id) !== 'undefined') {
Expand Down
4 changes: 2 additions & 2 deletions cvat-core/src/plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
const pluginList = await PluginRegistry.list();
for (const plugin of pluginList) {
const pluginDecorators = plugin.functions
.filter(obj => obj.callback === wrappedFunc)[0];
.filter((obj) => obj.callback === wrappedFunc)[0];
if (pluginDecorators && pluginDecorators.enter) {
try {
await pluginDecorators.enter.call(this, plugin, ...args);
Expand All @@ -35,7 +35,7 @@

for (const plugin of pluginList) {
const pluginDecorators = plugin.functions
.filter(obj => obj.callback === wrappedFunc)[0];
.filter((obj) => obj.callback === wrappedFunc)[0];
if (pluginDecorators && pluginDecorators.leave) {
try {
result = await pluginDecorators.leave.call(this, plugin, result, ...args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,38 @@ import { Canvas } from '../../../../../cvat-canvas/src/typescript/canvas';

interface Props {
jobInstance: any;
canvas: Canvas;
frame: number | null;
onSetupCanvas(): void;
}

export default class CanvasWrapperComponent extends React.PureComponent<Props> {
private initializedSize = false;
public readonly canvas: Canvas;
public constructor(props: Props) {
super(props);
this.canvas = new Canvas();
this.initializedSize = false;
}

public componentDidMount(): void {
const {
jobInstance,
onSetupCanvas,
canvas,
} = this.props;

// It's awful approach from the point of view React
// But we do not have any choice because cvat-canvas returns regular DOM element
const [wrapper] = window.document
.getElementsByClassName('cvat-annotation-page-canvas-container');
wrapper.appendChild(this.canvas.html());
wrapper.appendChild(canvas.html());
canvas.updateSize();

this.canvas.html().addEventListener('canvas.setup', () => {
if (!this.initializedSize) {
this.initializedSize = true;
this.canvas.updateSize();
this.canvas.fit();
}

canvas.html().addEventListener('canvas.setup', () => {
onSetupCanvas();
if (jobInstance.task.mode === 'annotation') {
this.canvas.fit();
canvas.fit();
}
onSetupCanvas();
});

canvas.html().addEventListener('canvas.setup', () => {
canvas.fit();
}, { once: true });

this.updateCanvas();
}

Expand All @@ -57,27 +51,25 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
const {
jobInstance,
frame,
canvas,
} = this.props;

if (frame !== null) {
jobInstance.frames.get(frame)
.then((frameData: any) => jobInstance.annotations.get(frame)
.then((annotations: any[]) => {
this.canvas.setup(frameData, annotations);
}).catch((error: any) => {
console.log(error);
// TODO: jobInstance.annotations.get(frame)
// requires meta information and there is an error
}))
.catch((error: any) => {
console.log(error);
});
Promise.all([

jobInstance.frames.get(frame),
jobInstance.annotations.get(frame),
]).then(([frameData, annotations]) => {
canvas.setup(frameData, annotations);
}).catch((error: any) => {
console.log(error);
});
}
}

public render(): JSX.Element {
return (
// This element doesn't has any props
// This element doesn't have any props
// So, React isn't going to rerender it
// And it's a reason why cvat-canvas appended in mount function works
<Layout.Content
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
Layout,
} from 'antd';

import { Canvas } from '../../../../../cvat-canvas/src/typescript/canvas';

import ControlsSideBarComponent from './controls-side-bar';
import CanvasWrapperComponent from './canvas-wrapper-component';
import ObjectSideBarComponent from './objects-side-bar/objects-side-bar';
Expand All @@ -15,32 +17,42 @@ interface Props {
onSetupCanvas(): void;
}

export default function StandardWorkspaceComponent(props: Props): JSX.Element {
const {
jobInstance,
frame,
onSetupCanvas,
} = props;

const canvasWrapper = React.createRef<CanvasWrapperComponent>();

return (
<Layout>
<ControlsSideBarComponent />
<CanvasWrapperComponent
jobInstance={jobInstance}
frame={frame}
onSetupCanvas={onSetupCanvas}
ref={canvasWrapper}
/>
<ObjectSideBarComponent
onSidebarFoldUnfold={(): void => {
if (canvasWrapper.current) {
canvasWrapper.current.canvas.updateSize();
canvasWrapper.current.canvas.fit();
}
}}
/>
</Layout>
);
interface State {
canvas: Canvas;
}

export default class StandardWorkspaceComponent extends React.PureComponent<Props, State> {
public constructor(props: Props) {
super(props);
this.state = {
canvas: new Canvas(),
};
}

public render(): JSX.Element {
const {
jobInstance,
frame,
onSetupCanvas,
} = this.props;

const { canvas } = this.state;

return (
<Layout hasSider>
<ControlsSideBarComponent />
<CanvasWrapperComponent
jobInstance={jobInstance}
frame={frame}
onSetupCanvas={onSetupCanvas}
canvas={canvas}
/>
<ObjectSideBarComponent
onSidebarFoldUnfold={(): void => {
canvas.updateSize();
}}
/>
</Layout>
);
}
}