123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- import React, { useState, useEffect } from 'react';
- import OuterRect from '../OuterRect';
- import {
- svgPath,
- bezierCommand,
- controlPoint,
- line,
- } from '../../helpers/svgBezierCurve';
- import { pointCalc, rectCalcWithPoint, calcViewBox } from '../../helpers/brush';
- import { AnnotationContainer } from '../../global/otherStyled';
- import { SVG } from './styled';
- const Ink: React.FC<AnnotationElementPropsType> = ({
- obj_attr: { position, bdcolor, bdwidth = 0, transparency },
- isCollapse,
- onUpdate,
- viewport,
- scale,
- id,
- }: AnnotationElementPropsType) => {
- const [points, setPoints] = useState<PointType[][]>([]);
- const [rect, setRect] = useState({ top: 0, left: 0, width: 0, height: 0 });
- const [moving, setMoving] = useState(false);
- const borderWidth = bdwidth * scale;
- const handleScaleOrMove = ({
- top,
- left,
- width = 0,
- height = 0,
- }: CoordType): void => {
- setMoving(true);
- setRect((currentRect) => {
- const rx = width / currentRect.width;
- const ry = height / currentRect.height;
- const dx = left - currentRect.left;
- const dy = currentRect.top - top;
- let disX = 0;
- let disY = 0;
- setPoints((currentPoint) => {
- const newRect = rectCalcWithPoint(currentPoint, borderWidth);
- disX = newRect.left - left;
- disY = newRect.top - top;
- const newPoints = (currentPoint as PointType[][])[0].map((ele) => {
- let x = (ele.x + dx) * rx;
- let y = (ele.y - dy) * ry;
- if (rx !== 1) {
- x = x - disX;
- }
- if (ry !== 1) {
- y = y - disY + 5;
- }
- return {
- x,
- y,
- };
- });
- return [newPoints];
- });
- return { top, left, width, height };
- });
- };
- const handleMouseUp = () => {
- setMoving(false);
- };
- useEffect(() => {
- const newPoints = pointCalc(
- position as PointType[][],
- viewport.height,
- scale,
- );
- const newRect = rectCalcWithPoint(newPoints, borderWidth);
- setPoints(newPoints);
- setRect(newRect);
- }, [viewport, scale]);
- useEffect(() => {
- if (!moving && points[0]) {
- const newPoints = (points as PointType[][])[0].map((ele) => ({
- x: ele.x / scale,
- y: (viewport.height - ele.y) / scale,
- }));
- onUpdate({
- position: [newPoints],
- });
- }
- }, [moving, points]);
- return (
- <>
- <AnnotationContainer
- id={id}
- top={`${rect.top}px`}
- left={`${rect.left}px`}
- width={`${rect.width}px`}
- height={`${rect.height}px`}
- >
- <SVG
- width={rect.width + borderWidth}
- height={rect.height + borderWidth}
- viewBox={calcViewBox(rect, borderWidth)}
- >
- {points.map((ele: PointType[], index: number) => {
- const key = `${id}_path_${index}`;
- return (
- <path
- key={key}
- d={svgPath(
- ele as PointType[],
- bezierCommand(controlPoint(line, 0.2)),
- )}
- fill="none"
- stroke={bdcolor}
- strokeWidth={borderWidth}
- strokeOpacity={transparency}
- />
- );
- })}
- </SVG>
- </AnnotationContainer>
- {!isCollapse ? (
- <OuterRect
- top={rect.top}
- left={rect.left}
- width={rect.width}
- height={rect.height}
- onMove={handleScaleOrMove}
- onScale={handleScaleOrMove}
- onMouseUp={handleMouseUp}
- />
- ) : (
- ''
- )}
- </>
- );
- };
- export default Ink;
|