index.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. import React, { useEffect, 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. Canvas,
  13. } from './styled';
  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. toolState: ToolType | FormType | '';
  26. };
  27. const PageView: React.FC<Props> = ({
  28. pageNum,
  29. getPage,
  30. viewport,
  31. renderingState = 'LOADING',
  32. rotation,
  33. scale,
  34. annotations = [],
  35. watermark = {},
  36. queryString,
  37. matchesMap,
  38. toolState,
  39. }: Props) => {
  40. let pdfPage: any = null;
  41. let renderTask: any = null;
  42. const rootEle = useRef<HTMLDivElement | null>(null);
  43. const setRenderTask = (task: any) => {
  44. renderTask = task;
  45. };
  46. const renderPage = async (): Promise<void> => {
  47. if (getPage) {
  48. getPage().then((obj: PdfPageType) => {
  49. pdfPage = obj;
  50. const setTextDivs = (elements: HTMLElement[]) => {
  51. if (queryString && matchesMap.length) {
  52. matchesMap.forEach((item) => {
  53. if (pageNum === item.page) {
  54. const id = `${item.page}_${item.index}`;
  55. renderMatches(elements, getPage, item.index, queryString, id);
  56. }
  57. });
  58. }
  59. };
  60. if (rootEle.current) {
  61. renderPdfPage({
  62. rootEle: rootEle.current,
  63. pdfPage: obj,
  64. viewport,
  65. setRenderTask,
  66. setTextDivs,
  67. });
  68. }
  69. });
  70. }
  71. };
  72. useEffect(() => {
  73. if (renderTask) {
  74. renderTask.cancel();
  75. renderTask = null;
  76. }
  77. if (pdfPage) {
  78. pdfPage.cleanup();
  79. pdfPage = null;
  80. }
  81. if (renderingState === 'RENDERING') {
  82. renderPage();
  83. }
  84. }, [renderingState, viewport, queryString, matchesMap]);
  85. useEffect(() => {
  86. if (queryString === '' && !matchesMap.length) {
  87. renderPage();
  88. }
  89. }, [queryString, matchesMap]);
  90. return (
  91. <PageWrapper
  92. ref={rootEle}
  93. id={`page_${pageNum}`}
  94. data-page-num={pageNum}
  95. width={viewport.width}
  96. height={viewport.height}
  97. rotation={rotation}
  98. >
  99. {renderingState === 'LOADING' ? (
  100. <Inner>載入中...</Inner>
  101. ) : (
  102. <>
  103. <PdfCanvas />
  104. {watermark.text || watermark.imagepath ? (
  105. <WatermarkLayer>
  106. <Watermark viewScale={scale} {...watermark} />
  107. </WatermarkLayer>
  108. ) : (
  109. ''
  110. )}
  111. <TextLayer
  112. data-id="text-layer"
  113. style={{
  114. display:
  115. toolState === 'freehand' || toolState === 'shape'
  116. ? 'none'
  117. : 'block',
  118. }}
  119. />
  120. <AnnotationLayer data-id="annotation-layer">
  121. {annotations}
  122. </AnnotationLayer>
  123. <Canvas
  124. className="canvas"
  125. viewBox={`0 0 ${viewport.width} ${viewport.height}`}
  126. />
  127. </>
  128. )}
  129. </PageWrapper>
  130. );
  131. };
  132. export default PageView;