|
@@ -20,14 +20,11 @@ const Ink: React.FC<AnnotationElementPropsType> = ({
|
|
|
scale,
|
|
|
id,
|
|
|
}: AnnotationElementPropsType) => {
|
|
|
- let points: PointType[][] = [];
|
|
|
- let tempRect: HTMLCoordinateType = { top: 0, left: 0, width: 0, height: 0 };
|
|
|
- const borderWidth = bdwidth * scale;
|
|
|
-
|
|
|
- points = pointCalc(position as PointType[][], viewport.height, scale);
|
|
|
- tempRect = rectCalcWithPoint(points, borderWidth);
|
|
|
-
|
|
|
+ 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,
|
|
@@ -35,28 +32,48 @@ const Ink: React.FC<AnnotationElementPropsType> = ({
|
|
|
width = 0,
|
|
|
height = 0,
|
|
|
}: CoordType): void => {
|
|
|
- const xScaleRate = width / tempRect.width;
|
|
|
- const yScaleRate = height / tempRect.height;
|
|
|
- const xDistance = left - tempRect.left;
|
|
|
- const yDistance = tempRect.top - top;
|
|
|
-
|
|
|
- const newPosition = (position as PointType[][])[0].map((ele) => ({
|
|
|
- x: (ele.x + xDistance) * (xScaleRate || 1),
|
|
|
- y: (ele.y + yDistance) * (yScaleRate || 1),
|
|
|
- }));
|
|
|
-
|
|
|
- setRect({
|
|
|
- top,
|
|
|
- left,
|
|
|
- width,
|
|
|
- height,
|
|
|
- });
|
|
|
+ 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;
|
|
|
|
|
|
- onUpdate({
|
|
|
- position: [newPosition],
|
|
|
+ const newPoints = (currentPoint as PointType[][])[0].map((ele) => {
|
|
|
+ let x = (ele.x + dx) * rx;
|
|
|
+ let y = (ele.y - dy) * ry;
|
|
|
+
|
|
|
+ if (rx !== 1 || ry !== 1) {
|
|
|
+ x = x - disX;
|
|
|
+ }
|
|
|
+ if (ry !== 1) {
|
|
|
+ y = y - disY;
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ x,
|
|
|
+ y,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ return [newPoints];
|
|
|
+ });
|
|
|
+
|
|
|
+ return { top, left, width, height };
|
|
|
});
|
|
|
};
|
|
|
|
|
|
+ const handleMouseUp = () => {
|
|
|
+ setMoving(false);
|
|
|
+ };
|
|
|
+
|
|
|
useEffect(() => {
|
|
|
const newPoints = pointCalc(
|
|
|
position as PointType[][],
|
|
@@ -64,9 +81,23 @@ const Ink: React.FC<AnnotationElementPropsType> = ({
|
|
|
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
|
|
@@ -76,7 +107,7 @@ const Ink: React.FC<AnnotationElementPropsType> = ({
|
|
|
width={`${rect.width}px`}
|
|
|
height={`${rect.height}px`}
|
|
|
>
|
|
|
- <SVG viewBox={calcViewBox(tempRect, borderWidth)}>
|
|
|
+ <SVG viewBox={calcViewBox(rect, borderWidth)}>
|
|
|
{points.map((ele: PointType[], index: number) => {
|
|
|
const key = `${id}_path_${index}`;
|
|
|
return (
|
|
@@ -103,6 +134,7 @@ const Ink: React.FC<AnnotationElementPropsType> = ({
|
|
|
height={rect.height}
|
|
|
onMove={handleScaleOrMove}
|
|
|
onScale={handleScaleOrMove}
|
|
|
+ onMouseUp={handleMouseUp}
|
|
|
/>
|
|
|
) : (
|
|
|
''
|