@jaymanyoo/pdf-book-viewer
Version:
A React-compatible library for displaying PDFs as realistic flip books with 3D page turning animations
270 lines (212 loc) • 7.35 kB
Markdown
# @jaymanyoo/pdf-book-viewer
A React-compatible library for displaying PDFs as realistic flip books with 3D page turning animations.
## Features
- 🔄 **Realistic page flipping** - Smooth 3D animations using PageFlip library
- 📄 **Smart page handling** - Automatically detects portrait vs landscape pages
- 📱 **Mobile friendly** - Touch/swipe gestures and responsive design
- ⌨️ **Keyboard navigation** - Arrow keys for page navigation
- 🎨 **Customizable** - Configurable dimensions and animations
- 🚀 **Easy integration** - Simple API, works with any PDF source
- ⚛️ **React support** - Full React component with TypeScript support
## Installation
```bash
npm install @jaymanyoo/pdf-book-viewer pdfjs-dist
# or
yarn add @jaymanyoo/pdf-book-viewer pdfjs-dist
```
**Note:** `pdfjs-dist` is a required peer dependency that must be installed separately.
## Quick Start
### React Usage
```jsx
import React, { useState } from 'react';
import { ReactPDFBookViewer } from '@jaymanyoo/pdf-book-viewer/react';
function App() {
const [selectedFile, setSelectedFile] = useState(null);
const handleFileSelect = (event) => {
const file = event.target.files?.[0];
if (file && file.type === 'application/pdf') {
setSelectedFile(file);
}
};
return (
<div>
<input type="file" accept=".pdf" onChange={handleFileSelect} />
{selectedFile && (
<ReactPDFBookViewer
source={selectedFile}
width={800}
height={600}
onPageChange={(page, total) => {
console.log(`Page ${page} of ${total}`);
}}
onLoadStart={() => console.log('Loading...')}
onLoadEnd={() => console.log('Loaded!')}
onError={(error) => console.error('Error:', error)}
/>
)}
</div>
);
}
```
### Loading from URL
```jsx
<ReactPDFBookViewer
source="https://example.com/document.pdf"
width={800}
height={600}
onPageChange={(page, total) => {
console.log(`Page ${page} of ${total}`);
}}
/>
```
### TypeScript Support
```tsx
import React, { useRef } from 'react';
import { ReactPDFBookViewer, PDFBookViewerMethods, ReactPDFBookViewerProps } from '@jaymanyoo/pdf-book-viewer/react';
interface MyViewerProps {
pdfUrl: string;
onComplete?: () => void;
}
const MyTypedViewer: React.FC<MyViewerProps> = ({ pdfUrl, onComplete }) => {
const viewerRef = useRef<PDFBookViewerMethods>(null);
const handleNextPage = () => {
viewerRef.current?.nextPage();
};
const handlePrevPage = () => {
viewerRef.current?.prevPage();
};
return (
<div>
<button onClick={handlePrevPage}>Previous</button>
<button onClick={handleNextPage}>Next</button>
<ReactPDFBookViewer
ref={viewerRef}
source={pdfUrl}
width={800}
height={600}
onLoadEnd={onComplete}
/>
</div>
);
};
```
## Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `source` | `string \| File` | - | PDF source (URL or File object) |
| `width` | `number` | `400` | Viewer width in pixels |
| `height` | `number` | `600` | Viewer height in pixels |
| `onPageChange` | `(page: number, total: number) => void` | - | Called when page changes |
| `onLoadStart` | `() => void` | - | Called when PDF loading starts |
| `onLoadEnd` | `() => void` | - | Called when PDF loading completes |
| `onError` | `(error: Error) => void` | - | Called when an error occurs |
| `style` | `React.CSSProperties` | - | Custom styles for the container |
| `className` | `string` | `''` | CSS class for the container |
## Ref Methods
When using a ref, you can access these methods:
```tsx
const viewerRef = useRef<PDFBookViewerMethods>(null);
// Navigation
viewerRef.current?.nextPage(); // Go to next page
viewerRef.current?.prevPage(); // Go to previous page
viewerRef.current?.goToPage(5); // Go to specific page
// Loading
viewerRef.current?.load(file); // Load new PDF
// State
const current = viewerRef.current?.getCurrentPage(); // Get current page
const total = viewerRef.current?.getTotalPages(); // Get total pages
// Cleanup
viewerRef.current?.destroy(); // Clean up resources
```
## Import Paths
```javascript
// React component
import { ReactPDFBookViewer } from '@jaymanyoo/pdf-book-viewer/react';
// TypeScript types
import type {
ReactPDFBookViewerProps,
PDFBookViewerMethods
} from '@jaymanyoo/pdf-book-viewer/react';
```
## Page Handling
The viewer automatically handles different page orientations:
- **Portrait pages**: First/middle pages show on the right with transparent left, last page shows on left with transparent right
- **Landscape pages**: Automatically split into left and right halves
- **Mixed orientations**: Seamlessly handles PDFs with both portrait and landscape pages
## Interactions
- **Mouse**: Click and drag to flip pages
- **Touch**: Swipe gestures on mobile devices
- **Keyboard**: Arrow keys for navigation (when focused)
## Browser Support
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
## Dependencies
- **pdfjs-dist** (peer dependency) - For PDF rendering
- **PageFlip library** - Automatically loaded from CDN for 3D animations
- **React** (peer dependency) - For React components
## Examples
Complete example with file upload and URL loading:
```jsx
import React, { useState } from 'react';
import { ReactPDFBookViewer } from '@jaymanyoo/pdf-book-viewer/react';
function PDFViewerExample() {
const [selectedFile, setSelectedFile] = useState(null);
const [urlInput, setUrlInput] = useState('');
const handleFileSelect = (event) => {
const file = event.target.files?.[0];
if (file && file.type === 'application/pdf') {
setSelectedFile(file);
}
};
const loadFromURL = () => {
if (urlInput.trim()) {
setSelectedFile(urlInput.trim());
}
};
const loadSample = () => {
const sampleURL = 'https://mozilla.github.io/pdf.js/web/compressed.tracemonkey-pldi-09.pdf';
setSelectedFile(sampleURL);
setUrlInput(sampleURL);
};
return (
<div style={{ padding: '20px' }}>
<div style={{ marginBottom: '20px' }}>
<h3>Upload PDF File</h3>
<input type="file" accept=".pdf" onChange={handleFileSelect} />
</div>
<div style={{ marginBottom: '20px' }}>
<h3>Load from URL</h3>
<input
type="text"
value={urlInput}
onChange={(e) => setUrlInput(e.target.value)}
placeholder="Enter PDF URL"
style={{ width: '300px', marginRight: '10px' }}
/>
<button onClick={loadFromURL}>Load</button>
</div>
<div style={{ marginBottom: '20px' }}>
<button onClick={loadSample}>Load Sample PDF</button>
</div>
{selectedFile && (
<ReactPDFBookViewer
source={selectedFile}
width={800}
height={600}
onPageChange={(page, total) => {
console.log(`Page ${page} of ${total}`);
}}
onLoadStart={() => console.log('Loading PDF...')}
onLoadEnd={() => console.log('PDF loaded successfully!')}
onError={(error) => console.error('PDF loading error:', error)}
/>
)}
</div>
);
}
export default PDFViewerExample;
```
## License
MIT License