position.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. import _ from 'lodash';
  2. export const rectCalc = (
  3. position: PositionType,
  4. viewHeight: number,
  5. scale: number
  6. ): HTMLCoordinateType => ({
  7. top: viewHeight - position.top * scale,
  8. left: position.left * scale,
  9. width: (position.right - position.left) * scale,
  10. height: (position.top - position.bottom) * scale,
  11. });
  12. export const getPosition = (
  13. type: string,
  14. element: Record<string, any>
  15. ): AnnotationPositionType => {
  16. switch (type) {
  17. case 'Ink': {
  18. const gestures: PointType[][] = [];
  19. const nodes: HTMLCollection = element.childNodes[1].childNodes;
  20. const nodeList = Array.prototype.slice.call(nodes);
  21. nodeList.forEach((ele: HTMLElement) => {
  22. if (ele.tagName === 'gesture') {
  23. const points: PointType[] = [];
  24. const gestureArray = (ele.innerHTML || ele.textContent || '').split(
  25. ';'
  26. );
  27. gestureArray.forEach((ele1: string) => {
  28. const pointArr = ele1.split(',');
  29. const point = {
  30. x: parseInt(pointArr[0], 10),
  31. y: parseInt(pointArr[1], 10),
  32. };
  33. points.push(point);
  34. });
  35. gestures.push(points);
  36. }
  37. });
  38. return gestures;
  39. }
  40. case 'Line': {
  41. const start = element.attributes.start.value.split(',');
  42. const end = element.attributes.end.value.split(',');
  43. return {
  44. start: {
  45. x: start[0],
  46. y: start[1],
  47. },
  48. end: {
  49. x: end[0],
  50. y: end[1],
  51. },
  52. };
  53. }
  54. case 'Square':
  55. case 'Circle': {
  56. const width = parseInt(element.attributes.width.value, 10);
  57. const rect = element.attributes.rect.value.split(',');
  58. return {
  59. left: parseInt(rect[0], 10) + width,
  60. bottom: parseInt(rect[1], 10) + width,
  61. right: parseInt(rect[2], 10) - width,
  62. top: parseInt(rect[3], 10) - width,
  63. };
  64. }
  65. case 'Text':
  66. case 'FreeText':
  67. case 'textfield':
  68. case 'checkbox': {
  69. const rect = element.attributes.rect.value.split(',');
  70. return {
  71. left: parseInt(rect[0], 10),
  72. bottom: parseInt(rect[1], 10),
  73. right: parseInt(rect[2], 10),
  74. top: parseInt(rect[3], 10),
  75. };
  76. }
  77. case 'Highlight':
  78. case 'Underline':
  79. case 'Squiggly':
  80. case 'StrikeOut': {
  81. let tempArray: any[] = [];
  82. if (element.attributes.coords) {
  83. const coords = element.attributes.coords.value.split(',');
  84. tempArray = _.chunk(coords, 8);
  85. }
  86. const position = tempArray.map((ele: string[]) => ({
  87. left: parseInt(ele[0], 10),
  88. bottom: parseInt(ele[1], 10),
  89. right: parseInt(ele[2], 10),
  90. top: parseInt(ele[5], 10),
  91. }));
  92. return position;
  93. }
  94. default:
  95. return '';
  96. }
  97. };
  98. export const parsePositionForBackend = (
  99. type: string,
  100. position: AnnotationPositionType,
  101. pageHeight: number,
  102. scale: number
  103. ): AnnotationPositionType => {
  104. switch (type) {
  105. case 'Highlight':
  106. case 'Underline':
  107. case 'Squiggly':
  108. case 'StrikeOut': {
  109. const positionArray = position as PositionType[];
  110. return positionArray.map((ele: PositionType) => ({
  111. left: ele.left / scale,
  112. bottom: (pageHeight - ele.bottom) / scale,
  113. right: ele.right / scale,
  114. top: (pageHeight - ele.top) / scale,
  115. }));
  116. }
  117. case 'Square':
  118. case 'Circle':
  119. case 'FreeText':
  120. case 'Text':
  121. case 'Image':
  122. case 'textfield':
  123. case 'checkbox': {
  124. const normalPosition = position as PositionType;
  125. return {
  126. left: normalPosition.left / scale,
  127. bottom: (pageHeight - normalPosition.bottom) / scale,
  128. right: normalPosition.right / scale,
  129. top: (pageHeight - normalPosition.top) / scale,
  130. };
  131. }
  132. case 'Line': {
  133. const { start, end } = position as LinePositionType;
  134. return {
  135. start: {
  136. x: start.x / scale,
  137. y: (pageHeight - start.y) / scale,
  138. },
  139. end: {
  140. x: end.x / scale,
  141. y: (pageHeight - end.y) / scale,
  142. },
  143. };
  144. }
  145. case 'Ink': {
  146. if (Array.isArray(position)) {
  147. const points = position as PointType[][];
  148. return [
  149. points[0].map(point => ({
  150. x: point.x / scale,
  151. y: (pageHeight - point.y) / scale,
  152. })),
  153. ];
  154. }
  155. const point = position as PointType;
  156. return {
  157. x: point.x / scale,
  158. y: (pageHeight - point.y) / scale,
  159. };
  160. }
  161. default:
  162. return {
  163. left: 0,
  164. bottom: 0,
  165. right: 0,
  166. top: 0,
  167. };
  168. }
  169. };
  170. type GetAbsoluteCoordinateType = (
  171. parentElement: HTMLElement | SVGSVGElement | SVGCircleElement | null,
  172. clickEvent: any
  173. ) => { x: number; y: number };
  174. export const getAbsoluteCoordinate: GetAbsoluteCoordinateType = (
  175. parentElement,
  176. clickEvent
  177. ) => {
  178. if (!parentElement) return { x: 0, y: 0 };
  179. let pageX = 0;
  180. let pageY = 0;
  181. if (clickEvent.touches) {
  182. const touch = clickEvent.touches[0];
  183. ({ pageX, pageY } = touch);
  184. } else {
  185. ({ pageX, pageY } = clickEvent);
  186. }
  187. const rect = parentElement.getBoundingClientRect();
  188. const offsetX = window.pageXOffset || window.scrollX || 0;
  189. const offsetY = window.pageYOffset || window.scrollY || 0;
  190. const coordinate = {
  191. x: pageX - rect.left - offsetX,
  192. y: pageY - rect.top - offsetY,
  193. };
  194. return coordinate;
  195. };
  196. export default rectCalc;