import _ from 'lodash'; export const rectCalc = ( position: PositionType, viewHeight: number, scale: number, ): HTMLCoordinateType => ({ top: viewHeight - position.top * scale, left: position.left * scale, width: (position.right - position.left) * scale, height: (position.top - position.bottom) * scale, }); export const getPosition = ( type: string, element: HTMLElement, ): AnnotationPositionType => { const attributes = element.attributes as ElementAttributeType; switch (type) { case 'Ink': { const gestures: PointType[][] = []; const nodes: NodeListOf = element.childNodes[1].childNodes; const nodeList = Array.prototype.slice.call(nodes); nodeList.forEach((ele: HTMLElement) => { if (ele.tagName === 'gesture') { const points: PointType[] = []; const gestureArray = (ele.innerHTML || ele.textContent || '').split( ';', ); gestureArray.forEach((ele1: string) => { const pointArr = ele1.split(','); const point = { x: parseInt(pointArr[0], 10), y: parseInt(pointArr[1], 10), }; points.push(point); }); gestures.push(points); } }); return gestures; } case 'Line': { const start = attributes.start.value.split(','); const end = attributes.end.value.split(','); return { start: { x: parseInt(start[0], 10), y: parseInt(start[1], 10), }, end: { x: parseInt(end[0], 10), y: parseInt(end[1], 10), }, }; } case 'Square': case 'Circle': { const width = parseInt(attributes.width.value, 10); const rect = attributes.rect.value.split(','); return { left: parseInt(rect[0], 10) + width, bottom: parseInt(rect[1], 10) + width, right: parseInt(rect[2], 10) - width, top: parseInt(rect[3], 10) - width, }; } case 'Text': case 'FreeText': case 'textfield': case 'checkbox': { const rect = attributes.rect.value.split(','); return { left: parseInt(rect[0], 10), bottom: parseInt(rect[1], 10), right: parseInt(rect[2], 10), top: parseInt(rect[3], 10), }; } case 'Highlight': case 'Underline': case 'Squiggly': case 'StrikeOut': { let tempArray: string[][] = []; if (attributes.coords) { const coords = attributes.coords.value.split(','); tempArray = _.chunk(coords, 8); } const position = tempArray.map((ele: string[]) => ({ left: parseInt(ele[0], 10), bottom: parseInt(ele[1], 10), right: parseInt(ele[2], 10), top: parseInt(ele[5], 10), })); return position; } default: return { left: 0, bottom: 0, right: 0, top: 0, }; } }; export const parsePositionForBackend = ( type: string, position: AnnotationPositionType, pageHeight: number, scale: number, ): AnnotationPositionType => { switch (type) { case 'Highlight': case 'Underline': case 'Squiggly': case 'StrikeOut': { const positionArray = position as PositionType[]; return positionArray.map((ele: PositionType) => ({ left: ele.left / scale, bottom: (pageHeight - ele.bottom) / scale, right: ele.right / scale, top: (pageHeight - ele.top) / scale, })); } case 'Square': case 'Circle': case 'FreeText': case 'Text': case 'Image': case 'textfield': case 'checkbox': { const normalPosition = position as PositionType; return { left: normalPosition.left / scale, bottom: (pageHeight - normalPosition.bottom) / scale, right: normalPosition.right / scale, top: (pageHeight - normalPosition.top) / scale, }; } case 'Line': { const { start, end } = position as LinePositionType; return { start: { x: start.x / scale, y: (pageHeight - start.y) / scale, }, end: { x: end.x / scale, y: (pageHeight - end.y) / scale, }, }; } case 'Ink': { if (Array.isArray(position)) { const points = position as PointType[][]; return [ points[0].map((point) => ({ x: point.x / scale, y: (pageHeight - point.y) / scale, })), ]; } const point = position as PointType; return { x: point.x / scale, y: (pageHeight - point.y) / scale, }; } default: return { left: 0, bottom: 0, right: 0, top: 0, }; } }; type GetAbsoluteCoordinateType = ( parentElement: HTMLElement | SVGSVGElement | SVGCircleElement | null, // eslint-disable-next-line @typescript-eslint/no-explicit-any clickEvent: any, ) => { x: number; y: number }; export const getAbsoluteCoordinate: GetAbsoluteCoordinateType = ( parentElement, clickEvent, ) => { if (!parentElement) return { x: 0, y: 0 }; let pageX = 0; let pageY = 0; if (clickEvent.touches) { const touch = clickEvent.touches[0]; ({ pageX, pageY } = touch); } else { ({ pageX, pageY } = clickEvent); } const rect = parentElement.getBoundingClientRect(); const offsetX = window.pageXOffset || window.scrollX || 0; const offsetY = window.pageYOffset || window.scrollY || 0; const coordinate = { x: pageX - rect.left - offsetX, y: pageY - rect.top - offsetY, }; return coordinate; }; export default rectCalc;