123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- 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';
- 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: { bdcolor = '', bdwidth = 0, transparency = 0, position, is_arrow },
- scale,
- viewport,
- isCollapse,
- onUpdate,
- }: AnnotationElementPropsType) => {
- 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 actualbdwidth = bdwidth * scale;
- const handleMove = ({
- start: moveStart,
- end: moveEnd,
- }: LinePositionType): void => {
- 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={`${rect.top}px`}
- left={`${rect.left}px`}
- width={`${rect.width}px`}
- height={`${rect.height}px`}
- >
- <SVG
- width={rect.width}
- height={rect.height}
- viewBox={`${rect.left} ${rect.top} ${rect.width} ${rect.height}`}
- >
- {is_arrow ? (
- <defs>
- <marker
- id={uuid}
- markerWidth={actualbdwidth * 2}
- markerHeight={actualbdwidth * 3}
- refX={3}
- refY={2}
- orient="auto"
- markerUnits="strokeWidth"
- >
- <polyline
- points="0.25,0.5 3.25,2 0.25,3.5 3.25,2 -0.25,2"
- stroke={bdcolor}
- strokeWidth={1}
- fill="none"
- strokeDasharray={100}
- />
- </marker>
- </defs>
- ) : null}
- <line
- x1={startPoint.x}
- y1={startPoint.y}
- x2={endPoint.x}
- y2={endPoint.y}
- stroke={bdcolor}
- strokeWidth={actualbdwidth}
- strokeOpacity={transparency}
- markerEnd={is_arrow ? `url(#${uuid})` : ''}
- />
- </SVG>
- </AnnotationContainer>
- {!isCollapse ? (
- <Outer
- top={rect.top}
- left={rect.left}
- width={rect.width}
- height={rect.height}
- start={startPoint}
- end={endPoint}
- onMove={handleMove}
- onMouseUp={handleMouseUp}
- />
- ) : (
- ''
- )}
- </>
- );
- };
- export default Line;
|