feat: support pdf zoom in mobile (#990)
Reviewed-on: daoyoucloud/tachybase#990
This commit is contained in:
		
							parent
							
								
									04a6f3f09a
								
							
						
					
					
						commit
						d0bb8038ab
					
				@ -36,6 +36,7 @@
 | 
			
		||||
    "react-pdf": "^7.5.1",
 | 
			
		||||
    "react-router-dom": "^6.11.2",
 | 
			
		||||
    "react-transition-group": "^4.4.5",
 | 
			
		||||
    "react-zoom-pan-pinch": "^3.4.4",
 | 
			
		||||
    "redis": "^4.6.11",
 | 
			
		||||
    "signature_pad": "4.1.7",
 | 
			
		||||
    "throttle-debounce": "^5.0.0",
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,14 @@
 | 
			
		||||
import React, { forwardRef, useEffect, useImperativeHandle, useState } from 'react';
 | 
			
		||||
import { Spin } from 'antd';
 | 
			
		||||
import { Spin, Tag } from 'antd';
 | 
			
		||||
import { LoadingOutlined } from '@ant-design/icons';
 | 
			
		||||
import { Document, Page, pdfjs } from 'react-pdf';
 | 
			
		||||
import { saveAs } from 'file-saver';
 | 
			
		||||
import 'react-pdf/dist/Page/AnnotationLayer.css';
 | 
			
		||||
import 'react-pdf/dist/Page/TextLayer.css';
 | 
			
		||||
import { uid } from '@tachybase/schema';
 | 
			
		||||
import { useRequest } from '@tachybase/client';
 | 
			
		||||
import { css, useRequest } from '@tachybase/client';
 | 
			
		||||
import { useTranslation } from '../locale';
 | 
			
		||||
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch';
 | 
			
		||||
 | 
			
		||||
const options = {
 | 
			
		||||
  cMapUrl: '/cmaps/',
 | 
			
		||||
@ -79,28 +80,48 @@ export const PDFViewer = forwardRef<PDFViewerRef, PDFViewerProps>((props, ref) =
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <LoadingSpin spinning={loading}>
 | 
			
		||||
      <Document
 | 
			
		||||
        options={options}
 | 
			
		||||
        file={data as ArrayBuffer}
 | 
			
		||||
        loading={() => (
 | 
			
		||||
          <LoadingSpin spinning={true}>
 | 
			
		||||
            <div style={{ height: '100vh' }}></div>
 | 
			
		||||
          </LoadingSpin>
 | 
			
		||||
        )}
 | 
			
		||||
        onLoadSuccess={async (doc) => {
 | 
			
		||||
          setNumPages(doc.numPages);
 | 
			
		||||
        }}
 | 
			
		||||
        noData={<div style={{ height: '100vh' }}></div>}
 | 
			
		||||
        error={<div>{t('error')}</div>}
 | 
			
		||||
      <TransformWrapper
 | 
			
		||||
        wheel={{ disabled: true }}
 | 
			
		||||
        doubleClick={{ disabled: true }}
 | 
			
		||||
        panning={{ allowLeftClickPan: false }}
 | 
			
		||||
      >
 | 
			
		||||
        {Array.from(new Array(numPages), (el, index) => (
 | 
			
		||||
          <Page key={`page_${index + 1}`} pageNumber={index + 1} width={width}>
 | 
			
		||||
            <p style={{ marginLeft: '92%', marginBottom: '30pt', fontSize: '14px', fontFamily: 'source-han-sans' }}>
 | 
			
		||||
              {index + 1}/{numPages}页
 | 
			
		||||
            </p>
 | 
			
		||||
          </Page>
 | 
			
		||||
        ))}
 | 
			
		||||
      </Document>
 | 
			
		||||
        <TransformComponent>
 | 
			
		||||
          <Document
 | 
			
		||||
            options={options}
 | 
			
		||||
            file={data as ArrayBuffer}
 | 
			
		||||
            loading={() => (
 | 
			
		||||
              <LoadingSpin spinning={true}>
 | 
			
		||||
                <div style={{ height: '100vh' }}></div>
 | 
			
		||||
              </LoadingSpin>
 | 
			
		||||
            )}
 | 
			
		||||
            onLoadSuccess={async (doc) => {
 | 
			
		||||
              setNumPages(doc.numPages);
 | 
			
		||||
            }}
 | 
			
		||||
            noData={<div style={{ height: '100vh' }}></div>}
 | 
			
		||||
            error={<div>{t('error')}</div>}
 | 
			
		||||
          >
 | 
			
		||||
            {Array.from(new Array(numPages), (el, index) => (
 | 
			
		||||
              <Page key={`page_${index + 1}`} pageNumber={index + 1} width={width}>
 | 
			
		||||
                <div
 | 
			
		||||
                  className={css`
 | 
			
		||||
                    text-align: center;
 | 
			
		||||
                    border-bottom: 1px dashed;
 | 
			
		||||
                  `}
 | 
			
		||||
                >
 | 
			
		||||
                  <Tag
 | 
			
		||||
                    className={css`
 | 
			
		||||
                      margin-bottom: 2px;
 | 
			
		||||
                    `}
 | 
			
		||||
                    bordered={false}
 | 
			
		||||
                  >
 | 
			
		||||
                    第 {index + 1}/{numPages} 页
 | 
			
		||||
                  </Tag>
 | 
			
		||||
                </div>
 | 
			
		||||
              </Page>
 | 
			
		||||
            ))}
 | 
			
		||||
          </Document>
 | 
			
		||||
        </TransformComponent>
 | 
			
		||||
      </TransformWrapper>
 | 
			
		||||
    </LoadingSpin>
 | 
			
		||||
  );
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { Plugin, EditTitleField } from '@tachybase/client';
 | 
			
		||||
import { Plugin, EditTitleField, CollectionProvider, CollectionRecordProvider } from '@tachybase/client';
 | 
			
		||||
import { useFieldSchema } from '@tachybase/schema';
 | 
			
		||||
import { isValid } from '@tachybase/schema';
 | 
			
		||||
import { autorun } from '@tachybase/schema';
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@ import { PDFViewer } from '../../components/PDFViewer';
 | 
			
		||||
import { Space } from 'antd';
 | 
			
		||||
import { css } from '@tachybase/client';
 | 
			
		||||
import { usePDFViewerRef } from '../../schema-initializer/blocks/PDFVIewerBlockInitializer';
 | 
			
		||||
import { debounce } from 'lodash';
 | 
			
		||||
 | 
			
		||||
export const InternalPDFViewer = (props) => {
 | 
			
		||||
  const { usePdfPath: useMaybePdfPath } = props;
 | 
			
		||||
@ -10,10 +11,19 @@ export const InternalPDFViewer = (props) => {
 | 
			
		||||
  const [width, setWidth] = useState(0);
 | 
			
		||||
  const [, setHeight] = useState(0);
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    if (containerRef.current) {
 | 
			
		||||
    const updateUI = debounce(() => {
 | 
			
		||||
      setWidth(containerRef.current.offsetWidth);
 | 
			
		||||
      setHeight(containerRef.current.offsetHeight);
 | 
			
		||||
    }, 200);
 | 
			
		||||
    const observer = new ResizeObserver(() => {
 | 
			
		||||
      updateUI();
 | 
			
		||||
    });
 | 
			
		||||
    if (containerRef.current) {
 | 
			
		||||
      observer.observe(containerRef.current);
 | 
			
		||||
    }
 | 
			
		||||
    return () => {
 | 
			
		||||
      observer.disconnect();
 | 
			
		||||
    };
 | 
			
		||||
  }, [containerRef]);
 | 
			
		||||
  const ref = usePDFViewerRef();
 | 
			
		||||
  const usePdfPath = useMaybePdfPath ?? (() => '');
 | 
			
		||||
 | 
			
		||||
@ -1610,6 +1610,9 @@ importers:
 | 
			
		||||
      react-transition-group:
 | 
			
		||||
        specifier: ^4.4.5
 | 
			
		||||
        version: 4.4.5(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
      react-zoom-pan-pinch:
 | 
			
		||||
        specifier: ^3.4.4
 | 
			
		||||
        version: 3.4.4(react-dom@18.2.0)(react@18.2.0)
 | 
			
		||||
      redis:
 | 
			
		||||
        specifier: ^4.6.11
 | 
			
		||||
        version: 4.6.13
 | 
			
		||||
@ -26700,6 +26703,17 @@ packages:
 | 
			
		||||
      react-dom: 18.2.0(react@18.2.0)
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /react-zoom-pan-pinch@3.4.4(react-dom@18.2.0)(react@18.2.0):
 | 
			
		||||
    resolution: {integrity: sha512-lGTu7D9lQpYEQ6sH+NSlLA7gicgKRW8j+D/4HO1AbSV2POvKRFzdWQ8eI0r3xmOsl4dYQcY+teV6MhULeg1xBw==}
 | 
			
		||||
    engines: {node: '>=8', npm: '>=5'}
 | 
			
		||||
    peerDependencies:
 | 
			
		||||
      react: '*'
 | 
			
		||||
      react-dom: '*'
 | 
			
		||||
    dependencies:
 | 
			
		||||
      react: 18.2.0
 | 
			
		||||
      react-dom: 18.2.0(react@18.2.0)
 | 
			
		||||
    dev: true
 | 
			
		||||
 | 
			
		||||
  /react@18.1.0:
 | 
			
		||||
    resolution: {integrity: sha512-4oL8ivCz5ZEPyclFQXaNksK3adutVS8l2xzZU0cqEFrE9Sb7fC0EFK5uEk74wIreL1DERyjvsU915j1pcT2uEQ==}
 | 
			
		||||
    engines: {node: '>=0.10.0'}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user