position.ts 5.1 KB

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