123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- import { ANNOTATION_TYPE } from '../constants';
- import { parseAnnotationObject, appendUserIdAndDate } from './annotation';
- type GetMarkupWithSelectionFunc = ({
- color,
- type,
- opacity,
- scale,
- }: {
- color: string;
- type: string;
- opacity: number;
- scale: number;
- textLayer: HTMLElement;
- }) => AnnotationType | null;
- export const getMarkupWithSelection: GetMarkupWithSelectionFunc = ({
- color,
- type,
- opacity,
- scale,
- textLayer,
- }) => {
- const selection: Selection | null = document.getSelection();
- if (!selection || selection.isCollapsed) return null;
- const {
- startContainer,
- startOffset,
- endContainer,
- endOffset,
- } = selection.getRangeAt(0);
- const startElement = startContainer.parentNode as HTMLElement;
- const endElement = endContainer.parentNode as HTMLElement;
- const startPage = startElement?.parentNode?.parentNode as HTMLElement;
- const startPageNum = parseInt(
- startPage.getAttribute('data-page-num') as string,
- 10
- );
- const pageHeight = startPage.offsetHeight;
- const startCloneEle = startElement.cloneNode(true) as HTMLElement;
- const endCloneEle = endElement.cloneNode(true) as HTMLElement;
- const startText = startElement.innerText.substring(0, startOffset);
- const endText = endElement.innerText.substring(endOffset);
- startCloneEle.innerText = startText;
- endCloneEle.innerText = endText;
- textLayer.appendChild(startCloneEle);
- textLayer.appendChild(endCloneEle);
- const startExtraWidth = startCloneEle.getBoundingClientRect().width;
- const endExtraWidth = endCloneEle.getBoundingClientRect().width;
- textLayer.removeChild(startCloneEle);
- textLayer.removeChild(endCloneEle);
- const info: AnnotationType = {
- obj_type: '',
- obj_attr: {
- page: 0,
- bdcolor: '',
- position: [],
- transparency: 0,
- },
- };
- const position: PositionType[] = [];
- const startRect = startElement.getBoundingClientRect();
- const endRect = endElement.getBoundingClientRect();
- // left to right and up to down select
- let startX = startElement.offsetLeft + startExtraWidth;
- let startY = startElement.offsetTop;
- let endX = endElement.offsetLeft + endRect.width - endExtraWidth;
- let endY = endElement.offsetTop + endRect.height;
- if (startX > endX && startY >= endY) {
- // right to left and down to up select
- startX = endElement.offsetLeft + startExtraWidth;
- startY = endElement.offsetTop;
- endX = startElement.offsetLeft + startRect.width - endExtraWidth;
- endY = startElement.offsetTop + startRect.height;
- }
- // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
- // @ts-ignore
- const textElements = [...textLayer.childNodes];
- let inRange = false;
- textElements.forEach((ele: HTMLElement) => {
- const { height, width } = ele.getBoundingClientRect();
- const { offsetTop, offsetLeft } = ele;
- const top = offsetTop;
- const left = offsetLeft;
- const right = offsetLeft + width;
- const bottom = offsetTop + height;
- const coords = {
- top,
- bottom,
- left,
- right,
- };
- if (startElement === ele && endElement === ele) {
- // in same element
- coords.left = startX;
- coords.right = endX;
- position.push(coords);
- } else if (startElement === ele) {
- // in start element
- coords.left = startX;
- position.push(coords);
- inRange = true;
- } else if (endElement === ele) {
- // in end element
- coords.right = endX;
- position.push(coords);
- inRange = false;
- } else if (inRange) {
- // middle element
- position.push(coords);
- }
- });
- for (let i = 1; i < position.length; i += 1) {
- if (
- position[i].top >= position[i - 1].top - 4 &&
- position[i].bottom <= position[i - 1].bottom + 4
- ) {
- position[i - 1].right = position[i].left;
- }
- }
- info.obj_type = ANNOTATION_TYPE[type];
- info.obj_attr = {
- page: startPageNum,
- bdcolor: color,
- position,
- transparency: opacity,
- };
- return appendUserIdAndDate(parseAnnotationObject(info, pageHeight, scale));
- };
- export default getMarkupWithSelection;
|