UNPKG

lost-sia

Version:

Single Image Annotation Tool

283 lines (261 loc) 6.2 kB
import React, { Component } from "react"; import "./Annotation.scss"; import * as modes from "../types/modes"; import * as cursorstyles from "../types/cursorstyles"; class Node extends Component { /************* * LIFECYCLE * **************/ constructor(props) { super(props); this.state = { haloCss: "node-halo-off", selAreaCss: "sel-area-off", // anno: undefined, nodeSelected: false, style: {}, }; } componentDidMount() { this.setState({ // anno: this.props.anno, style: { ...this.props.style, cursor: this.getCursorStyle(this.props.mode), }, }); // switch (this.props.mode){ // case modes.CREATE: // if (this.props.idx !== 0){ // this.turnSelAreaOn() // } // default: // break // } } componentDidUpdate(prevProps) { switch (this.props.mode) { case modes.CREATE: if (this.props.idx !== 0 || this.props.isPoint) { this.turnSelAreaOn(); } break; case modes.EDIT: this.turnSelAreaOn(); break; default: break; } //on mode change if (prevProps.mode !== this.props.mode) { this.setState({ style: { ...this.state.style, cursor: this.getCursorStyle(this.props.mode), }, }); } if (prevProps.style !== this.props.style) { this.setState({ style: { ...this.state.style, ...this.props.style, cursor: this.getCursorStyle(this.props.mode), }, }); } } /************* * EVENTS * **************/ onClick(e) { this.turnHaloOn(); if (this.props.onClick) { this.props.onClick(e, this.props.idx); } } onMouseMove(e) { if (this.props.onMouseMove) { this.props.onMouseMove(e, this.props.idx); } // switch (this.props.mode){ // case modes.CREATE: // let newAnno = [...this.state.anno] // const mousePos = mouse.getMousePosition(e, this.props.svg) // newAnno[this.props.idx].x = mousePos.x // newAnno[this.props.idx].y = mousePos.y // this.setState({ // anno: newAnno // }) // if (this.props.onAnnoUpdate){ // this.props.onAnnoUpdate(e, this.props.idx, newAnno) // } // default: // break // } } onContextMenu(e) { e.preventDefault(); } onMouseUp(e) { switch (this.props.mode) { case modes.EDIT: switch (e.button) { case 0: this.turnSelAreaOff(); break; default: break; } break; default: break; } if (this.props.onMouseUp) { this.props.onMouseUp(e, this.props.idx); } } onMouseDown(e) { e.stopPropagation(); if (this.props.onMouseDown) { this.props.onMouseDown(e, this.props.idx); } switch (this.props.mode) { case modes.CREATE: switch (e.button) { case 0: this.turnSelAreaOff(); break; case 2: this.turnSelAreaOff(); break; default: break; } // case modes.EDIT: // switch (e.button){ // case 0: // this.turnSelAreaOn() // break // default: // break // } break; default: break; } } onMouseOver(e) { if (this.props.isSelected) { this.turnHaloOn(); } } onMouseLeave(e) { if (this.props.isSelected) { this.turnHaloOff(); } } onDoubleClick(e) { if (this.props.onDoubleClick) { this.props.onDoubleClick(e, this.props.idx); } } handleMouseLeave(e) { if (this.props.onMouseLeave) { this.props.onMouseLeave(e, this.props.idx); } } /************* * LOGIC * **************/ getCursorStyle(mode) { switch (mode) { case modes.CREATE: return cursorstyles.CREATE_NODE; case modes.EDIT: return cursorstyles.EDIT_NODE; case modes.VIEW: return cursorstyles.NORMAL_NODE; default: break; } } turnSelAreaOn() { if (this.state.selAreaCss !== "sel-area-on") { this.setState({ selAreaCss: "sel-area-on", }); } } turnSelAreaOff() { if (this.state.selAreaCss !== "sel-area-off") { this.setState({ selAreaCss: "sel-area-off", }); } } turnHaloOn() { this.setState({ haloCss: "node-halo-on", }); } turnHaloOff() { this.setState({ haloCss: "node-halo-off", }); } /************* * RENDERING * **************/ renderHalo() { if (this.state.haloCss === "node-halo-off") return null; const data = this.props.anno[this.props.idx]; return ( <circle cx={data.x} cy={data.y} r={this.props.style.r * 3} className={this.state.haloCss} onMouseLeave={(e) => this.onMouseLeave(e)} /> ); } renderNodes() { const data = this.props.anno[this.props.idx]; if (data === undefined) { return; } return ( <g onClick={(e) => this.onClick(e)} onMouseMove={(e) => this.onMouseMove(e)} onContextMenu={(e) => this.onContextMenu(e)} onMouseUp={(e) => this.onMouseUp(e)} onMouseDown={(e) => this.onMouseDown(e)} onDoubleClick={(e) => this.onDoubleClick(e)} onMouseLeave={(e) => this.handleMouseLeave(e)} > <circle cx={data.x} cy={data.y} r={"100%"} className={this.state.selAreaCss} /> {this.renderHalo()} <circle cx={data.x} cy={data.y} r={3} fill="red" style={this.state.style} className={this.props.className} onMouseOver={(e) => this.onMouseOver(e)} /> </g> ); } render() { return <g>{this.renderNodes()}</g>; } } export default Node;