123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import React from 'react';
- import OuterRect from '../OuterRect';
- import {
- svgPath,
- bezierCommand,
- controlPoint,
- line,
- } from '../../helpers/svgBezierCurve';
- import { AnnotationContainer } from '../../global/otherStyled';
- import { SVG } from './styled';
- const Ink: React.SFC<AnnotationElementPropsType> = ({
- obj_attr: { position, bdcolor, bdwidth = 0, transparency },
- isCollapse,
- onUpdate,
- viewport,
- scale,
- id,
- }: AnnotationElementPropsType) => {
- const pointCalc = (
- _points: PointType[][],
- h: number,
- s: number
- ): PointType[][] => {
- const reducer = _points.reduce(
- (acc: PointType[][], cur: PointType[]): PointType[][] => {
- const p = cur.map((point: PointType) => ({
- x: point.x * s,
- y: h - point.y * s,
- }));
- acc.push(p);
- return acc;
- },
- []
- );
- return reducer;
- };
- const rectCalcWithPoint = (
- pointsGroup: PointType[][],
- borderWidth: number
- ): HTMLCoordinateType => {
- const xArray: number[] = [];
- const yArray: number[] = [];
- pointsGroup[0].forEach((point: PointType) => {
- xArray.push(point.x);
- yArray.push(point.y);
- });
- const top = Math.min(...yArray);
- const left = Math.min(...xArray);
- const bottom = Math.max(...yArray);
- const right = Math.max(...xArray);
- return {
- top,
- left,
- width: right - left + borderWidth,
- height: bottom - top + borderWidth,
- };
- };
- const borderWidth = bdwidth * scale;
- const annotPoints = pointCalc(
- position as PointType[][],
- viewport.height,
- scale
- );
- const annotRect = rectCalcWithPoint(annotPoints, borderWidth);
- const scaleOrMoveCalc = (
- rect: HTMLCoordinateType,
- updatePoints: (data: UpdateData) => void
- ) => ({ top, left, width = 0, height = 0 }: CoordType): void => {
- const xScaleRate = width / rect.width;
- const yScaleRate = height / rect.height;
- const xDistance = left - rect.left;
- const yDistance = rect.top - top;
- const newPosition = (position as PointType[][])[0].map(ele => ({
- x: (ele.x + xDistance) * (xScaleRate || 1),
- y: (ele.y + yDistance) * (yScaleRate || 1),
- }));
- updatePoints({
- position: [newPosition],
- });
- };
- const handleScaleOrMove = scaleOrMoveCalc(annotRect, onUpdate);
- const calcViewBox = (
- { top, left, width, height }: HTMLCoordinateType,
- _borderWidth: number
- ): string => `
- ${left - _borderWidth / 2} ${top - _borderWidth / 2} ${width} ${height}
- `;
- return (
- <>
- <AnnotationContainer
- top={`${annotRect.top}px`}
- left={`${annotRect.left}px`}
- width={`${annotRect.width}px`}
- height={`${annotRect.height}px`}
- >
- <SVG viewBox={calcViewBox(annotRect, bdwidth * scale)}>
- {annotPoints.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={bdwidth * scale}
- strokeOpacity={transparency}
- />
- );
- })}
- </SVG>
- </AnnotationContainer>
- {!isCollapse ? (
- <OuterRect
- top={annotRect.top}
- left={annotRect.left}
- width={annotRect.width}
- height={annotRect.height}
- onMove={handleScaleOrMove}
- onScale={handleScaleOrMove}
- />
- ) : (
- ''
- )}
- </>
- );
- };
- export default Ink;
|