index.tsx 4.2 KB

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