{showInput && (
{inputElement(
inputComment,
this.onInputCommentChange,
this.onDelete
)}
)}
);
}
public setAnnotationState = (annotationState: IAnnotationState) => {
this.currentAnnotationState = annotationState;
};
public onShapeChange = () => {
if (this.canvas2D && this.canvasRef.current) {
this.canvas2D.clearRect(
0,
0,
this.canvasRef.current.width,
this.canvasRef.current.height
);
let hasSelectedItem = false;
for (const item of this.shapes) {
const isSelected = item.getAnnotationData().id === this.selectedId;
const { x, y, height } = item.paint(
this.canvas2D,
this.calculateShapePosition,
isSelected
);
if (isSelected) {
if (!this.currentTransformer) {
this.currentTransformer = new Transformer(
item,
this.scaleState.scale
);
}
hasSelectedItem = true;
this.currentTransformer.paint(
this.canvas2D,
this.calculateShapePosition,
this.scaleState.scale
);
this.setState({
showInput: true,
inputPosition: {
left: x,
top: y + height + this.props.marginWithInput,
},
inputComment: item.getAnnotationData().comment || "",
});
}
}
if (!hasSelectedItem) {
this.setState({
showInput: false,
inputComment: "",
});
}
}
this.currentAnnotationData = this.shapes.map((item) =>
item.getAnnotationData()
);
const { onChange } = this.props;
onChange(this.currentAnnotationData);
};
private syncAnnotationData = () => {
const { annotationData } = this.props;
if (annotationData) {
const refreshShapesWithAnnotationData = () => {
this.selectedId = null;
this.shapes = annotationData.map(
(eachAnnotationData) =>
new RectShape(
eachAnnotationData,
this.onShapeChange,
this.annotationStyle
)
);
this.onShapeChange();
};
if (annotationData.length !== this.shapes.length) {
refreshShapesWithAnnotationData();
} else {
for (const annotationDataItem of annotationData) {
const targetShape = this.shapes.find(
(item) => item.getAnnotationData().id === annotationDataItem.id
);
if (targetShape && targetShape.equal(annotationDataItem)) {
continue;
} else {
refreshShapesWithAnnotationData();
break;
}
}
}
}
};
private syncSelectedId = () => {
const { selectedId } = this.props;
if (selectedId && selectedId !== this.selectedId) {
this.selectedId = selectedId;
this.onShapeChange();
}
};
private onDelete = () => {
const deleteTarget = this.shapes.findIndex(
(shape) => shape.getAnnotationData().id === this.selectedId
);
if (deleteTarget >= 0) {
this.shapes.splice(deleteTarget, 1);
this.onShapeChange();
}
};
private setCanvasDPI = () => {
const currentCanvas = this.canvasRef.current;
const currentImageCanvas = this.imageCanvasRef.current;
if (currentCanvas && currentImageCanvas) {
const currentCanvas2D = currentCanvas.getContext("2d");
const currentImageCanvas2D = currentImageCanvas.getContext("2d");
if (currentCanvas2D && currentImageCanvas2D) {
currentCanvas2D.scale(2, 2);
currentImageCanvas2D.scale(2, 2);
}
}
};
private onInputCommentChange = (comment: string) => {
const selectedShapeIndex = this.shapes.findIndex(
(item) => item.getAnnotationData().id === this.selectedId
);
this.shapes[selectedShapeIndex].setComment(comment);
this.setState({ inputComment: comment });
};
private cleanImage = () => {
if (this.imageCanvas2D && this.imageCanvasRef.current) {
this.imageCanvas2D.clearRect(
0,
0,
this.imageCanvasRef.current.width,
this.imageCanvasRef.current.height
);
}
};
private onImageChange = () => {
this.cleanImage();
if (this.imageCanvas2D && this.imageCanvasRef.current) {
if (this.currentImageElement) {
const { originX, originY, scale } = this.scaleState;
this.imageCanvas2D.drawImage(
this.currentImageElement,
originX,
originY,
this.currentImageElement.width * scale,
this.currentImageElement.height * scale
);
} else {
const nextImageNode = document.createElement("img");
nextImageNode.addEventListener("load", () => {
this.currentImageElement = nextImageNode;
const { width, height } = nextImageNode;
const imageNodeRatio = height / width;
const { width: canvasWidth, height: canvasHeight } = this.props;
const canvasNodeRatio = canvasHeight / canvasWidth;
if (!isNaN(imageNodeRatio) && !isNaN(canvasNodeRatio)) {
if (imageNodeRatio < canvasNodeRatio) {
const scale = canvasWidth / width;
this.scaleState = {
originX: 0,
originY: (canvasHeight - scale * height) / 2,
scale,
};
} else {
const scale = canvasHeight / height;
this.scaleState = {
originX: (canvasWidth - scale * width) / 2,
originY: 0,
scale,
};
}
}
this.onImageChange();
this.onShapeChange();
});
nextImageNode.alt = "";
nextImageNode.src = this.props.image;
}
}
};
private onMouseDown: MouseEventHandler