Prechádzať zdrojové kódy

optimization pdf page render

RoyLiu 4 rokov pred
rodič
commit
aea46f2293

+ 14 - 16
components/Page/index.tsx

@@ -13,17 +13,17 @@ import {
   Inner,
 } from './styled';
 
+let pdfPage: any = null;
+
 type Props = {
   pageNum: number;
-  renderingState?: RenderingStateType;
-  getPage?: () => Promise<any>;
+  renderingState: RenderingStateType;
+  getPage: () => Promise<any>;
   viewport: ViewportType;
-  rotation?: number;
+  rotation: number;
   scale: number;
-  annotations?: React.ReactNode[];
-  drawing?: React.ReactNode[];
-  watermark?: WatermarkType;
-  currentPage: number;
+  annotations: React.ReactNode[];
+  watermark: WatermarkType;
   queryString: string;
   matchesMap: MatchType[];
 };
@@ -32,28 +32,26 @@ const PageView: React.FC<Props> = ({
   pageNum,
   getPage,
   viewport,
-  renderingState = 'PAUSED',
+  renderingState = 'LOADING',
   rotation,
   scale,
   annotations = [],
   watermark = {},
-  currentPage,
   queryString,
   matchesMap,
 }: Props) => {
   const rootEle = useRef<HTMLDivElement | null>(null);
-  const [pdfPage, setPdfPage] = useState<any>(null);
   const [renderTask, setRenderTask] = useState<any>(null);
 
   const renderPage = async (): Promise<any> => {
     if (getPage) {
       getPage().then(obj => {
-        setPdfPage(obj);
+        pdfPage = obj;
 
-        const setTextDivsWithPage = (elements: HTMLElement[]) => {
-          if (matchesMap.length) {
+        const setTextDivs = (elements: HTMLElement[]) => {
+          if (queryString && matchesMap.length) {
             matchesMap.forEach(item => {
-              if (item.page === currentPage) {
+              if (pageNum === item.page) {
                 const id = `${item.page}_${item.index}`;
                 renderMatches(elements, getPage, item.index, queryString, id);
               }
@@ -67,7 +65,7 @@ const PageView: React.FC<Props> = ({
             pdfPage: obj,
             viewport,
             setRenderTask,
-            setTextDivs: setTextDivsWithPage,
+            setTextDivs,
           });
         }
       });
@@ -84,7 +82,7 @@ const PageView: React.FC<Props> = ({
     if (renderingState === 'RENDERING') {
       renderPage();
     }
-  }, [currentPage, renderingState, viewport]);
+  }, [renderingState, viewport, queryString, matchesMap]);
 
   useEffect(() => {
     if (queryString === '' && !matchesMap.length) {

+ 15 - 4
containers/PdfPage.tsx

@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useEffect, useState } from 'react';
 
 import Page from '../components/Page';
 import Annotation from './Annotation';
@@ -8,10 +8,12 @@ import useStore from '../store';
 
 type Props = {
   index: number;
-  renderingState: RenderingStateType;
 };
 
-const PdfPage: React.FC<Props> = ({ index, renderingState }: Props) => {
+const PdfPage: React.FC<Props> = ({ index }: Props) => {
+  const [renderingState, setRenderingState] = useState<RenderingStateType>(
+    'LOADING'
+  );
   const [
     {
       viewport,
@@ -45,6 +47,16 @@ const PdfPage: React.FC<Props> = ({ index, renderingState }: Props) => {
     return result;
   };
 
+  useEffect(() => {
+    if (currentPage + 2 >= index && currentPage - 2 <= index) {
+      if (renderingState !== 'RENDERING') {
+        setRenderingState('RENDERING');
+      }
+    } else if (renderingState === 'RENDERING') {
+      setRenderingState('LOADING');
+    }
+  }, [renderingState, currentPage]);
+
   return (
     <Page
       pageNum={index}
@@ -55,7 +67,6 @@ const PdfPage: React.FC<Props> = ({ index, renderingState }: Props) => {
       rotation={rotation}
       watermark={watermark}
       annotations={getAnnotationWithPage(annotations, index)}
-      currentPage={currentPage}
       queryString={queryString}
       matchesMap={matchesMap}
     />

+ 6 - 66
containers/PdfPages.tsx

@@ -1,4 +1,4 @@
-import React, { useEffect, useState, useRef } from 'react';
+import React, { useEffect, useRef } from 'react';
 import _ from 'lodash';
 
 import Viewer from '../components/Viewer';
@@ -16,81 +16,18 @@ type Props = {
 let timer = 0;
 
 const PdfPages: React.FC<Props> = ({ scrollToUpdate }: Props) => {
-  const [elements, setElement] = useState<React.ReactNode[]>([]);
   const containerRef = useRef<HTMLDivElement>(null);
   const [
-    {
-      totalPage,
-      currentPage,
-      scale,
-      viewport,
-      rotation,
-      displayMode,
-      annotations,
-    },
+    { totalPage, scale, viewport, rotation, displayMode },
     dispatch,
   ] = useStore();
   const { changeScale } = useActions(dispatch);
   const [zoom] = useGestureScale(containerRef);
 
-  const createPages = (): void => {
-    const pagesContent: React.ReactNode[] = [];
-
-    for (let i = 1; i <= totalPage; i += 1) {
-      const key = `page-${i}`;
-
-      const component = (
-        <PdfPage
-          key={key}
-          index={i}
-          renderingState={_.range(1, 3).includes(i) ? 'RENDERING' : 'LOADING'}
-        />
-      );
-      pagesContent.push(component);
-    }
-
-    setElement(pagesContent);
-  };
-
-  const updatePages = (): void => {
-    const renderingIndexQueue = _.range(currentPage - 1, currentPage + 2);
-    let index = currentPage - 3;
-    const end = currentPage + 3;
-
-    while (currentPage) {
-      if (elements[index]) {
-        const pageNum = index + 1;
-        const key = `page-${pageNum}`;
-
-        elements[index] = (
-          <PdfPage
-            key={key}
-            index={pageNum}
-            renderingState={
-              renderingIndexQueue.includes(pageNum) ? 'RENDERING' : 'LOADING'
-            }
-          />
-        );
-      }
-
-      index += 1;
-      if (index >= end) break;
-    }
-
-    if (elements.length) {
-      setElement([...elements]);
-    }
-  };
-
   useEffect(() => {
-    createPages();
     watchScroll(containerRef.current, scrollToUpdate);
   }, []);
 
-  useEffect(() => {
-    updatePages();
-  }, [currentPage, viewport, rotation, annotations]);
-
   useEffect(() => {
     if (zoom !== 0) {
       const viewer = containerRef.current as HTMLElement;
@@ -112,7 +49,10 @@ const PdfPages: React.FC<Props> = ({ scrollToUpdate }: Props) => {
       rotation={rotation}
       displayMode={displayMode}
     >
-      {elements}
+      {totalPage &&
+        Array(totalPage)
+          .fill(1)
+          .map((x, i) => <PdfPage key={`page-${i + x}`} index={i + x} />)}
     </Viewer>
   );
 };

+ 3 - 3
containers/PdfViewer.tsx

@@ -121,12 +121,12 @@ const PdfViewer: React.FC = () => {
     const ele: HTMLDivElement = document.getElementById(
       'page_1'
     ) as HTMLDivElement;
-    const page = Math.round(
+    const pageNum = Math.round(
       (state.lastY + ele.offsetHeight / 1.4) / (ele.offsetHeight + 50)
     );
 
-    if (page !== currentPageRef.current) {
-      setCurrentPage(page);
+    if (pageNum !== currentPageRef.current) {
+      setCurrentPage(pageNum);
     }
   };
 

+ 1 - 1
store/initialPdfState.ts

@@ -12,7 +12,7 @@ export type StateType = {
 };
 
 export default {
-  totalPage: 1,
+  totalPage: 0,
   currentPage: 1,
   pdf: null,
   progress: {