lost-sia
Version:
Single Image Annotation Tool
201 lines (184 loc) • 4.72 kB
JSX
import React, { Component } from "react";
import InfSelectionArea from "./InfSelectionArea";
import Node from "./Node";
import * as modes from "../types/modes";
import * as transform from "../utils/transform";
import * as canvasActions from "../types/canvasActions";
class Point extends Component {
/*************
* LIFECYCLE *
**************/
constructor(props) {
super(props);
this.state = {
anno: undefined,
};
}
componentDidMount(prevProps) {
if (this.props.anno.mode === modes.CREATE) {
const data = this.props.anno.data[0];
const newAnno = {
...this.props.anno,
data: [{ x: data.x, y: data.y }],
selectedNode: 0,
};
this.setState({
anno: newAnno,
});
} else {
this.setState({ anno: { ...this.props.anno } });
}
}
componentDidUpdate(prevProps) {
if (prevProps.anno !== this.props.anno) {
this.setState({ anno: { ...this.props.anno } });
}
}
/**************
* ANNO EVENTS *
***************/
onMouseMove(e) {
switch (this.state.anno.mode) {
case modes.MOVE:
this.move(
e.movementX / this.props.svg.scale,
e.movementY / this.props.svg.scale,
);
break;
default:
break;
}
}
onMouseUp(e) {
switch (this.state.anno.mode) {
case modes.MOVE:
if (e.button === 0) {
this.requestModeChange(this.state.anno, modes.VIEW);
this.performedAction(this.state.anno, canvasActions.ANNO_MOVED);
}
break;
case modes.CREATE:
this.requestModeChange(this.state.anno, modes.VIEW);
this.performedAction(this.state.anno, canvasActions.ANNO_CREATED);
break;
default:
break;
}
}
onNodeMouseDown(e, idx) {
switch (this.state.anno.mode) {
case modes.VIEW:
if (e.button === 0) {
if (this.props.isSelected) {
this.requestModeChange(this.state.anno, modes.MOVE);
}
}
break;
default:
break;
}
}
/*************
* LOGIC *
**************/
getResult() {
return this.state.anno;
}
performedAction(anno, pAction) {
if (this.props.onAction) {
this.props.onAction(anno, pAction);
}
}
requestModeChange(anno, mode) {
this.props.onModeChangeRequest(anno, mode);
}
move(movementX, movementY) {
this.setState({
anno: {
...this.state.anno,
data: transform.move(this.state.anno.data, movementX, movementY),
},
});
}
renderInfSelectionArea() {
switch (this.state.anno.mode) {
case modes.MOVE:
return <InfSelectionArea enable={true} svg={this.props.svg} />;
default:
return null;
}
}
renderNode() {
if (!this.props.isSelected) return null;
switch (this.state.anno.mode) {
case modes.EDIT_LABEL:
case modes.MOVE:
return null;
case modes.EDIT:
case modes.CREATE:
return (
<Node
anno={this.state.anno.data}
key={this.state.selectedNode}
idx={this.state.anno.selectedNode}
style={this.props.style}
className={this.props.className}
isSelected={this.props.isSelected}
mode={this.state.anno.mode}
svg={this.props.svg}
onMouseDown={(e, idx) => this.onNodeMouseDown(e, idx)}
isPoint={true}
/>
);
default:
return this.state.anno.data.map((e, idx) => {
return (
<Node
anno={this.state.anno.data}
idx={idx}
key={idx}
style={this.props.style}
className={this.props.className}
isSelected={this.props.isSelected}
mode={this.state.anno.mode}
svg={this.props.svg}
onMouseDown={(e, idx) => this.onNodeMouseDown(e, idx)}
isPoint={true}
/>
);
});
}
}
renderPoint() {
return this.state.anno.data.map((e, idx) => {
return (
<circle
key={idx}
cx={e.x}
cy={e.y}
r={10}
fill="red"
style={this.props.style}
className={this.props.className}
/>
);
});
}
render() {
if (this.state.anno) {
return (
<g
onMouseMove={(e) => this.onMouseMove(e)}
onMouseUp={(e) => this.onMouseUp(e)}
>
{this.renderPoint()}
{this.renderNode()}
{this.renderInfSelectionArea()}
</g>
);
} else {
return null;
}
}
}
export default Point;