@marvellousptc/react-pageflip
v2.1.0
Published
Enhanced React.js page flip component based on StPageFlip, with single-page mode and improved touch/swipe support
Maintainers
Readme
@marvellousptc/react-pageflip
Enhanced React.js page flip component based on StPageFlip, with single-page mode and improved touch/swipe support.
Forked from Nodlik/react-pageflip, with the page-flip core vendored and modified.

What's New (compared to the original)
singlePagemode: Force single-page display with flip animation, independent of container width. Ideal for mobile reading.- Fixed portrait back-flip animation: Back-flip in portrait/single-page mode now correctly peels from the left side, matching the landscape left-page flip effect.
- Fixed
disableFlipByClickblocking swipe:disableFlipByClicknow only blocks click-to-flip; swipe gestures and programmaticflipPrev/flipNextcalls are no longer affected. - Vendored page-flip core: The
page-fliplibrary source is included directly, no external dependency needed.
Features
- Works with simple images on canvas and complex HTML blocks
- Has simple API and flexible configuration
- Compatible with mobile devices
- Supports landscape and portrait screen mode
- Supports single-page mode with full flip animation
- Supports soft and hard page types (only in HTML mode)
- No external dependencies
Installation
npm install @marvellousptc/react-pageflipBasic Usage
import HTMLFlipBook from '@marvellousptc/react-pageflip';
function MyBook(props) {
return (
<HTMLFlipBook width={300} height={500}>
<div className="demoPage">Page 1</div>
<div className="demoPage">Page 2</div>
<div className="demoPage">Page 3</div>
<div className="demoPage">Page 4</div>
</HTMLFlipBook>
);
}Single Page Mode (for mobile)
import HTMLFlipBook from '@marvellousptc/react-pageflip';
function MyBook() {
const isMobile = window.innerWidth <= 768;
return (
<HTMLFlipBook
width={300}
height={500}
size="stretch"
minWidth={300}
maxWidth={500}
minHeight={400}
maxHeight={700}
singlePage={isMobile}
usePortrait={false}
>
<div className="demoPage">Page 1</div>
<div className="demoPage">Page 2</div>
<div className="demoPage">Page 3</div>
<div className="demoPage">Page 4</div>
</HTMLFlipBook>
);
}Advanced Usage
You can define pages as a component, but in this case you should use React.forwardRef method:
const Page = React.forwardRef((props, ref) => {
return (
<div className="demoPage" ref={ref}>
<h1>Page Header</h1>
<p>{props.children}</p>
<p>Page number: {props.number}</p>
</div>
);
});
function MyBook(props) {
return (
<HTMLFlipBook width={300} height={500}>
<Page number="1">Page text</Page>
<Page number="2">Page text</Page>
<Page number="3">Page text</Page>
<Page number="4">Page text</Page>
</HTMLFlipBook>
);
}Props
| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| width | number | required | Page width |
| height | number | required | Page height |
| size | "fixed" \| "stretch" | "fixed" | Whether the book stretches to fill parent |
| minWidth, maxWidth, minHeight, maxHeight | number | — | Threshold values for size: "stretch" |
| drawShadow | boolean | true | Draw shadows when flipping |
| flippingTime | number (ms) | 1000 | Flipping animation duration |
| usePortrait | boolean | true | Enable auto-switching to portrait mode |
| singlePage | boolean | false | NEW Force single-page display with flip animation |
| startZIndex | number | 0 | Initial z-index value |
| autoSize | boolean | true | Parent element auto-sizes to book |
| maxShadowOpacity | number [0..1] | 1 | Shadow intensity |
| showCover | boolean | false | First and last pages as hard covers |
| mobileScrollSupport | boolean | true | Disable content scrolling on touch |
| swipeDistance | number (px) | 30 | Minimum swipe distance to detect |
| clickEventForward | boolean | true | Forward click events to a and button children |
| useMouseEvents | boolean | true | Enable mouse and touch events |
| disableFlipByClick | boolean | false | Disable page flip on click (swipe still works) |
| renderOnlyPageLengthChange | boolean | false | Only re-render when page count changes |
Events
function DemoBook() {
const onFlip = useCallback((e) => {
console.log('Current page: ' + e.data);
}, []);
return (
<HTMLFlipBook onFlip={onFlip}>
{/* ... pages */}
</HTMLFlipBook>
);
}Available events:
onFlip: number- triggered by page turningonChangeOrientation: ("portrait", "landscape")- triggered when orientation changesonChangeState: ("user_fold", "fold_corner", "flipping", "read")- triggered when book state changesonInit: ({page, mode})- triggered when book is initializedonUpdate: ({page, mode})- triggered when book pages are updated
Event object has two fields: data: number | string and object: PageFlip
Methods
Use React ref and pageFlip() to access methods:
function DemoBook() {
const book = useRef();
return (
<>
<button onClick={() => book.current.pageFlip().flipNext()}>
Next page
</button>
<HTMLFlipBook ref={book}>
{/* ... pages */}
</HTMLFlipBook>
</>
);
}| Method | Parameters | Return | Description |
| --- | --- | --- | --- |
| getPageCount | | number | Get total page count |
| getCurrentPageIndex | | number | Get current page index (0-based) |
| getOrientation | | string | Get orientation: portrait or landscape |
| getBoundsRect | | PageRect | Get book size and position |
| turnToPage | pageNum: number | void | Go to page (no animation) |
| turnToNextPage | | void | Next page (no animation) |
| turnToPrevPage | | void | Previous page (no animation) |
| flipNext | corner: 'top' \| 'bottom' | void | Next page (with animation) |
| flipPrev | corner: 'top' \| 'bottom' | void | Previous page (with animation) |
| flip | pageNum, corner | void | Go to page (with animation) |
| loadFromImages | images: string[] | void | Load pages from images |
| loadFromHtml | items: HTMLElement[] | void | Load pages from HTML elements |
| updateFromHtml | items: HTMLElement[] | void | Update pages from HTML elements |
| updateFromImages | images: string[] | void | Update pages from images |
| destroy | | void | Remove element and event handlers |
Credits
Based on react-pageflip by Nodlik and StPageFlip. Licensed under MIT.
