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