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: Improved rotation feature #1206

Merged
merged 25 commits into from
Feb 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8baacd6
Added settings actions
ActiveChooN Feb 17, 2020
1d56998
Added image filters for background and autosaving
ActiveChooN Feb 18, 2020
9175eb3
Merge branch 'develop' into dk/cvat-ui
ActiveChooN Feb 18, 2020
d24614f
Added frame speed control and frame auto fit
ActiveChooN Feb 18, 2020
d353e92
Merge branch 'develop' into dk/cvat-ui
ActiveChooN Feb 19, 2020
b5370f9
Added unsaved leave confirmation
ActiveChooN Feb 19, 2020
cf137b4
ESLint fixes
ActiveChooN Feb 20, 2020
4972f0a
PR fixes
ActiveChooN Feb 20, 2020
8c2fe43
Another PR fixes
ActiveChooN Feb 20, 2020
60f4477
Fixed link to new job and unsaved changes message
ActiveChooN Feb 21, 2020
22b6821
Fixed PR
ActiveChooN Feb 25, 2020
a5a62f0
Sync unsaved changes
bsekachev Feb 26, 2020
c0b9bb8
Merge pull request #1203 from opencv/bs/sync_unsaved_changes
ActiveChooN Feb 26, 2020
3b8f608
Fixed PR for sync hasUnsavedChanges
ActiveChooN Feb 26, 2020
a9383b2
Fixed PR
ActiveChooN Feb 26, 2020
ad4f301
Merge branch 'develop' into dk/cvat-ui
ActiveChooN Feb 27, 2020
21f1d84
Merge branch 'develop' into dk/cvat-ui
ActiveChooN Feb 27, 2020
5c96ad8
Fixed PR
ActiveChooN Feb 27, 2020
2979b01
Fixed new UI link
ActiveChooN Feb 27, 2020
e6b6d29
Improved frames rotation
ActiveChooN Feb 27, 2020
9340549
Improved frames rotation
ActiveChooN Feb 27, 2020
906fb88
Merge branch 'develop' into dk/cvat-ui
ActiveChooN Feb 27, 2020
80e8e54
Fixed PR
ActiveChooN Feb 27, 2020
28cc028
Minor fixes and README update
ActiveChooN Feb 28, 2020
2329226
Merge branch 'develop' into dk/cvat-ui
ActiveChooN Feb 28, 2020
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
9 changes: 2 additions & 7 deletions cvat-canvas/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,6 @@ Canvas itself handles:
### API Methods

```ts
enum Rotation {
ANTICLOCKWISE90,
CLOCKWISE90,
}

enum RectDrawingMethod {
CLASSIC = 'By 2 points',
EXTREME_POINTS = 'By 4 points'
Expand Down Expand Up @@ -79,7 +74,7 @@ Canvas itself handles:
setZLayer(zLayer: number | null): void;
setup(frameData: any, objectStates: any[]): void;
activate(clientID: number, attributeID?: number): void;
rotate(rotation: Rotation, remember?: boolean): void;
rotate(frameAngle: number): void;
focus(clientID: number, padding?: number): void;
fit(): void;
grid(stepX: number, stepY: number): void;
Expand Down Expand Up @@ -147,7 +142,7 @@ Standard JS events are used.
canvas.fitCanvas();

// Next you can use its API methods. For example:
canvas.rotate(window.Canvas.Rotation.CLOCKWISE90);
canvas.rotate(270);
canvas.draw({
enabled: true,
shapeType: 'rectangle',
Expand Down
8 changes: 3 additions & 5 deletions cvat-canvas/src/typescript/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// SPDX-License-Identifier: MIT

import {
Rotation,
DrawData,
MergeData,
SplitData,
Expand Down Expand Up @@ -37,7 +36,7 @@ interface Canvas {
setZLayer(zLayer: number | null): void;
setup(frameData: any, objectStates: any[]): void;
activate(clientID: number | null, attributeID?: number): void;
rotate(rotation: Rotation, remember?: boolean): void;
rotate(rotationAngle: number): void;
focus(clientID: number, padding?: number): void;
fit(): void;
grid(stepX: number, stepY: number): void;
Expand Down Expand Up @@ -97,8 +96,8 @@ class CanvasImpl implements Canvas {
this.model.activate(clientID, attributeID);
}

public rotate(rotation: Rotation, remember: boolean = false): void {
this.model.rotate(rotation, remember);
public rotate(rotationAngle: number): void {
this.model.rotate(rotationAngle);
}

public focus(clientID: number, padding: number = 0): void {
Expand Down Expand Up @@ -140,7 +139,6 @@ class CanvasImpl implements Canvas {

export {
CanvasImpl as Canvas,
Rotation,
CanvasVersion,
RectDrawingMethod,
};
26 changes: 5 additions & 21 deletions cvat-canvas/src/typescript/canvasModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ export enum FrameZoom {
MAX = 10,
}

export enum Rotation {
ANTICLOCKWISE90,
CLOCKWISE90,
}

export enum UpdateReasons {
IMAGE_CHANGED = 'image_changed',
IMAGE_ZOOMED = 'image_zoomed',
Expand Down Expand Up @@ -135,7 +130,7 @@ export interface CanvasModel {

setup(frameData: any, objectStates: any[]): void;
activate(clientID: number | null, attributeID: number | null): void;
rotate(rotation: Rotation, remember: boolean): void;
rotate(rotationAngle: number): void;
focus(clientID: number, padding: number): void;
fit(): void;
grid(stepX: number, stepY: number): void;
Expand Down Expand Up @@ -166,7 +161,6 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
gridSize: Size;
left: number;
objects: any[];
rememberAngle: boolean;
scale: number;
top: number;
zLayer: number | null;
Expand Down Expand Up @@ -208,7 +202,6 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
},
left: 0,
objects: [],
rememberAngle: false,
scale: 1,
top: 0,
zLayer: null,
Expand Down Expand Up @@ -323,10 +316,6 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
return;
}

if (!this.data.rememberAngle) {
this.data.angle = 0;
}

this.data.imageSize = {
height: (frameData.height as number),
width: (frameData.width as number),
Expand Down Expand Up @@ -355,16 +344,11 @@ export class CanvasModelImpl extends MasterImpl implements CanvasModel {
this.notify(UpdateReasons.SHAPE_ACTIVATED);
}

public rotate(rotation: Rotation, remember: boolean = false): void {
if (rotation === Rotation.CLOCKWISE90) {
this.data.angle += 90;
} else {
this.data.angle -= 90;
public rotate(rotationAngle: number): void {
if (this.data.angle !== rotationAngle) {
this.data.angle = (360 + Math.floor((rotationAngle) / 90) * 90) % 360;
this.fit();
}

this.data.angle %= 360;
this.data.rememberAngle = remember;
this.fit();
}

public focus(clientID: number, padding: number): void {
Expand Down
23 changes: 23 additions & 0 deletions cvat-ui/src/actions/annotation-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
ObjectType,
Task,
FrameSpeed,
Rotation,
} from 'reducers/interfaces';

import getCore from 'cvat-core';
Expand Down Expand Up @@ -129,6 +130,7 @@ export enum AnnotationActionTypes {
CHANGE_ANNOTATIONS_FILTERS = 'CHANGE_ANNOTATIONS_FILTERS',
FETCH_ANNOTATIONS_SUCCESS = 'FETCH_ANNOTATIONS_SUCCESS',
FETCH_ANNOTATIONS_FAILED = 'FETCH_ANNOTATIONS_FAILED',
ROTATE_FRAME = 'ROTATE_FRAME',
SWITCH_Z_LAYER = 'SWITCH_Z_LAYER',
ADD_Z_LAYER = 'ADD_Z_LAYER',
}
Expand Down Expand Up @@ -666,6 +668,27 @@ ThunkAction<Promise<void>, {}, {}, AnyAction> {
};
}


export function rotateCurrentFrame(rotation: Rotation): AnyAction {
const state: CombinedState = getStore().getState();
const { number: frameNumber } = state.annotation.player.frame;
const { startFrame } = state.annotation.job.instance;
const { frameAngles } = state.annotation.player;
const { rotateAll } = state.settings.player;

const frameAngle = (frameAngles[frameNumber - startFrame]
+ (rotation === Rotation.CLOCKWISE90 ? 90 : 270)) % 360;

return {
type: AnnotationActionTypes.ROTATE_FRAME,
payload: {
offset: frameNumber - state.annotation.job.instance.startFrame,
angle: frameAngle,
rotateAll,
},
};
}

export function dragCanvas(enabled: boolean): AnyAction {
return {
type: AnnotationActionTypes.DRAG_CANVAS,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ interface Props {
selectedStatesID: number[];
annotations: any[];
frameData: any;
frameAngle: number;
frame: number;
opacity: number;
colorBy: ColorBy;
Expand Down Expand Up @@ -101,6 +102,7 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
selectedOpacity,
blackBorders,
frameData,
frameAngle,
annotations,
canvasInstance,
sidebarCollapsed,
Expand Down Expand Up @@ -149,6 +151,10 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
canvasInstance.setZLayer(curZLayer);
}

if (prevProps.frameAngle !== frameAngle) {
canvasInstance.rotate(frameAngle);
}

this.activateOnCanvas();
}

Expand Down Expand Up @@ -305,11 +311,13 @@ export default class CanvasWrapperComponent extends React.PureComponent<Props> {
const {
annotations,
frameData,
frameAngle,
canvasInstance,
} = this.props;

if (frameData !== null) {
canvasInstance.setup(frameData, annotations);
canvasInstance.rotate(frameAngle);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {

import {
ActiveControl,
Rotation
} from 'reducers/interfaces';

import {
Expand All @@ -22,9 +23,9 @@ import {
Canvas,
} from 'cvat-canvas';

import RotateControl from './rotate-control';
import CursorControl from './cursor-control';
import MoveControl from './move-control';
import RotateControl from './rotate-control';
import FitControl from './fit-control';
import ResizeControl from './resize-control';
import DrawRectangleControl from './draw-rectangle-control';
Expand All @@ -37,23 +38,23 @@ import SplitControl from './split-control';

interface Props {
canvasInstance: Canvas;
rotateAll: boolean;
activeControl: ActiveControl;

mergeObjects(enabled: boolean): void;
groupObjects(enabled: boolean): void;
splitTrack(enabled: boolean): void;
rotateFrame(rotation: Rotation): void;
}

export default function ControlsSideBarComponent(props: Props): JSX.Element {
const {
canvasInstance,
activeControl,
rotateAll,

mergeObjects,
groupObjects,
splitTrack,
rotateFrame,
} = props;

return (
Expand All @@ -64,7 +65,7 @@ export default function ControlsSideBarComponent(props: Props): JSX.Element {
>
<CursorControl canvasInstance={canvasInstance} activeControl={activeControl} />
<MoveControl canvasInstance={canvasInstance} activeControl={activeControl} />
<RotateControl canvasInstance={canvasInstance} rotateAll={rotateAll} />
<RotateControl rotateFrame={rotateFrame} />

<hr />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,15 @@ import {

import {
Rotation,
Canvas,
} from 'cvat-canvas';
} from 'reducers/interfaces';

interface Props {
canvasInstance: Canvas;
rotateAll: boolean;
rotateFrame(rotation: Rotation): void;
}

function RotateControl(props: Props): JSX.Element {
const {
rotateAll,
canvasInstance,
rotateFrame,
} = props;

return (
Expand All @@ -39,16 +36,14 @@ function RotateControl(props: Props): JSX.Element {
<Tooltip title='Rotate the image anticlockwise' placement='topRight'>
<Icon
className='cvat-rotate-canvas-controls-left'
onClick={(): void => canvasInstance
.rotate(Rotation.ANTICLOCKWISE90, rotateAll)}
onClick={(): void => rotateFrame(Rotation.ANTICLOCKWISE90)}
component={RotateIcon}
/>
</Tooltip>
<Tooltip title='Rotate the image clockwise' placement='topRight'>
<Icon
className='cvat-rotate-canvas-controls-right'
onClick={(): void => canvasInstance
.rotate(Rotation.CLOCKWISE90, rotateAll)}
onClick={(): void => rotateFrame(Rotation.CLOCKWISE90)}
component={RotateIcon}
/>
</Tooltip>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface StateToProps {
selectedStatesID: number[];
annotations: any[];
frameData: any;
frameAngle: number;
frame: number;
opacity: number;
colorBy: ColorBy;
Expand Down Expand Up @@ -105,6 +106,7 @@ function mapStateToProps(state: CombinedState): StateToProps {
data: frameData,
number: frame,
},
frameAngles,
},
annotations: {
states: annotations,
Expand Down Expand Up @@ -143,6 +145,7 @@ function mapStateToProps(state: CombinedState): StateToProps {
canvasInstance,
jobInstance,
frameData,
frameAngle: frameAngles[frame - jobInstance.startFrame],
frame,
activatedStateID,
selectedStatesID,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ import {
mergeObjects,
groupObjects,
splitTrack,
rotateCurrentFrame,
} from 'actions/annotation-actions';
import ControlsSideBarComponent from 'components/annotation-page/standard-workspace/controls-side-bar/controls-side-bar';
import {
ActiveControl,
CombinedState,
Rotation,
} from 'reducers/interfaces';

interface StateToProps {
Expand All @@ -28,6 +30,7 @@ interface DispatchToProps {
mergeObjects(enabled: boolean): void;
groupObjects(enabled: boolean): void;
splitTrack(enabled: boolean): void;
rotateFrame(angle: Rotation): void;
}

function mapStateToProps(state: CombinedState): StateToProps {
Expand Down Expand Up @@ -63,6 +66,9 @@ function dispatchToProps(dispatch: any): DispatchToProps {
splitTrack(enabled: boolean): void {
dispatch(splitTrack(enabled));
},
rotateFrame(rotation: Rotation): void {
dispatch(rotateCurrentFrame(rotation));
},
};
}

Expand Down
2 changes: 0 additions & 2 deletions cvat-ui/src/cvat-canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@

import {
Canvas,
Rotation,
CanvasVersion,
RectDrawingMethod,
} from '../../cvat-canvas/src/typescript/canvas';

export {
Canvas,
Rotation,
CanvasVersion,
RectDrawingMethod,
};
Loading