index.tsx 4.2 KB

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