index.tsx 2.9 KB

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