index.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import React from 'react';
  2. import { v4 as uuidv4 } from 'uuid';
  3. import Outer from '../OuterRectForLine';
  4. import {
  5. AnnotationElementPropsType, LinePositionType, HTMLCoordinateType,
  6. } from '../../constants/type';
  7. import { parsePositionForBackend } from '../../helpers/position';
  8. import { AnnotationContainer } from '../../global/otherStyled';
  9. const Note: React.SFC<AnnotationElementPropsType> = ({
  10. obj_type,
  11. obj_attr,
  12. scale,
  13. viewport,
  14. isCollapse,
  15. onUpdate,
  16. }: AnnotationElementPropsType) => {
  17. const {
  18. bdcolor = '',
  19. bdwidth = 0,
  20. transparency = 0,
  21. position,
  22. is_arrow,
  23. } = obj_attr;
  24. const uuid = uuidv4();
  25. const getActualPoint = (
  26. { start, end }: LinePositionType, h: number, s: number,
  27. ): LinePositionType => {
  28. const x1 = start.x * scale;
  29. const y1 = h - start.y * s;
  30. const x2 = end.x * scale;
  31. const y2 = h - end.y * s;
  32. return {
  33. start: {
  34. x: x1,
  35. y: y1,
  36. },
  37. end: {
  38. x: x2,
  39. y: y2,
  40. },
  41. };
  42. };
  43. const pointCalc = (
  44. { start, end }: LinePositionType,
  45. borderWidth: number,
  46. ): LinePositionType => ({
  47. start: {
  48. x: start.x + borderWidth,
  49. y: start.y + borderWidth,
  50. },
  51. end: {
  52. x: end.x + borderWidth,
  53. y: end.y + borderWidth,
  54. },
  55. });
  56. const rectCalc = (
  57. { start, end }: LinePositionType, h: number, s: number,
  58. ): HTMLCoordinateType => {
  59. const startY = h - start.y * s;
  60. const endY = h - end.y * s;
  61. return {
  62. top: startY > endY ? endY : startY,
  63. left: start.x > end.x ? end.x * s : start.x * s,
  64. width: Math.abs((end.x - start.x) * s),
  65. height: Math.abs(endY - startY),
  66. };
  67. };
  68. const actualbdwidth = bdwidth * scale;
  69. const annotRect = rectCalc(position as LinePositionType, viewport.height, scale);
  70. const { start, end } = getActualPoint(position as LinePositionType, viewport.height, scale);
  71. const {
  72. start: completeStart,
  73. end: completeEnd,
  74. } = pointCalc({ start, end } as LinePositionType, actualbdwidth);
  75. const actualWidth = annotRect.width + actualbdwidth + 15;
  76. const actualHeight = annotRect.height + actualbdwidth + 15;
  77. const handleMove = ({ start: moveStart, end: moveEnd }: LinePositionType): void => {
  78. const newPosition = {
  79. start: {
  80. x: moveStart.x, y: moveStart.y,
  81. },
  82. end: {
  83. x: moveEnd.x, y: moveEnd.y,
  84. },
  85. };
  86. onUpdate({
  87. position: parsePositionForBackend(obj_type, newPosition, viewport.height, scale),
  88. });
  89. };
  90. return (
  91. <>
  92. <AnnotationContainer
  93. top={`${annotRect.top}px`}
  94. left={`${annotRect.left}px`}
  95. width={`${actualWidth}px`}
  96. height={`${actualHeight}px`}
  97. >
  98. <svg
  99. width={`${actualWidth}px`}
  100. height={`${actualHeight}px`}
  101. viewBox={`${annotRect.left} ${annotRect.top} ${actualWidth} ${actualHeight}`}
  102. >
  103. {
  104. is_arrow ? (
  105. <defs>
  106. <marker
  107. id={uuid}
  108. markerWidth={actualbdwidth * 2}
  109. markerHeight={actualbdwidth * 3}
  110. refX={3}
  111. refY={2}
  112. orient="auto"
  113. markerUnits="strokeWidth"
  114. >
  115. <polyline
  116. points="0.25,0.5 3.25,2 0.25,3.5 3.25,2 -0.25,2"
  117. stroke={bdcolor}
  118. strokeWidth={1}
  119. fill="none"
  120. strokeDasharray={100}
  121. />
  122. </marker>
  123. </defs>
  124. ) : null
  125. }
  126. <line
  127. x1={completeStart.x}
  128. y1={completeStart.y}
  129. x2={completeEnd.x}
  130. y2={completeEnd.y}
  131. stroke={bdcolor}
  132. strokeWidth={actualbdwidth}
  133. strokeOpacity={transparency}
  134. markerEnd={is_arrow ? `url(#${uuid})` : ''}
  135. />
  136. </svg>
  137. </AnnotationContainer>
  138. {
  139. !isCollapse ? (
  140. <Outer
  141. top={annotRect.top}
  142. left={annotRect.left}
  143. width={actualWidth}
  144. height={actualHeight}
  145. start={start}
  146. end={end}
  147. completeStart={completeStart}
  148. completeEnd={completeEnd}
  149. onMove={handleMove}
  150. />
  151. ) : ''
  152. }
  153. </>
  154. );
  155. };
  156. export default Note;