123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- import { ANNOTATION_TYPE } from '../constants';
- import { AnnotationType, PositionType } from '../constants/type';
- import { parseAnnotationObject } from './annotation';
- const EXTEND_RANGE = 2;
- type ScalePositionFunc = (
- ({
- top, left, bottom, right,
- }: PositionType, scale: number) => PositionType
- );
- type GetMarkupWithSelectionFunc = (
- ({
- color, type, opacity, scale,
- }: {
- color: string;
- type: string;
- opacity: number;
- scale: number;
- }) => AnnotationType | null
- );
- const scalePosition: ScalePositionFunc = ({
- top, left, bottom, right,
- }, scale) => ({
- top: top / scale,
- left: left / scale,
- bottom: bottom / scale,
- right: right / scale,
- });
- export const getMarkupWithSelection: GetMarkupWithSelectionFunc = ({
- color, type, opacity, scale,
- }) => {
- const selection: any = document.getSelection();
- if (!selection.rangeCount) 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 endPage = endElement?.parentNode?.parentNode as HTMLElement;
- const startPageNum = parseInt(startPage.getAttribute('data-page-num') as string, 10);
- const endPageNum = parseInt(endPage.getAttribute('data-page-num') as string, 10);
- const textLayer = startPage.querySelector('[data-id="text-layer"]') as HTMLElement;
- const pageHeight = startPage.offsetHeight;
- if (startPageNum !== endPageNum) return null;
- if (startOffset === endOffset && startOffset === endOffset) return null;
- const startEle = startElement.cloneNode(true) as HTMLElement;
- const endEle = endElement.cloneNode(true) as HTMLElement;
- const startText = startElement.innerText.substring(0, startOffset);
- const endText = endEle.innerText.substring(endOffset);
- startEle.innerText = startText;
- endEle.innerText = endText;
- textLayer.appendChild(startEle);
- textLayer.appendChild(endEle);
- const startEleWidth = startEle.offsetWidth;
- const endEleWidth = endEle.offsetWidth;
- textLayer.removeChild(startEle);
- textLayer.removeChild(endEle);
- const info: AnnotationType = {
- obj_type: '',
- obj_attr: {
- page: 0,
- bdcolor: '',
- position: [],
- transparency: 0,
- },
- };
- const position: PositionType[] = [];
- // left to right and up to down select
- let startX = startElement.offsetLeft + startEleWidth;
- let startY = startElement.offsetTop - EXTEND_RANGE;
- let endX = endElement.offsetLeft + endElement.offsetWidth - endEleWidth;
- let endY = endElement.offsetTop + endElement.offsetHeight + EXTEND_RANGE;
- if (startX > endX && startY >= endY) {
- // right to left and down to up select
- startX = endElement.offsetLeft + startEleWidth;
- startY = endElement.offsetTop - EXTEND_RANGE;
- endX = startElement.offsetLeft + startElement.offsetWidth - endEleWidth;
- endY = startElement.offsetTop + startElement.offsetHeight + EXTEND_RANGE;
- }
- // @ts-ignore
- const textElements = [...textLayer.childNodes];
- textElements.forEach((ele: any) => {
- const {
- offsetTop, offsetLeft, offsetHeight, offsetWidth,
- } = ele;
- const offsetRight = offsetLeft + offsetWidth;
- const offsetBottom = offsetTop + offsetHeight;
- let coords = {
- top: 0, left: 0, right: 0, bottom: 0,
- };
- if (offsetTop >= startY && offsetBottom <= endY) {
- if (startElement === endElement) {
- // start and end same element
- coords = {
- top: offsetTop,
- bottom: offsetBottom,
- left: startX,
- right: endX,
- };
- } else if (startElement === ele) {
- // start element
- coords = {
- top: offsetTop,
- bottom: offsetBottom,
- left: startX,
- right: offsetRight,
- };
- } else if (endElement === ele) {
- // end element
- coords = {
- top: offsetTop,
- bottom: offsetBottom,
- left: offsetLeft,
- right: endX,
- };
- } else if (
- (offsetLeft >= startX && offsetRight <= endX)
- || (offsetTop > (startY + 5) && offsetBottom < (endY - 5))
- || (offsetLeft >= startX && offsetBottom <= startY + offsetHeight + 5)
- || (offsetRight <= endX && offsetTop >= endX - offsetHeight - 5)
- ) {
- // middle element
- coords = {
- top: offsetTop,
- bottom: offsetBottom,
- left: offsetLeft,
- right: offsetRight,
- };
- }
- position.push(scalePosition(coords, scale));
- }
- });
- info.obj_type = ANNOTATION_TYPE[type];
- info.obj_attr = {
- page: startPageNum,
- bdcolor: color,
- position,
- transparency: opacity,
- };
- return parseAnnotationObject(info, pageHeight, scale);
- };
- export default parseAnnotationObject;
|