PdfPages.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import React, { useEffect, useState, useRef } from 'react';
  2. import _ from 'lodash';
  3. import Viewer from '../components/Viewer';
  4. import PdfPage from './PdfPage';
  5. import { watchScroll, scaleCheck } from '../helpers/utility';
  6. import useGestureScale from '../hooks/useGestureScale';
  7. import useActions from '../actions';
  8. import useStore from '../store';
  9. type Props = {
  10. scrollToUpdate: (state: ScrollStateType) => void;
  11. };
  12. let timer = 0;
  13. const PdfPages: React.FC<Props> = ({ scrollToUpdate }: Props) => {
  14. const [elements, setElement] = useState<React.ReactNode[]>([]);
  15. const containerRef = useRef<HTMLDivElement>(null);
  16. const [
  17. {
  18. totalPage,
  19. currentPage,
  20. scale,
  21. viewport,
  22. rotation,
  23. displayMode,
  24. annotations,
  25. },
  26. dispatch,
  27. ] = useStore();
  28. const { changeScale } = useActions(dispatch);
  29. const [zoom] = useGestureScale(containerRef);
  30. const createPages = (): void => {
  31. const pagesContent: React.ReactNode[] = [];
  32. for (let i = 1; i <= totalPage; i += 1) {
  33. const key = `page-${i}`;
  34. const component = (
  35. <PdfPage
  36. key={key}
  37. index={i}
  38. renderingState={_.range(1, 3).includes(i) ? 'RENDERING' : 'LOADING'}
  39. />
  40. );
  41. pagesContent.push(component);
  42. }
  43. setElement(pagesContent);
  44. };
  45. const updatePages = (): void => {
  46. const renderingIndexQueue = _.range(currentPage - 1, currentPage + 2);
  47. let index = currentPage - 3;
  48. const end = currentPage + 3;
  49. while (currentPage) {
  50. if (elements[index]) {
  51. const pageNum = index + 1;
  52. const key = `page-${pageNum}`;
  53. elements[index] = (
  54. <PdfPage
  55. key={key}
  56. index={pageNum}
  57. renderingState={
  58. renderingIndexQueue.includes(pageNum) ? 'RENDERING' : 'LOADING'
  59. }
  60. />
  61. );
  62. }
  63. index += 1;
  64. if (index >= end) break;
  65. }
  66. if (elements.length) {
  67. setElement([...elements]);
  68. }
  69. };
  70. useEffect(() => {
  71. createPages();
  72. watchScroll(containerRef.current, scrollToUpdate);
  73. }, []);
  74. useEffect(() => {
  75. updatePages();
  76. }, [currentPage, viewport, rotation, annotations]);
  77. useEffect(() => {
  78. if (zoom !== 0) {
  79. const viewer = containerRef.current as HTMLElement;
  80. viewer.style.transform = `scale(${1 + zoom})`;
  81. clearTimeout(timer);
  82. timer = setTimeout(() => {
  83. const targetScale = Math.round(scale * 100 + zoom * 100);
  84. changeScale(scaleCheck(targetScale));
  85. viewer.style.transform = `scale(1)`;
  86. }, 500);
  87. }
  88. }, [zoom]);
  89. return (
  90. <Viewer
  91. ref={containerRef}
  92. viewport={viewport}
  93. rotation={rotation}
  94. displayMode={displayMode}
  95. >
  96. {elements}
  97. </Viewer>
  98. );
  99. };
  100. export default PdfPages;