index.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import React, { useEffect, useState, useRef } from 'react';
  2. import Watermark from '../Watermark';
  3. import { renderPdfPage } from '../../helpers/pdf';
  4. import { renderMatches } from '../../helpers/search';
  5. import {
  6. PageWrapper,
  7. PdfCanvas,
  8. AnnotationLayer,
  9. TextLayer,
  10. WatermarkLayer,
  11. Inner,
  12. } from './styled';
  13. type Props = {
  14. pageNum: number;
  15. renderingState?: RenderingStateType;
  16. getPage?: () => Promise<any>;
  17. viewport: ViewportType;
  18. rotation?: number;
  19. scale: number;
  20. annotations?: React.ReactNode[];
  21. drawing?: React.ReactNode[];
  22. watermark?: WatermarkType;
  23. currentPage: number;
  24. queryString: string;
  25. matchesMap: MatchType[];
  26. };
  27. const PageView: React.FC<Props> = ({
  28. pageNum,
  29. getPage,
  30. viewport,
  31. renderingState = 'PAUSED',
  32. rotation,
  33. scale,
  34. annotations = [],
  35. watermark = {},
  36. currentPage,
  37. queryString,
  38. matchesMap,
  39. }: Props) => {
  40. const rootEle = useRef<HTMLDivElement | null>(null);
  41. const [pdfPage, setPdfPage] = useState<any>(null);
  42. const [renderTask, setRenderTask] = useState<any>(null);
  43. const renderPage = async (): Promise<any> => {
  44. if (getPage) {
  45. getPage().then(obj => {
  46. setPdfPage(obj);
  47. const setTextDivsWithPage = (elements: HTMLElement[]) => {
  48. if (matchesMap.length) {
  49. matchesMap.forEach(item => {
  50. if (item.page === currentPage) {
  51. const id = `${item.page}_${item.index}`;
  52. renderMatches(elements, getPage, item.index, queryString, id);
  53. }
  54. });
  55. }
  56. };
  57. if (rootEle.current) {
  58. renderPdfPage({
  59. rootEle: rootEle.current,
  60. pdfPage: obj,
  61. viewport,
  62. setRenderTask,
  63. setTextDivs: setTextDivsWithPage,
  64. });
  65. }
  66. });
  67. }
  68. };
  69. useEffect(() => {
  70. if (renderingState === 'LOADING' && pdfPage) {
  71. pdfPage.cleanup();
  72. }
  73. if (renderingState === 'RENDERING' && renderTask) {
  74. renderTask.cancel();
  75. }
  76. if (renderingState === 'RENDERING') {
  77. renderPage();
  78. }
  79. }, [currentPage, renderingState, viewport]);
  80. useEffect(() => {
  81. if (queryString === '' && !matchesMap.length) {
  82. renderPage();
  83. }
  84. }, [queryString, matchesMap]);
  85. return (
  86. <PageWrapper
  87. ref={rootEle}
  88. id={`page_${pageNum}`}
  89. data-page-num={pageNum}
  90. width={viewport.width}
  91. height={viewport.height}
  92. rotation={rotation}
  93. >
  94. {renderingState === 'LOADING' ? (
  95. <Inner>載入中...</Inner>
  96. ) : (
  97. <>
  98. <PdfCanvas />
  99. {watermark.text || watermark.imagepath ? (
  100. <WatermarkLayer>
  101. <Watermark viewScale={scale} {...watermark} />
  102. </WatermarkLayer>
  103. ) : (
  104. ''
  105. )}
  106. <TextLayer data-id="text-layer" />
  107. <AnnotationLayer data-id="annotation-layer">
  108. {annotations}
  109. </AnnotationLayer>
  110. </>
  111. )}
  112. </PageWrapper>
  113. );
  114. };
  115. export default PageView;