react-3d-flipbook 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1005 -0
- package/dist/components/BookmarksPanel.d.ts +21 -0
- package/dist/components/Flipbook.d.ts +5 -0
- package/dist/components/SearchPanel.d.ts +26 -0
- package/dist/components/TableOfContents.d.ts +13 -0
- package/dist/components/ThumbnailsPanel.d.ts +14 -0
- package/dist/components/WebGLPageFlip.d.ts +46 -0
- package/dist/components/index.d.ts +12 -0
- package/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/useAutoplay.d.ts +58 -0
- package/dist/hooks/useFlipbook.d.ts +48 -0
- package/dist/hooks/usePdfLoader.d.ts +127 -0
- package/dist/index.d.ts +1121 -0
- package/dist/index.esm.js +25056 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +25121 -0
- package/dist/index.js.map +1 -0
- package/dist/setupTests.d.ts +1 -0
- package/dist/types/index.d.ts +481 -0
- package/dist/utils/index.d.ts +131 -0
- package/dist/utils/pdfUtils.d.ts +158 -0
- package/package.json +122 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FlipbookPage } from '../types';
|
|
3
|
+
export interface Bookmark {
|
|
4
|
+
page: number;
|
|
5
|
+
title?: string;
|
|
6
|
+
createdAt: Date;
|
|
7
|
+
note?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface BookmarksPanelProps {
|
|
10
|
+
pages: FlipbookPage[];
|
|
11
|
+
bookmarks: number[];
|
|
12
|
+
currentPage: number;
|
|
13
|
+
isOpen: boolean;
|
|
14
|
+
position?: 'left' | 'right';
|
|
15
|
+
showThumbnails?: boolean;
|
|
16
|
+
onPageSelect: (page: number) => void;
|
|
17
|
+
onRemoveBookmark: (page: number) => void;
|
|
18
|
+
onClose: () => void;
|
|
19
|
+
}
|
|
20
|
+
declare const BookmarksPanel: React.FC<BookmarksPanelProps>;
|
|
21
|
+
export default BookmarksPanel;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { FlipbookPage } from "../types";
|
|
3
|
+
export interface SearchResult {
|
|
4
|
+
pageNumber: number;
|
|
5
|
+
pageIndex: number;
|
|
6
|
+
text: string;
|
|
7
|
+
matchIndex: number;
|
|
8
|
+
contextBefore: string;
|
|
9
|
+
contextAfter: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SearchPanelProps {
|
|
12
|
+
pages: FlipbookPage[];
|
|
13
|
+
pageTextContent?: Map<number, string>;
|
|
14
|
+
currentPage: number;
|
|
15
|
+
isOpen: boolean;
|
|
16
|
+
position?: "left" | "right";
|
|
17
|
+
minQueryLength?: number;
|
|
18
|
+
maxResults?: number;
|
|
19
|
+
highlightColor?: string;
|
|
20
|
+
onPageSelect: (page: number) => void;
|
|
21
|
+
onClose: () => void;
|
|
22
|
+
onSearchStart?: () => void;
|
|
23
|
+
onSearchEnd?: (results: SearchResult[]) => void;
|
|
24
|
+
}
|
|
25
|
+
declare const SearchPanel: React.FC<SearchPanelProps>;
|
|
26
|
+
export default SearchPanel;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { TocItem } from '../types';
|
|
3
|
+
export interface TableOfContentsProps {
|
|
4
|
+
items: TocItem[];
|
|
5
|
+
currentPage: number;
|
|
6
|
+
isOpen: boolean;
|
|
7
|
+
position?: 'left' | 'right';
|
|
8
|
+
closeOnClick?: boolean;
|
|
9
|
+
onPageSelect: (page: number) => void;
|
|
10
|
+
onClose: () => void;
|
|
11
|
+
}
|
|
12
|
+
declare const TableOfContents: React.FC<TableOfContentsProps>;
|
|
13
|
+
export default TableOfContents;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { FlipbookPage } from '../types';
|
|
3
|
+
export interface ThumbnailsPanelProps {
|
|
4
|
+
pages: FlipbookPage[];
|
|
5
|
+
currentPage: number;
|
|
6
|
+
isOpen: boolean;
|
|
7
|
+
position?: 'left' | 'right';
|
|
8
|
+
thumbnailSize?: number;
|
|
9
|
+
showPageNumbers?: boolean;
|
|
10
|
+
onPageSelect: (page: number) => void;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
}
|
|
13
|
+
declare const ThumbnailsPanel: React.FC<ThumbnailsPanelProps>;
|
|
14
|
+
export default ThumbnailsPanel;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { FlipbookPage } from "../types";
|
|
2
|
+
export interface WebGLPageFlipProps {
|
|
3
|
+
pages: FlipbookPage[];
|
|
4
|
+
currentPage: number;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
singlePageMode?: boolean;
|
|
8
|
+
flipDuration?: number;
|
|
9
|
+
pageHardness?: number;
|
|
10
|
+
coverHardness?: number;
|
|
11
|
+
pageSegmentsW?: number;
|
|
12
|
+
pageSegmentsH?: number;
|
|
13
|
+
shadows?: boolean;
|
|
14
|
+
shadowOpacity?: number;
|
|
15
|
+
lights?: boolean;
|
|
16
|
+
lightIntensity?: number;
|
|
17
|
+
lightColor?: number;
|
|
18
|
+
pageRoughness?: number;
|
|
19
|
+
pageMetalness?: number;
|
|
20
|
+
antialias?: boolean;
|
|
21
|
+
backgroundColor?: string;
|
|
22
|
+
/** Camera zoom/margin factor - higher values move camera further back (default: 1.35) */
|
|
23
|
+
cameraZoom?: number;
|
|
24
|
+
/** Base page scale in world units - affects overall page size (default: 6) */
|
|
25
|
+
pageScale?: number;
|
|
26
|
+
/** Camera vertical position offset (default: 0) */
|
|
27
|
+
cameraPositionY?: number;
|
|
28
|
+
/** Camera look-at Y position (default: 0) */
|
|
29
|
+
cameraLookAtY?: number;
|
|
30
|
+
/** Field of view in degrees (default: 45) */
|
|
31
|
+
cameraFov?: number;
|
|
32
|
+
onFlipStart?: (page: number, direction: "next" | "prev") => void;
|
|
33
|
+
onFlipEnd?: (page: number) => void;
|
|
34
|
+
onPageChange?: (page: number) => void;
|
|
35
|
+
}
|
|
36
|
+
export interface WebGLPageFlipInstance {
|
|
37
|
+
flipNext: () => void;
|
|
38
|
+
flipPrev: () => void;
|
|
39
|
+
flipToPage: (page: number) => void;
|
|
40
|
+
flipToFirst: () => void;
|
|
41
|
+
flipToLast: () => void;
|
|
42
|
+
isFlipping: () => boolean;
|
|
43
|
+
dispose: () => void;
|
|
44
|
+
}
|
|
45
|
+
declare const WebGLPageFlip: import("react").ForwardRefExoticComponent<WebGLPageFlipProps & import("react").RefAttributes<WebGLPageFlipInstance>>;
|
|
46
|
+
export default WebGLPageFlip;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export { default as Flipbook } from "./Flipbook";
|
|
2
|
+
export type { default as FlipbookComponent } from "./Flipbook";
|
|
3
|
+
export { default as WebGLPageFlip } from "./WebGLPageFlip";
|
|
4
|
+
export type { WebGLPageFlipProps, WebGLPageFlipInstance, } from "./WebGLPageFlip";
|
|
5
|
+
export { default as ThumbnailsPanel } from "./ThumbnailsPanel";
|
|
6
|
+
export type { ThumbnailsPanelProps } from "./ThumbnailsPanel";
|
|
7
|
+
export { default as TableOfContents } from "./TableOfContents";
|
|
8
|
+
export type { TableOfContentsProps } from "./TableOfContents";
|
|
9
|
+
export { default as SearchPanel } from "./SearchPanel";
|
|
10
|
+
export type { SearchPanelProps, SearchResult } from "./SearchPanel";
|
|
11
|
+
export { default as BookmarksPanel } from "./BookmarksPanel";
|
|
12
|
+
export type { BookmarksPanelProps, Bookmark } from "./BookmarksPanel";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { useFlipbook, useSwipeGesture, useWheelZoom, useResizeObserver, } from "./useFlipbook";
|
|
2
|
+
export { useAutoplay } from "./useAutoplay";
|
|
3
|
+
export type { UseAutoplayOptions, UseAutoplayReturn } from "./useAutoplay";
|
|
4
|
+
export { usePdfLoader } from "./usePdfLoader";
|
|
5
|
+
export type { UsePdfLoaderOptions, UsePdfLoaderReturn } from "./usePdfLoader";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export interface UseAutoplayOptions {
|
|
2
|
+
/** Total number of pages */
|
|
3
|
+
numPages: number;
|
|
4
|
+
/** Current page number (1-based) */
|
|
5
|
+
currentPage: number;
|
|
6
|
+
/** Interval between page flips in milliseconds */
|
|
7
|
+
interval?: number;
|
|
8
|
+
/** Whether to loop back to the first page after the last */
|
|
9
|
+
loop?: boolean;
|
|
10
|
+
/** Whether to start autoplay automatically */
|
|
11
|
+
autoStart?: boolean;
|
|
12
|
+
/** Number of pages to flip at a time (1 for single, 2 for spread) */
|
|
13
|
+
pageIncrement?: number;
|
|
14
|
+
/** Whether the flipbook is in right-to-left mode */
|
|
15
|
+
rightToLeft?: boolean;
|
|
16
|
+
/** Callback when page should change */
|
|
17
|
+
onPageChange: (page: number) => void;
|
|
18
|
+
/** Callback when autoplay starts */
|
|
19
|
+
onStart?: () => void;
|
|
20
|
+
/** Callback when autoplay stops */
|
|
21
|
+
onStop?: () => void;
|
|
22
|
+
/** Callback when autoplay pauses */
|
|
23
|
+
onPause?: () => void;
|
|
24
|
+
/** Callback when autoplay resumes */
|
|
25
|
+
onResume?: () => void;
|
|
26
|
+
/** Callback when autoplay completes (reaches end without loop) */
|
|
27
|
+
onComplete?: () => void;
|
|
28
|
+
}
|
|
29
|
+
export interface UseAutoplayReturn {
|
|
30
|
+
/** Whether autoplay is currently active */
|
|
31
|
+
isPlaying: boolean;
|
|
32
|
+
/** Whether autoplay is paused */
|
|
33
|
+
isPaused: boolean;
|
|
34
|
+
/** Current autoplay interval in milliseconds */
|
|
35
|
+
interval: number;
|
|
36
|
+
/** Time remaining until next page flip (ms) */
|
|
37
|
+
timeRemaining: number;
|
|
38
|
+
/** Progress through current interval (0-1) */
|
|
39
|
+
progress: number;
|
|
40
|
+
/** Start autoplay */
|
|
41
|
+
start: () => void;
|
|
42
|
+
/** Stop autoplay completely */
|
|
43
|
+
stop: () => void;
|
|
44
|
+
/** Pause autoplay (can resume) */
|
|
45
|
+
pause: () => void;
|
|
46
|
+
/** Resume paused autoplay */
|
|
47
|
+
resume: () => void;
|
|
48
|
+
/** Toggle between play and pause */
|
|
49
|
+
toggle: () => void;
|
|
50
|
+
/** Set the autoplay interval */
|
|
51
|
+
setInterval: (ms: number) => void;
|
|
52
|
+
/** Skip to next page immediately */
|
|
53
|
+
skipNext: () => void;
|
|
54
|
+
/** Reset autoplay to beginning */
|
|
55
|
+
reset: () => void;
|
|
56
|
+
}
|
|
57
|
+
export declare function useAutoplay(options: UseAutoplayOptions): UseAutoplayReturn;
|
|
58
|
+
export default useAutoplay;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FlipbookInstance, FlipbookOptions, FlipbookPage } from "../types";
|
|
2
|
+
interface UseFlipbookOptions extends Partial<FlipbookOptions> {
|
|
3
|
+
pages: FlipbookPage[];
|
|
4
|
+
initialPage?: number;
|
|
5
|
+
onPageChange?: (page: number) => void;
|
|
6
|
+
onZoomChange?: (zoom: number) => void;
|
|
7
|
+
onFullscreenChange?: (isFullscreen: boolean) => void;
|
|
8
|
+
}
|
|
9
|
+
interface UseFlipbookReturn {
|
|
10
|
+
currentPage: number;
|
|
11
|
+
numPages: number;
|
|
12
|
+
zoom: number;
|
|
13
|
+
isFullscreen: boolean;
|
|
14
|
+
isLoading: boolean;
|
|
15
|
+
isAnimating: boolean;
|
|
16
|
+
canGoNext: boolean;
|
|
17
|
+
canGoPrev: boolean;
|
|
18
|
+
bookmarkedPages: number[];
|
|
19
|
+
containerRef: React.RefObject<HTMLDivElement>;
|
|
20
|
+
nextPage: () => void;
|
|
21
|
+
prevPage: () => void;
|
|
22
|
+
firstPage: () => void;
|
|
23
|
+
lastPage: () => void;
|
|
24
|
+
goToPage: (page: number) => void;
|
|
25
|
+
setCurrentPageDirect: (page: number) => void;
|
|
26
|
+
zoomIn: () => void;
|
|
27
|
+
zoomOut: () => void;
|
|
28
|
+
zoomTo: (zoom: number) => void;
|
|
29
|
+
resetZoom: () => void;
|
|
30
|
+
toggleFullscreen: () => void;
|
|
31
|
+
enterFullscreen: () => void;
|
|
32
|
+
exitFullscreenMode: () => void;
|
|
33
|
+
toggleBookmark: (page?: number) => void;
|
|
34
|
+
isPageBookmarked: (page: number) => boolean;
|
|
35
|
+
preloadPages: (pageIndices: number[]) => Promise<void>;
|
|
36
|
+
getInstance: () => FlipbookInstance;
|
|
37
|
+
}
|
|
38
|
+
export declare function useFlipbook(options: UseFlipbookOptions): UseFlipbookReturn;
|
|
39
|
+
export declare function useSwipeGesture(containerRef: React.RefObject<HTMLElement>, onSwipeLeft: () => void, onSwipeRight: () => void, options?: {
|
|
40
|
+
threshold?: number;
|
|
41
|
+
enabled?: boolean;
|
|
42
|
+
}): void;
|
|
43
|
+
export declare function useWheelZoom(containerRef: React.RefObject<HTMLElement>, onZoom: (delta: number) => void, options?: {
|
|
44
|
+
enabled?: boolean;
|
|
45
|
+
sensitivity?: number;
|
|
46
|
+
}): void;
|
|
47
|
+
export declare function useResizeObserver(ref: React.RefObject<HTMLElement>, callback: (entry: ResizeObserverEntry) => void): void;
|
|
48
|
+
export {};
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { FlipbookPage } from "../types";
|
|
2
|
+
interface PDFDocumentProxy {
|
|
3
|
+
numPages: number;
|
|
4
|
+
getPage: (pageNumber: number) => Promise<PDFPageProxy>;
|
|
5
|
+
destroy: () => Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
interface PDFPageProxy {
|
|
8
|
+
getViewport: (options: {
|
|
9
|
+
scale: number;
|
|
10
|
+
rotation?: number;
|
|
11
|
+
}) => PDFPageViewport;
|
|
12
|
+
render: (params: PDFRenderParams) => PDFRenderTask;
|
|
13
|
+
getTextContent: (params?: {
|
|
14
|
+
normalizeWhitespace?: boolean;
|
|
15
|
+
}) => Promise<PDFTextContent>;
|
|
16
|
+
cleanup: () => void;
|
|
17
|
+
}
|
|
18
|
+
interface PDFPageViewport {
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
scale: number;
|
|
22
|
+
rotation: number;
|
|
23
|
+
viewBox: number[];
|
|
24
|
+
transform: number[];
|
|
25
|
+
clone: (options?: {
|
|
26
|
+
scale?: number;
|
|
27
|
+
rotation?: number;
|
|
28
|
+
}) => PDFPageViewport;
|
|
29
|
+
}
|
|
30
|
+
interface PDFRenderParams {
|
|
31
|
+
canvasContext: CanvasRenderingContext2D;
|
|
32
|
+
viewport: PDFPageViewport;
|
|
33
|
+
enableWebGL?: boolean;
|
|
34
|
+
renderInteractiveForms?: boolean;
|
|
35
|
+
transform?: number[];
|
|
36
|
+
}
|
|
37
|
+
interface PDFRenderTask {
|
|
38
|
+
promise: Promise<void>;
|
|
39
|
+
cancel: () => void;
|
|
40
|
+
}
|
|
41
|
+
interface PDFTextContent {
|
|
42
|
+
items: PDFTextItem[];
|
|
43
|
+
styles: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
interface PDFTextItem {
|
|
46
|
+
str: string;
|
|
47
|
+
dir: string;
|
|
48
|
+
transform: number[];
|
|
49
|
+
width: number;
|
|
50
|
+
height: number;
|
|
51
|
+
fontName: string;
|
|
52
|
+
}
|
|
53
|
+
interface PDFDocumentLoadingTask {
|
|
54
|
+
promise: Promise<PDFDocumentProxy>;
|
|
55
|
+
destroy: () => Promise<void>;
|
|
56
|
+
onProgress?: (progress: {
|
|
57
|
+
loaded: number;
|
|
58
|
+
total: number;
|
|
59
|
+
}) => void;
|
|
60
|
+
}
|
|
61
|
+
interface PDFJSLib {
|
|
62
|
+
getDocument: (src: string | {
|
|
63
|
+
url: string;
|
|
64
|
+
[key: string]: unknown;
|
|
65
|
+
} | ArrayBuffer | Uint8Array) => PDFDocumentLoadingTask;
|
|
66
|
+
GlobalWorkerOptions: {
|
|
67
|
+
workerSrc: string;
|
|
68
|
+
};
|
|
69
|
+
version: string;
|
|
70
|
+
}
|
|
71
|
+
declare global {
|
|
72
|
+
interface Window {
|
|
73
|
+
pdfjsLib?: PDFJSLib;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export interface UsePdfLoaderOptions {
|
|
77
|
+
/** PDF file URL or ArrayBuffer */
|
|
78
|
+
source: string | ArrayBuffer | Uint8Array | null;
|
|
79
|
+
/** PDF.js worker source URL (required for PDF.js to work) */
|
|
80
|
+
workerSrc?: string;
|
|
81
|
+
/** Scale factor for rendering pages (default: 1.5) */
|
|
82
|
+
scale?: number;
|
|
83
|
+
/** Whether to extract text content for search */
|
|
84
|
+
extractText?: boolean;
|
|
85
|
+
/** Maximum texture size for page rendering */
|
|
86
|
+
maxTextureSize?: number;
|
|
87
|
+
/** Callback when loading starts */
|
|
88
|
+
onLoadStart?: () => void;
|
|
89
|
+
/** Callback for loading progress */
|
|
90
|
+
onLoadProgress?: (progress: number) => void;
|
|
91
|
+
/** Callback when loading completes */
|
|
92
|
+
onLoadComplete?: (numPages: number) => void;
|
|
93
|
+
/** Callback when loading fails */
|
|
94
|
+
onLoadError?: (error: Error) => void;
|
|
95
|
+
/** Callback when a page is rendered */
|
|
96
|
+
onPageRendered?: (pageNumber: number, dataUrl: string) => void;
|
|
97
|
+
}
|
|
98
|
+
export interface UsePdfLoaderReturn {
|
|
99
|
+
/** Whether PDF.js is available */
|
|
100
|
+
isAvailable: boolean;
|
|
101
|
+
/** Whether the PDF is currently loading */
|
|
102
|
+
isLoading: boolean;
|
|
103
|
+
/** Loading progress (0-1) */
|
|
104
|
+
progress: number;
|
|
105
|
+
/** Any error that occurred during loading */
|
|
106
|
+
error: Error | null;
|
|
107
|
+
/** Number of pages in the PDF */
|
|
108
|
+
numPages: number;
|
|
109
|
+
/** Generated flipbook pages */
|
|
110
|
+
pages: FlipbookPage[];
|
|
111
|
+
/** Text content extracted from pages (for search) */
|
|
112
|
+
textContent: Map<number, string>;
|
|
113
|
+
/** Load a PDF from a source */
|
|
114
|
+
loadPdf: (source: string | ArrayBuffer | Uint8Array) => Promise<void>;
|
|
115
|
+
/** Render a specific page to canvas/image */
|
|
116
|
+
renderPage: (pageNumber: number, options?: {
|
|
117
|
+
scale?: number;
|
|
118
|
+
format?: "png" | "jpeg";
|
|
119
|
+
quality?: number;
|
|
120
|
+
}) => Promise<string>;
|
|
121
|
+
/** Get text content from a specific page */
|
|
122
|
+
getPageText: (pageNumber: number) => Promise<string>;
|
|
123
|
+
/** Cleanup and destroy the PDF document */
|
|
124
|
+
destroy: () => void;
|
|
125
|
+
}
|
|
126
|
+
export declare function usePdfLoader(options?: UsePdfLoaderOptions): UsePdfLoaderReturn;
|
|
127
|
+
export default usePdfLoader;
|