|
@@ -1,137 +1,154 @@
|
|
|
-import React from 'react';
|
|
|
+import React, { useState, useEffect } from 'react';
|
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
|
|
import Outer from '../OuterRectForLine';
|
|
|
import { parsePositionForBackend } from '../../helpers/position';
|
|
|
+
|
|
|
import { AnnotationContainer } from '../../global/otherStyled';
|
|
|
|
|
|
-const Note: React.SFC<AnnotationElementPropsType> = ({
|
|
|
+import { SVG } from './styled';
|
|
|
+
|
|
|
+const getActualPoint = (
|
|
|
+ { start, end }: LinePositionType,
|
|
|
+ h: number,
|
|
|
+ s: number,
|
|
|
+): LinePositionType => {
|
|
|
+ const x1 = start.x * s;
|
|
|
+ const y1 = h - start.y * s;
|
|
|
+ const x2 = end.x * s;
|
|
|
+ const y2 = h - end.y * s;
|
|
|
+ return {
|
|
|
+ start: {
|
|
|
+ x: x1,
|
|
|
+ y: y1,
|
|
|
+ },
|
|
|
+ end: {
|
|
|
+ x: x2,
|
|
|
+ y: y2,
|
|
|
+ },
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+const rectCalc = ({ start, end }: LinePositionType): HTMLCoordinateType => {
|
|
|
+ return {
|
|
|
+ top: start.y < end.y ? start.y : end.y,
|
|
|
+ left: start.x < end.x ? start.x : end.x,
|
|
|
+ width: Math.abs(end.x - start.x),
|
|
|
+ height: Math.abs(end.y - start.y),
|
|
|
+ };
|
|
|
+};
|
|
|
+
|
|
|
+const Line: React.FC<AnnotationElementPropsType> = ({
|
|
|
id,
|
|
|
obj_type,
|
|
|
- obj_attr,
|
|
|
+ obj_attr: { bdcolor = '', bdwidth = 0, transparency = 0, position, is_arrow },
|
|
|
scale,
|
|
|
viewport,
|
|
|
isCollapse,
|
|
|
onUpdate,
|
|
|
}: AnnotationElementPropsType) => {
|
|
|
- const {
|
|
|
- bdcolor = '',
|
|
|
- bdwidth = 0,
|
|
|
- transparency = 0,
|
|
|
- position,
|
|
|
- is_arrow,
|
|
|
- } = obj_attr;
|
|
|
+ const [startPoint, setStartPoint] = useState({ x: 0, y: 0 });
|
|
|
+ const [endPoint, setEndPoint] = useState({ x: 0, y: 0 });
|
|
|
+ const [rect, setRect] = useState({ top: 0, left: 0, width: 0, height: 0 });
|
|
|
+ const [moving, setMoving] = useState(false);
|
|
|
const uuid = uuidv4();
|
|
|
|
|
|
- const getActualPoint = (
|
|
|
- { start, end }: LinePositionType,
|
|
|
- h: number,
|
|
|
- s: number,
|
|
|
- ): LinePositionType => {
|
|
|
- const x1 = start.x * scale;
|
|
|
- const y1 = h - start.y * s;
|
|
|
- const x2 = end.x * scale;
|
|
|
- const y2 = h - end.y * s;
|
|
|
- return {
|
|
|
- start: {
|
|
|
- x: x1,
|
|
|
- y: y1,
|
|
|
- },
|
|
|
- end: {
|
|
|
- x: x2,
|
|
|
- y: y2,
|
|
|
- },
|
|
|
- };
|
|
|
- };
|
|
|
-
|
|
|
- const pointCalc = (
|
|
|
- { start, end }: LinePositionType,
|
|
|
- borderWidth: number,
|
|
|
- ): LinePositionType => ({
|
|
|
- start: {
|
|
|
- x: start.x + borderWidth,
|
|
|
- y: start.y + borderWidth,
|
|
|
- },
|
|
|
- end: {
|
|
|
- x: end.x + borderWidth,
|
|
|
- y: end.y + borderWidth,
|
|
|
- },
|
|
|
- });
|
|
|
-
|
|
|
- const rectCalc = (
|
|
|
- { start, end }: LinePositionType,
|
|
|
- h: number,
|
|
|
- s: number,
|
|
|
- ): HTMLCoordinateType => {
|
|
|
- const startY = h - start.y * s;
|
|
|
- const endY = h - end.y * s;
|
|
|
-
|
|
|
- return {
|
|
|
- top: startY > endY ? endY : startY,
|
|
|
- left: start.x > end.x ? end.x * s : start.x * s,
|
|
|
- width: Math.abs((end.x - start.x) * s),
|
|
|
- height: Math.abs(endY - startY),
|
|
|
- };
|
|
|
- };
|
|
|
-
|
|
|
const actualbdwidth = bdwidth * scale;
|
|
|
- const annotRect = rectCalc(
|
|
|
- position as LinePositionType,
|
|
|
- viewport.height,
|
|
|
- scale,
|
|
|
- );
|
|
|
- const { start, end } = getActualPoint(
|
|
|
- position as LinePositionType,
|
|
|
- viewport.height,
|
|
|
- scale,
|
|
|
- );
|
|
|
- const { start: completeStart, end: completeEnd } = pointCalc(
|
|
|
- { start, end } as LinePositionType,
|
|
|
- actualbdwidth,
|
|
|
- );
|
|
|
-
|
|
|
- const actualWidth = annotRect.width + actualbdwidth + 15;
|
|
|
- const actualHeight = annotRect.height + actualbdwidth + 15;
|
|
|
|
|
|
const handleMove = ({
|
|
|
start: moveStart,
|
|
|
end: moveEnd,
|
|
|
}: LinePositionType): void => {
|
|
|
- const newPosition = {
|
|
|
- start: {
|
|
|
- x: moveStart.x,
|
|
|
- y: moveStart.y,
|
|
|
- },
|
|
|
- end: {
|
|
|
- x: moveEnd.x,
|
|
|
- y: moveEnd.y,
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
- onUpdate({
|
|
|
- position: parsePositionForBackend(
|
|
|
- obj_type,
|
|
|
- newPosition,
|
|
|
- viewport.height,
|
|
|
- scale,
|
|
|
- ),
|
|
|
- });
|
|
|
+ setMoving(true);
|
|
|
+ setStartPoint(moveStart);
|
|
|
+ setEndPoint(moveEnd);
|
|
|
+
|
|
|
+ const newRect = rectCalc({ start: moveStart, end: moveEnd });
|
|
|
+
|
|
|
+ if (is_arrow) {
|
|
|
+ setRect({
|
|
|
+ top: newRect.top - actualbdwidth * 2,
|
|
|
+ left: newRect.left - actualbdwidth * 2,
|
|
|
+ width: newRect.width + actualbdwidth * 4,
|
|
|
+ height: newRect.height + actualbdwidth * 4,
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ setRect({
|
|
|
+ top: newRect.top - actualbdwidth / 2,
|
|
|
+ left: newRect.left - actualbdwidth / 2,
|
|
|
+ width: newRect.width + actualbdwidth,
|
|
|
+ height: newRect.height + actualbdwidth,
|
|
|
+ });
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
+ const handleMouseUp = () => {
|
|
|
+ setMoving(false);
|
|
|
+ };
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ if (!moving && startPoint.x) {
|
|
|
+ const newPosition = {
|
|
|
+ start: {
|
|
|
+ x: startPoint.x,
|
|
|
+ y: startPoint.y,
|
|
|
+ },
|
|
|
+ end: {
|
|
|
+ x: endPoint.x,
|
|
|
+ y: endPoint.y,
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ onUpdate({
|
|
|
+ position: parsePositionForBackend(
|
|
|
+ obj_type,
|
|
|
+ newPosition,
|
|
|
+ viewport.height,
|
|
|
+ scale,
|
|
|
+ ),
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }, [moving, startPoint, endPoint]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ const { start, end } = getActualPoint(
|
|
|
+ position as LinePositionType,
|
|
|
+ viewport.height,
|
|
|
+ scale,
|
|
|
+ );
|
|
|
+
|
|
|
+ setStartPoint(start);
|
|
|
+ setEndPoint(end);
|
|
|
+
|
|
|
+ const initRect = rectCalc({ start, end });
|
|
|
+
|
|
|
+ if (is_arrow) {
|
|
|
+ setRect({
|
|
|
+ top: initRect.top - actualbdwidth * 2,
|
|
|
+ left: initRect.left - actualbdwidth * 2,
|
|
|
+ width: initRect.width + actualbdwidth * 4,
|
|
|
+ height: initRect.height + actualbdwidth * 4,
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ setRect({
|
|
|
+ top: initRect.top - actualbdwidth / 2,
|
|
|
+ left: initRect.left - actualbdwidth / 2,
|
|
|
+ width: initRect.width + actualbdwidth,
|
|
|
+ height: initRect.height + actualbdwidth,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }, [viewport, scale]);
|
|
|
+
|
|
|
return (
|
|
|
<>
|
|
|
<AnnotationContainer
|
|
|
id={id}
|
|
|
- top={`${annotRect.top}px`}
|
|
|
- left={`${annotRect.left}px`}
|
|
|
- width={`${actualWidth}px`}
|
|
|
- height={`${actualHeight}px`}
|
|
|
+ top={`${rect.top}px`}
|
|
|
+ left={`${rect.left}px`}
|
|
|
+ width={`${rect.width}px`}
|
|
|
+ height={`${rect.height}px`}
|
|
|
>
|
|
|
- <svg
|
|
|
- width={`${actualWidth}px`}
|
|
|
- height={`${actualHeight}px`}
|
|
|
- viewBox={`${annotRect.left} ${annotRect.top} ${actualWidth} ${actualHeight}`}
|
|
|
- >
|
|
|
+ <SVG viewBox={`${rect.left} ${rect.top} ${rect.width} ${rect.height}`}>
|
|
|
{is_arrow ? (
|
|
|
<defs>
|
|
|
<marker
|
|
@@ -154,28 +171,27 @@ const Note: React.SFC<AnnotationElementPropsType> = ({
|
|
|
</defs>
|
|
|
) : null}
|
|
|
<line
|
|
|
- x1={completeStart.x}
|
|
|
- y1={completeStart.y}
|
|
|
- x2={completeEnd.x}
|
|
|
- y2={completeEnd.y}
|
|
|
+ x1={startPoint.x}
|
|
|
+ y1={startPoint.y}
|
|
|
+ x2={endPoint.x}
|
|
|
+ y2={endPoint.y}
|
|
|
stroke={bdcolor}
|
|
|
strokeWidth={actualbdwidth}
|
|
|
strokeOpacity={transparency}
|
|
|
markerEnd={is_arrow ? `url(#${uuid})` : ''}
|
|
|
/>
|
|
|
- </svg>
|
|
|
+ </SVG>
|
|
|
</AnnotationContainer>
|
|
|
{!isCollapse ? (
|
|
|
<Outer
|
|
|
- top={annotRect.top}
|
|
|
- left={annotRect.left}
|
|
|
- width={actualWidth}
|
|
|
- height={actualHeight}
|
|
|
- start={start}
|
|
|
- end={end}
|
|
|
- completeStart={completeStart}
|
|
|
- completeEnd={completeEnd}
|
|
|
+ top={rect.top}
|
|
|
+ left={rect.left}
|
|
|
+ width={rect.width}
|
|
|
+ height={rect.height}
|
|
|
+ start={startPoint}
|
|
|
+ end={endPoint}
|
|
|
onMove={handleMove}
|
|
|
+ onMouseUp={handleMouseUp}
|
|
|
/>
|
|
|
) : (
|
|
|
''
|
|
@@ -184,4 +200,4 @@ const Note: React.SFC<AnnotationElementPropsType> = ({
|
|
|
);
|
|
|
};
|
|
|
|
|
|
-export default Note;
|
|
|
+export default Line;
|