123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- import React, { useEffect, useState } from 'react';
- import useCursorPosition from '../../hooks/useCursorPosition';
- import { getAbsoluteCoordinate } from '../../helpers/position';
- import theme from '../../helpers/theme';
- import { SVG, Circle } from './styled';
- type Props = LinePositionType & {
- top: number;
- left: number;
- width: number;
- height: number;
- onMove: (position: LinePositionType) => void;
- onClick?: (event: React.MouseEvent) => void;
- onMouseUp: () => void;
- };
- const MARGIN_DISTANCE = 10;
- const initState = {
- start: { x: 0, y: 0 },
- end: { x: 0, y: 0 },
- operator: '',
- clickX: 0,
- clickY: 0,
- };
- const index: React.FC<Props> = ({
- top,
- left,
- width,
- height,
- start,
- end,
- onMove,
- onClick,
- onMouseUp,
- }: Props) => {
- const [state, setState] = useState(initState);
- const [cursorPosition, setRef] = useCursorPosition(25);
- const handleMouseDown = (e: React.MouseEvent): void => {
- const operatorId = (e.target as HTMLElement).getAttribute(
- 'data-id',
- ) as string;
- const coord = getAbsoluteCoordinate(document.body, e);
- setRef(document.body);
- setState({
- start,
- end,
- operator: operatorId,
- clickX: coord.x,
- clickY: coord.y,
- });
- };
- const handleMouseUp = (): void => {
- setRef(null);
- setState(initState);
- onMouseUp();
- };
- useEffect(() => {
- if (cursorPosition.x && cursorPosition.y) {
- if (state.operator === 'start') {
- const x1 = cursorPosition.x - (state.clickX - state.start.x);
- const y1 = cursorPosition.y - (state.clickY - state.start.y);
- onMove({
- start: { x: x1, y: y1 },
- end,
- });
- } else if (state.operator === 'end') {
- const x2 = cursorPosition.x - (state.clickX - state.end.x);
- const y2 = cursorPosition.y - (state.clickY - state.end.y);
- onMove({
- start,
- end: { x: x2, y: y2 },
- });
- } else if (state.operator === 'move') {
- const x1 = cursorPosition.x - (state.clickX - state.start.x);
- const y1 = cursorPosition.y - (state.clickY - state.start.y);
- const x2 = cursorPosition.x - (state.clickX - state.end.x);
- const y2 = cursorPosition.y - (state.clickY - state.end.y);
- onMove({
- start: { x: x1, y: y1 },
- end: { x: x2, y: y2 },
- });
- }
- }
- }, [cursorPosition, state]);
- useEffect(() => {
- window.addEventListener('mouseup', handleMouseUp);
- return (): void => {
- window.removeEventListener('mouseup', handleMouseUp);
- };
- }, []);
- return (
- <SVG
- data-id="move"
- viewBox={`${left} ${top} ${width + MARGIN_DISTANCE}
- ${height + MARGIN_DISTANCE}`}
- style={{
- left: `${left - MARGIN_DISTANCE}px`,
- top: `${top - MARGIN_DISTANCE}px`,
- width: `${width + MARGIN_DISTANCE}px`,
- height: `${height + MARGIN_DISTANCE}px`,
- }}
- onClick={onClick}
- onMouseDown={handleMouseDown}
- >
- <Circle
- data-id="start"
- onMouseDown={handleMouseDown}
- fill={theme.colors.primary}
- cx={start.x + MARGIN_DISTANCE}
- cy={start.y + MARGIN_DISTANCE}
- r={6}
- />
- <Circle
- data-id="end"
- onMouseDown={handleMouseDown}
- fill={theme.colors.primary}
- cx={end.x + MARGIN_DISTANCE}
- cy={end.y + MARGIN_DISTANCE}
- r={6}
- />
- </SVG>
- );
- };
- export default index;
|