PdfPages.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import React, {
  2. useEffect, useState, useRef,
  3. } from 'react';
  4. import { AnnotationType, ScrollStateType } from '../constants/type';
  5. import Page from '../components/Page';
  6. import Viewer from '../components/Viewer';
  7. import Annotation from './Annotation';
  8. import { watchScroll } from '../helpers/utility';
  9. import { getPdfPage } from '../helpers/pdf';
  10. import useStore from '../store';
  11. type Props = {
  12. scrollToUpdate: (state: ScrollStateType) => void;
  13. };
  14. const PdfPages: React.FunctionComponent<Props> = ({
  15. scrollToUpdate,
  16. }: Props) => {
  17. const [elements, setElement] = useState<React.ReactNode[]>([]);
  18. const containerRef = useRef<HTMLDivElement>(null);
  19. const [{
  20. totalPage,
  21. currentPage,
  22. viewport,
  23. pdf,
  24. rotation,
  25. displayMode,
  26. annotations,
  27. scale,
  28. }] = useStore();
  29. const getAnnotations = (arr: AnnotationType[], pageNum: number): any[] => {
  30. const result: any[] = [];
  31. arr.forEach((ele: AnnotationType, index: number) => {
  32. if (ele.obj_attr?.page === pageNum) {
  33. result.push(<Annotation key={`annotations_${pageNum + index}`} scale={scale} index={index} {...ele} />);
  34. }
  35. });
  36. return result;
  37. };
  38. const createPages = (): void => {
  39. const pagesContent: React.ReactNode[] = [];
  40. for (let i = 1; i <= totalPage; i += 1) {
  41. const annotationElements = getAnnotations(annotations, i);
  42. const component = (
  43. <Page
  44. key={`page-${i}`}
  45. pageNum={i}
  46. renderingState={[1, 2, 3].includes(i) ? 'RENDERING' : 'LOADING'}
  47. viewport={viewport}
  48. getPage={(): Promise<any> => getPdfPage(pdf, i)}
  49. rotation={rotation}
  50. annotations={annotationElements}
  51. />
  52. );
  53. pagesContent.push(component);
  54. }
  55. setElement(pagesContent);
  56. };
  57. const updatePages = (): void => {
  58. const renderingIndexQueue = [currentPage - 1, currentPage, currentPage + 1];
  59. let index = currentPage - 4;
  60. const end = currentPage + 3;
  61. while (currentPage) {
  62. if (elements[index]) {
  63. const pageNum = index + 1;
  64. const annotationElements = getAnnotations(annotations, pageNum);
  65. elements[index] = (
  66. <Page
  67. key={`page-${pageNum}`}
  68. pageNum={pageNum}
  69. renderingState={renderingIndexQueue.includes(pageNum) ? 'RENDERING' : 'LOADING'}
  70. viewport={viewport}
  71. getPage={(): Promise<any> => getPdfPage(pdf, pageNum)}
  72. rotation={rotation}
  73. annotations={annotationElements}
  74. />
  75. );
  76. }
  77. index += 1;
  78. if (index >= end) break;
  79. }
  80. if (elements.length) {
  81. setElement([...elements]);
  82. }
  83. };
  84. useEffect(() => {
  85. createPages();
  86. watchScroll(containerRef.current, scrollToUpdate);
  87. }, []);
  88. useEffect(() => {
  89. updatePages();
  90. }, [currentPage, viewport, rotation, annotations]);
  91. return (
  92. <Viewer
  93. ref={containerRef}
  94. viewport={viewport}
  95. rotation={rotation}
  96. displayMode={displayMode}
  97. >
  98. {elements}
  99. </Viewer>
  100. );
  101. };
  102. export default PdfPages;