|
@@ -6,8 +6,11 @@ import Button from '../components/Button';
|
|
|
import ExpansionPanel from '../components/ExpansionPanel';
|
|
|
import Icon from '../components/Icon';
|
|
|
import ShapeOption from '../components/ShapeOption';
|
|
|
-import { OptionPropsType } from '../constants/type';
|
|
|
-import { getAbsoluteCoordinate, parsePositionForBackend } from '../helpers/position';
|
|
|
+
|
|
|
+import {
|
|
|
+ getAbsoluteCoordinate,
|
|
|
+ parsePositionForBackend,
|
|
|
+} from '../helpers/position';
|
|
|
import { parseAnnotationObject } from '../helpers/annotation';
|
|
|
import useCursorPosition from '../hooks/useCursorPosition';
|
|
|
|
|
@@ -20,11 +23,7 @@ type Props = {
|
|
|
onClick: () => void;
|
|
|
};
|
|
|
|
|
|
-const Shape: React.FC<Props> = ({
|
|
|
- title,
|
|
|
- isActive,
|
|
|
- onClick,
|
|
|
-}: Props) => {
|
|
|
+const Shape: React.FC<Props> = ({ title, isActive, onClick }: Props) => {
|
|
|
const [startPosition, setStartPosition] = useState({ x: 0, y: 0 });
|
|
|
const [uuid, setUuid] = useState('');
|
|
|
const [data, setData] = useState({
|
|
@@ -46,7 +45,13 @@ const Shape: React.FC<Props> = ({
|
|
|
}));
|
|
|
};
|
|
|
|
|
|
- const convertPosition = (type: string, x1: number, y1: number, x2: number, y2: number): any => {
|
|
|
+ const convertPosition = (
|
|
|
+ type: string,
|
|
|
+ x1: number,
|
|
|
+ y1: number,
|
|
|
+ x2: number,
|
|
|
+ y2: number
|
|
|
+ ): any => {
|
|
|
switch (type) {
|
|
|
case 'Line':
|
|
|
return {
|
|
@@ -69,46 +74,55 @@ const Shape: React.FC<Props> = ({
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- const addShape = useCallback((
|
|
|
- pageEle: HTMLElement,
|
|
|
- event: MouseEvent | TouchEvent,
|
|
|
- attributes: OptionPropsType,
|
|
|
- ): void => {
|
|
|
- const {
|
|
|
- shape = '', type, opacity, color, width = 0,
|
|
|
- } = attributes;
|
|
|
- const pageNum = pageEle.getAttribute('data-page-num') || 0;
|
|
|
- const coordinate = getAbsoluteCoordinate(pageEle, event);
|
|
|
- const id = uuidv4();
|
|
|
-
|
|
|
- setUuid(id);
|
|
|
- setStartPosition(coordinate);
|
|
|
-
|
|
|
- const shapeType = ANNOTATION_TYPE[shape];
|
|
|
- const position = convertPosition(
|
|
|
- shapeType, coordinate.x - 8, coordinate.y - 8, coordinate.x + 8, coordinate.y + 8,
|
|
|
- );
|
|
|
- const annoteData = {
|
|
|
- id,
|
|
|
- obj_type: shapeType,
|
|
|
- obj_attr: {
|
|
|
- page: pageNum as number,
|
|
|
- position,
|
|
|
- bdcolor: color,
|
|
|
- fcolor: type === 'fill' ? color : undefined,
|
|
|
- transparency: opacity,
|
|
|
- ftransparency: type === 'fill' ? opacity : undefined,
|
|
|
- bdwidth: width,
|
|
|
- is_arrow: shape === 'arrow',
|
|
|
- },
|
|
|
- };
|
|
|
- const shapeAnnotation = parseAnnotationObject(annoteData, viewport.height, scale);
|
|
|
+ const addShape = useCallback(
|
|
|
+ (
|
|
|
+ pageEle: HTMLElement,
|
|
|
+ event: MouseEvent | TouchEvent,
|
|
|
+ attributes: OptionPropsType
|
|
|
+ ): void => {
|
|
|
+ const { shape = '', type, opacity, color, width = 0 } = attributes;
|
|
|
+ const pageNum = pageEle.getAttribute('data-page-num') || 0;
|
|
|
+ const coordinate = getAbsoluteCoordinate(pageEle, event);
|
|
|
+ const id = uuidv4();
|
|
|
+
|
|
|
+ setUuid(id);
|
|
|
+ setStartPosition(coordinate);
|
|
|
+
|
|
|
+ const shapeType = ANNOTATION_TYPE[shape];
|
|
|
+ const position = convertPosition(
|
|
|
+ shapeType,
|
|
|
+ coordinate.x - 8,
|
|
|
+ coordinate.y - 8,
|
|
|
+ coordinate.x + 8,
|
|
|
+ coordinate.y + 8
|
|
|
+ );
|
|
|
+ const annoteData = {
|
|
|
+ id,
|
|
|
+ obj_type: shapeType,
|
|
|
+ obj_attr: {
|
|
|
+ page: pageNum as number,
|
|
|
+ position,
|
|
|
+ bdcolor: color,
|
|
|
+ fcolor: type === 'fill' ? color : undefined,
|
|
|
+ transparency: opacity,
|
|
|
+ ftransparency: type === 'fill' ? opacity : undefined,
|
|
|
+ bdwidth: width,
|
|
|
+ is_arrow: shape === 'arrow',
|
|
|
+ },
|
|
|
+ };
|
|
|
+ const shapeAnnotation = parseAnnotationObject(
|
|
|
+ annoteData,
|
|
|
+ viewport.height,
|
|
|
+ scale
|
|
|
+ );
|
|
|
|
|
|
- addAnnots([shapeAnnotation], true);
|
|
|
- }, [viewport, scale, data]);
|
|
|
+ addAnnots([shapeAnnotation]);
|
|
|
+ },
|
|
|
+ [viewport, scale, data]
|
|
|
+ );
|
|
|
|
|
|
const handleMouseDown = (event: MouseEvent | TouchEvent): void => {
|
|
|
- event.preventDefault();
|
|
|
+ // event.preventDefault();
|
|
|
|
|
|
const pageEle = (event.target as HTMLElement).parentNode as HTMLElement;
|
|
|
|
|
@@ -154,50 +168,54 @@ const Shape: React.FC<Props> = ({
|
|
|
};
|
|
|
}, [isActive, addShape]);
|
|
|
|
|
|
- const handleUpdate = useCallback((start: Record<string, any>, end: Record<string, any>): void => {
|
|
|
- const index = annotations.length - 1;
|
|
|
- const { x: x1, y: y1 } = start;
|
|
|
- const { x: x2, y: y2 } = end;
|
|
|
-
|
|
|
- if (annotations[index] && annotations[index].id === uuid) {
|
|
|
- const type = annotations[index].obj_type;
|
|
|
- const position = convertPosition(type, x1, y1, x2, y2);
|
|
|
-
|
|
|
- annotations[index].obj_attr.position = parsePositionForBackend(
|
|
|
- type, position, viewport.height, scale,
|
|
|
- );
|
|
|
- updateAnnots([...annotations]);
|
|
|
- }
|
|
|
- }, [annotations, viewport, scale, uuid]);
|
|
|
+ const handleUpdate = useCallback(
|
|
|
+ (start: Record<string, any>, end: Record<string, any>): void => {
|
|
|
+ const index = annotations.length - 1;
|
|
|
+ const { x: x1, y: y1 } = start;
|
|
|
+ const { x: x2, y: y2 } = end;
|
|
|
+
|
|
|
+ if (annotations[index] && annotations[index].id === uuid) {
|
|
|
+ const type = annotations[index].obj_type;
|
|
|
+ const position = convertPosition(type, x1, y1, x2, y2);
|
|
|
+
|
|
|
+ annotations[index].obj_attr.position = parsePositionForBackend(
|
|
|
+ type,
|
|
|
+ position,
|
|
|
+ viewport.height,
|
|
|
+ scale
|
|
|
+ );
|
|
|
+ updateAnnots([...annotations]);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ [annotations, viewport, scale, uuid]
|
|
|
+ );
|
|
|
|
|
|
useEffect(() => {
|
|
|
if (
|
|
|
- startPosition.x && startPosition.y
|
|
|
- && cursorPosition.x && cursorPosition.y
|
|
|
+ startPosition.x &&
|
|
|
+ startPosition.y &&
|
|
|
+ cursorPosition.x &&
|
|
|
+ cursorPosition.y
|
|
|
) {
|
|
|
handleUpdate(startPosition, cursorPosition);
|
|
|
}
|
|
|
}, [startPosition, cursorPosition]);
|
|
|
|
|
|
- return (
|
|
|
- <ExpansionPanel
|
|
|
+ const Label = (
|
|
|
+ <Button
|
|
|
+ shouldFitContainer
|
|
|
+ align="left"
|
|
|
+ onClick={onClick}
|
|
|
isActive={isActive}
|
|
|
- label={(
|
|
|
- <Button
|
|
|
- shouldFitContainer
|
|
|
- align="left"
|
|
|
- onClick={onClick}
|
|
|
- isActive={isActive}
|
|
|
- >
|
|
|
- <Icon glyph="shape" style={{ marginRight: '10px' }} />
|
|
|
- {title}
|
|
|
- </Button>
|
|
|
- )}
|
|
|
>
|
|
|
- <ShapeOption
|
|
|
- {...data}
|
|
|
- setDataState={setDataState}
|
|
|
- />
|
|
|
+ <Icon glyph="shape" style={{ marginRight: '10px' }} />
|
|
|
+ {title}
|
|
|
+ </Button>
|
|
|
+ );
|
|
|
+
|
|
|
+ return (
|
|
|
+ <ExpansionPanel isActive={isActive} label={Label}>
|
|
|
+ <ShapeOption {...data} setDataState={setDataState} />
|
|
|
</ExpansionPanel>
|
|
|
);
|
|
|
};
|