@kaktos/flipbook-react 1.0.0 → 1.0.2
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/README.md +197 -3
- package/dist/react-flipbook.cjs +1 -1
- package/dist/react-flipbook.css +1 -1
- package/dist/react-flipbook.js +863 -694
- package/dist/src/Flipbook.d.ts +1 -1
- package/dist/src/types.d.ts +5 -2
- package/dist/src/useFlipbook.d.ts +12 -3
- package/dist/src/useImageLoader.d.ts +12 -0
- package/dist/src/useViewport.d.ts +7 -0
- package/package.json +29 -4
package/README.md
CHANGED
|
@@ -1,3 +1,197 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
# @kaktos/flipbook-react
|
|
2
|
+
|
|
3
|
+
React component for 3D page flip effect. Supports touch/mouse/pointer gestures, multi-level zoom, keyboard navigation, and hi-res image switching.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm i @kaktos/flipbook-react
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import '@kaktos/flipbook-react/style.css'
|
|
15
|
+
import { Flipbook } from '@kaktos/flipbook-react'
|
|
16
|
+
|
|
17
|
+
function App() {
|
|
18
|
+
return (
|
|
19
|
+
<div style={{ width: 800, height: 600 }}>
|
|
20
|
+
<Flipbook
|
|
21
|
+
pages={[
|
|
22
|
+
'/images/1.jpg',
|
|
23
|
+
'/images/2.jpg',
|
|
24
|
+
'/images/3.jpg',
|
|
25
|
+
'/images/4.jpg',
|
|
26
|
+
]}
|
|
27
|
+
/>
|
|
28
|
+
</div>
|
|
29
|
+
)
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
> `style.css` is required. The component fills its parent container's width and height, so the parent must have explicit dimensions.
|
|
34
|
+
|
|
35
|
+
## Cover Page
|
|
36
|
+
|
|
37
|
+
Pass `null` as the first element in `pages` to use a single-page cover:
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
<Flipbook
|
|
41
|
+
pages={[
|
|
42
|
+
null, // cover placeholder (renders as single page)
|
|
43
|
+
'/images/1.jpg',
|
|
44
|
+
'/images/2.jpg',
|
|
45
|
+
'/images/3.jpg',
|
|
46
|
+
]}
|
|
47
|
+
/>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Render Props (Custom Controls)
|
|
51
|
+
|
|
52
|
+
Use the `children` render prop to build custom UI controls. The function receives the current state and action methods:
|
|
53
|
+
|
|
54
|
+
```tsx
|
|
55
|
+
<Flipbook pages={pages}>
|
|
56
|
+
{({ page, numPages, canFlipLeft, canFlipRight, flipLeft, flipRight }) => (
|
|
57
|
+
<div className="toolbar">
|
|
58
|
+
<button onClick={flipLeft} disabled={!canFlipLeft}>Prev</button>
|
|
59
|
+
<span>{page} / {numPages}</span>
|
|
60
|
+
<button onClick={flipRight} disabled={!canFlipRight}>Next</button>
|
|
61
|
+
</div>
|
|
62
|
+
)}
|
|
63
|
+
</Flipbook>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
The render prop provides:
|
|
67
|
+
|
|
68
|
+
| Property | Type | Description |
|
|
69
|
+
|---|---|---|
|
|
70
|
+
| `page` | `number` | Current page number (1-based) |
|
|
71
|
+
| `numPages` | `number` | Total number of pages |
|
|
72
|
+
| `canFlipLeft` | `boolean` | Whether left flip is possible |
|
|
73
|
+
| `canFlipRight` | `boolean` | Whether right flip is possible |
|
|
74
|
+
| `canZoomIn` | `boolean` | Whether zoom in is possible |
|
|
75
|
+
| `canZoomOut` | `boolean` | Whether zoom out is possible |
|
|
76
|
+
| `flipLeft()` | `function` | Flip to the left |
|
|
77
|
+
| `flipRight()` | `function` | Flip to the right |
|
|
78
|
+
| `zoomIn()` | `function` | Zoom in one level |
|
|
79
|
+
| `zoomOut()` | `function` | Zoom out one level |
|
|
80
|
+
| `goToPage(n)` | `function` | Jump to page `n` |
|
|
81
|
+
|
|
82
|
+
## Imperative Ref
|
|
83
|
+
|
|
84
|
+
For programmatic control outside of render props, use a ref:
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { useRef } from 'react'
|
|
88
|
+
import type { FlipbookRef } from '@kaktos/flipbook-react'
|
|
89
|
+
|
|
90
|
+
function App() {
|
|
91
|
+
const ref = useRef<FlipbookRef>(null)
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<>
|
|
95
|
+
<button onClick={() => ref.current?.goToPage(5)}>Go to page 5</button>
|
|
96
|
+
<Flipbook ref={ref} pages={pages} />
|
|
97
|
+
</>
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The ref exposes the same properties and methods as the render prop.
|
|
103
|
+
|
|
104
|
+
## Hi-Res Images
|
|
105
|
+
|
|
106
|
+
Provide `pagesHiRes` for high-resolution images that load when the user zooms in:
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
<Flipbook
|
|
110
|
+
pages={['/images/1.jpg', '/images/2.jpg']}
|
|
111
|
+
pagesHiRes={['/images-large/1.jpg', '/images-large/2.jpg']}
|
|
112
|
+
zooms={[1, 2, 4]}
|
|
113
|
+
/>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Standard images display at `zoom === 1`. Hi-res images swap in automatically when zoomed.
|
|
117
|
+
|
|
118
|
+
## Controlled Page
|
|
119
|
+
|
|
120
|
+
By default the component manages page state internally. To control it from outside, pass `page` and `onPageChange`:
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
const [page, setPage] = useState(0)
|
|
124
|
+
|
|
125
|
+
<Flipbook
|
|
126
|
+
pages={pages}
|
|
127
|
+
page={page}
|
|
128
|
+
onPageChange={setPage}
|
|
129
|
+
/>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Props
|
|
133
|
+
|
|
134
|
+
| Prop | Type | Default | Description |
|
|
135
|
+
|---|---|---|---|
|
|
136
|
+
| `pages` | `(string \| null)[]` | **required** | Array of page image URLs. `null` for cover placeholder. |
|
|
137
|
+
| `pagesHiRes` | `(string \| null)[]` | `[]` | Hi-res image URLs, swapped in when zoomed. |
|
|
138
|
+
| `pageLabels` | `string[]` | — | Alt text for each page image. Defaults to `"Page N"`. |
|
|
139
|
+
| `flipDuration` | `number` | `1000` | Flip animation duration in ms. |
|
|
140
|
+
| `zoomDuration` | `number` | `500` | Zoom animation duration in ms. |
|
|
141
|
+
| `zooms` | `number[] \| null` | `[1, 2, 4]` | Available zoom levels. `null` disables zoom. |
|
|
142
|
+
| `perspective` | `number` | `2400` | CSS perspective value for 3D effect. |
|
|
143
|
+
| `nPolygons` | `number` | `10` | Number of polygons per page for the flip curve. |
|
|
144
|
+
| `ambient` | `number` | `0.4` | Ambient lighting intensity (0–1). |
|
|
145
|
+
| `gloss` | `number` | `0.6` | Specular gloss intensity (0–1). |
|
|
146
|
+
| `swipeMin` | `number` | `3` | Minimum swipe distance (px) to trigger a flip. |
|
|
147
|
+
| `singlePage` | `boolean` | `false` | Force single-page mode even in landscape. |
|
|
148
|
+
| `forwardDirection` | `'left' \| 'right'` | `'right'` | Reading direction. |
|
|
149
|
+
| `centering` | `boolean` | `true` | Auto-center the book in the viewport. |
|
|
150
|
+
| `startPage` | `number \| null` | `null` | Initial page number (1-based). |
|
|
151
|
+
| `loadingImage` | `string` | Built-in spinner | Image shown while pages are loading. |
|
|
152
|
+
| `clickToZoom` | `boolean` | `true` | Enable click/tap to zoom. |
|
|
153
|
+
| `dragToFlip` | `boolean` | `true` | Enable drag/swipe to flip. |
|
|
154
|
+
| `wheel` | `'scroll' \| 'zoom'` | `'scroll'` | Mouse wheel behavior when zoomed. |
|
|
155
|
+
| `page` | `number` | — | Controlled page state (internal index). |
|
|
156
|
+
| `onPageChange` | `(page: number) => void` | — | Called when page changes in controlled mode. |
|
|
157
|
+
| `onFlipLeftStart` | `(page: number) => void` | — | Fired when left flip begins. |
|
|
158
|
+
| `onFlipLeftEnd` | `(page: number) => void` | — | Fired when left flip completes. |
|
|
159
|
+
| `onFlipRightStart` | `(page: number) => void` | — | Fired when right flip begins. |
|
|
160
|
+
| `onFlipRightEnd` | `(page: number) => void` | — | Fired when right flip completes. |
|
|
161
|
+
| `onZoomStart` | `(zoom: number) => void` | — | Fired when zoom animation begins. |
|
|
162
|
+
| `onZoomEnd` | `(zoom: number) => void` | — | Fired when zoom animation completes. |
|
|
163
|
+
|
|
164
|
+
The component also accepts all standard `<div>` HTML attributes (`className`, `style`, `id`, `data-*`, `aria-*`, etc.) which are spread onto the root element.
|
|
165
|
+
|
|
166
|
+
## Keyboard Navigation
|
|
167
|
+
|
|
168
|
+
When the viewport is focused:
|
|
169
|
+
|
|
170
|
+
| Key | Action |
|
|
171
|
+
|---|---|
|
|
172
|
+
| `ArrowLeft` | Flip left |
|
|
173
|
+
| `ArrowRight` | Flip right |
|
|
174
|
+
| `+` / `=` | Zoom in |
|
|
175
|
+
| `-` | Zoom out |
|
|
176
|
+
|
|
177
|
+
The left/right click areas are also keyboard-accessible with `Enter` or `Space`.
|
|
178
|
+
|
|
179
|
+
## CSS Customization
|
|
180
|
+
|
|
181
|
+
The component ships with structural CSS that is required for 3D transforms and layout. Visual defaults can be overridden with CSS variables:
|
|
182
|
+
|
|
183
|
+
```css
|
|
184
|
+
:root {
|
|
185
|
+
--flipbook-blank-page-bg: #f5f5f5; /* blank page background, default: #ddd */
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
You can also pass `className` and `style` to the root element:
|
|
190
|
+
|
|
191
|
+
```tsx
|
|
192
|
+
<Flipbook className="my-book" style={{ background: '#1a1a1a' }} pages={pages} />
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
MIT
|
package/dist/react-flipbook.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const C=require("react/jsx-runtime"),n=require("react");function ne(i){if(i&&i.constructor===Array){var s=i.filter(function(d){return typeof d=="number"}).filter(function(d){return!isNaN(d)});if(i.length===6&&s.length===6){var c=it();return c[0]=s[0],c[1]=s[1],c[4]=s[2],c[5]=s[3],c[12]=s[4],c[13]=s[5],c}else if(i.length===16&&s.length===16)return i}throw new TypeError("Expected a `number[]` with length 6 or 16.")}function it(){for(var i=[],s=0;s<16;s++)s%5==0?i.push(1):i.push(0);return i}function yn(i,s){for(var c=ne(i),d=ne(s),r=[],b=0;b<4;b++)for(var K=[c[b],c[b+4],c[b+8],c[b+12]],Q=0;Q<4;Q++){var w=Q*4,X=[d[w],d[w+1],d[w+2],d[w+3]],O=K[0]*X[0]+K[1]*X[1]+K[2]*X[2]+K[3]*X[3];r[b+w]=O}return r}function wn(i){var s=it();return s[11]=-1/i,s}function Ln(i){var s=Math.PI/180*i,c=it();return c[0]=c[10]=Math.cos(s),c[2]=c[8]=Math.sin(s),c[2]*=-1,c}function Sn(i){return"matrix3d("+ne(i).join(", ")+")"}function zn(i,s){var c=it();return c[12]=i,s&&(c[13]=s),c}function Cn(i,s,c){var d=it();return i!==void 0&&s!==void 0&&c!==void 0&&(d[12]=i,d[13]=s,d[14]=c),d}class Zt{constructor(s){s?s instanceof Zt?this.m=[...s.m]:this.m=[...s]:this.m=it()}clone(){return new Zt(this)}multiply(s){this.m=yn(this.m,s)}perspective(s){this.multiply(wn(s))}transformX(s){return(s*this.m[0]+this.m[12])/(s*this.m[3]+this.m[15])}translate(s,c){this.multiply(zn(s,c??0))}translate3d(s,c,d){this.multiply(Cn(s,c,d))}rotateY(s){this.multiply(Ln(s))}toString(){return Sn(this.m)}}const Tn="data:image/svg+xml,%3c?xml%20version='1.0'?%3e%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='500'%20height='500'%20viewBox='0%200%20500%20500'%20fill='transparent'%20style='background-color:%20%23fff'%3e%3ccircle%20cx='250'%20cy='250'%20r='48'%20stroke='%23333'%20stroke-width='2'%20stroke-dasharray='271%2030'%20%3e%3canimateTransform%20attributeName='transform'%20attributeType='XML'%20type='rotate'%20from='0%20250%20250'%20to='360%20250%20250'%20dur='1s'%20repeatCount='indefinite'%20/%3e%3c/circle%3e%3c/svg%3e",_n="_viewport_ij4oz_1",Fn="_viewportZoom_ij4oz_7 _viewport_ij4oz_1",En="_viewportZoomDragToScroll_ij4oz_12 _viewportZoom_ij4oz_7 _viewport_ij4oz_1",jn="_container_ij4oz_17",Zn="_clickLeft_ij4oz_33 _clickToFlip_ij4oz_25",On="_clickRight_ij4oz_38 _clickToFlip_ij4oz_25",Dn="_boundingBox_ij4oz_43",Wn="_page_ij4oz_48",Hn="_polygon_ij4oz_53",Xn="_polygonBlank_ij4oz_62 _polygon_ij4oz_53",$n="_lighting_ij4oz_67",T={viewport:_n,viewportZoom:Fn,viewportZoomDragToScroll:En,container:jn,clickLeft:Zn,clickRight:On,boundingBox:Dn,page:Wn,polygon:Hn,polygonBlank:Xn,lighting:$n};function We(i){return i*i}function Bn(i){return 1-We(1-i)}function De(i){return i<.5?We(i*2)/2:.5+Bn((i-.5)*2)/2}const xt={progress:0,direction:null,frontImage:null,backImage:null,auto:!1};function Nn(i,s){const{pages:c,pagesHiRes:d=[],flipDuration:r=1e3,zoomDuration:b=500,zooms:K=[1,2,4],perspective:Q=2400,nPolygons:w=10,ambient:X=.4,gloss:O=.6,swipeMin:at=3,singlePage:re=!1,forwardDirection:M="right",centering:He=!0,startPage:oe=null,loadingImage:se=Tn,clickToZoom:Pt=!0,dragToFlip:lt=!0,wheel:Ot="scroll"}=i,F=K??[1],[k,Xe]=n.useState(0),[$,$e]=n.useState(0),[D,Be]=n.useState(null),[Rt,Ne]=n.useState(null),[ce,Ye]=n.useState(1),[x,yt]=n.useState(0),[Dt,wt]=n.useState(0),[ie,Wt]=n.useState(1),[p,Ht]=n.useState(F[0]),[Lt,Xt]=n.useState(0),[B,ae]=n.useState(!1),[I,_]=n.useState(xt),[$t,Bt]=n.useState(null),[le,Ue]=n.useState({}),[,ue]=n.useState(0),Ae=c[0]===null&&(x===0||x===1),u=ce===2&&Ae?1:ce,ut=n.useRef(null),fe=n.useRef(null),tt=n.useRef(0),et=n.useRef(null),E=n.useRef(!1),St=n.useRef(!1),N=n.useRef(1/0),Y=n.useRef(-1/0),ge=n.useRef(0),he=n.useRef(0),ft=n.useRef(0),gt=n.useRef(0),ht=n.useRef(!1),de=n.useRef({count:0,target:0,cb:null}),pe=n.useRef({}),W=n.useRef(I);W.current=I;const nt=n.useRef(x);nt.current=x;const zt=n.useRef(u);zt.current=u;const dt=n.useRef(p);dt.current=p;const Ct=n.useRef(Lt);Ct.current=Lt;const me=n.useRef(i.onFlipLeftStart);me.current=i.onFlipLeftStart;const be=n.useRef(i.onFlipLeftEnd);be.current=i.onFlipLeftEnd;const Me=n.useRef(i.onFlipRightStart);Me.current=i.onFlipRightStart;const ke=n.useRef(i.onFlipRightEnd);ke.current=i.onFlipRightEnd;const Ie=n.useRef(i.onZoomStart);Ie.current=i.onZoomStart;const ve=n.useRef(i.onZoomEnd);ve.current=i.onZoomEnd;const Nt=n.useRef(new Set),L=n.useCallback(t=>{const e=requestAnimationFrame(o=>{Nt.current.delete(e),t(o)});return Nt.current.add(e),e},[]),Ge=c[0]===null?c.length-1:c.length,Yt=c[0]!==null?x+1:Math.max(1,x),U=n.useCallback((t,e=!1)=>{if(e&&p>1&&!B){const o=d[t];if(o)return o}return c[t]??null},[c,d,p,B]),Ut=n.useCallback(t=>{if(D===null||le[t])return t;if(!pe.current[t]){pe.current[t]=!0;const e=new Image;e.onload=()=>{Ue(o=>({...o,[t]:!0}))},e.src=t}return se},[D,le,se]),At=n.useCallback((t,e=!1)=>{const o=U(t,e);return e&&p>1&&!B?o:o?Ut(o):null},[U,Ut,p,B]),Gt=n.useCallback((t=!1)=>{for(let e=x-3;e<=x+3;e++)At(e);if(t)for(let e=x;e<x+u;e++){const o=d[e];o&&(new Image().src=o)}},[x,u,d,At]),xe=n.useCallback(()=>{yt(t=>u===1&&t===0&&c.length>0&&!c[0]?1:t)},[u,c]),Pe=!I.direction&&x<c.length-u,Re=!I.direction&&x>=u&&!(u===1&&!U(Dt-1)),pt=M==="left"?Pe:Re,mt=M==="right"?Pe:Re,Tt=!B&&Lt<F.length-1,_t=!B&&Lt>0,qt=M==="right"||u===1?Dt:ie,Vt=M==="left"?Dt:ie,qe=!!U(qt),Ve=!!U(Vt)&&u===2,ye=D&&Rt?Math.min(k/u/D,$/Rt,1):1,P=D?Math.round(D*ye):0,A=Rt?Math.round(Rt*ye):0,j=(k-P*u)/2,G=($-A)/2,Je=Math.ceil(P/w+1/p)+"px",Ke=A+"px",Qe=`${P}px ${A}px`,tn=n.useMemo(()=>{if(!I.direction||u!==1)return 1;let t=I.progress;return I.direction!==M&&(t=1-t),t>.7?1-(t-.7)/.3:1},[I.direction,I.progress,u,M]),q=(()=>{if(u===1)return j;const t=U(qt)?j:k/2;return I.direction?t<N.current?t:N.current:t})(),bt=(()=>{if(u===1)return k-j;const t=U(Vt)?k-j:k/2;return I.direction?t>Y.current?t:Y.current:t})(),Mt=He?Math.round(k/2-(q+bt)/2):0,we=n.useRef(Mt);we.current=Mt;const Le=n.useRef(u);$t===null&&D!==null&&Bt(Mt),Le.current!==u&&(Le.current=u,Bt(Mt),ht.current=!1);const kt=Math.round($t??0),en=et.current?et.current:Pt&&Tt?"zoom-in":Pt&&_t?"zoom-out":lt?"grab":"auto",nn=!E.current,rn=(B||p>1)&&nn?T.viewportZoomDragToScroll:B||p>1?T.viewportZoom:T.viewport,on=(()=>{const t=(bt-q)*p;return t<k?(q+kt)*p-(k-t)/2:(q+kt)*p})(),sn=(()=>{const t=(bt-q)*p;return t<k?(q+kt)*p-(k-t)/2:(bt+kt)*p-k})(),cn=(()=>{const t=A*p;return t<$?G*p-($-t)/2:G*p})(),an=(()=>{const t=A*p;return t<$?G*p-($-t)/2:(G+A)*p-$})(),Se=Math.min(sn,Math.max(on,ft.current)),ze=Math.min(an,Math.max(cn,gt.current)),Ce=n.useCallback((t,e)=>{const o=[],a=[-.5,-.25,0,.25,.5];if(X<1){const l=1-X,f=a.map(g=>(1-Math.cos((t-e*g)/180*Math.PI))*l);o.push(`linear-gradient(to right,rgba(0,0,0,${f[0]}),rgba(0,0,0,${f[1]}) 25%,rgba(0,0,0,${f[2]}) 50%,rgba(0,0,0,${f[3]}) 75%,rgba(0,0,0,${f[4]}))`)}if(O>0){const g=a.map(h=>Math.max(Math.pow(Math.cos((t+30-e*h)/180*Math.PI),200),Math.pow(Math.cos((t-30-e*h)/180*Math.PI),200)));o.push(`linear-gradient(to right,rgba(255,255,255,${g[0]*O}),rgba(255,255,255,${g[1]*O}) 25%,rgba(255,255,255,${g[2]*O}) 50%,rgba(255,255,255,${g[3]*O}) 75%,rgba(255,255,255,${g[4]*O}))`)}return o.join(",")},[X,O]),Jt=n.useCallback(t=>{const e=W.current;if(!e.direction)return[];let o=e.progress,a=e.direction;u===1&&a!==M&&(o=1-o,a=M);const l=t==="front"?e.frontImage:e.backImage,f=P/w;let g=j,h=!1;u===1?M==="right"?t==="back"&&(h=!0,g=j-P):a==="left"?t==="back"?g=P-j:h=!0:t==="front"?g=P-j:h=!0:a==="left"?t==="back"?g=k/2:h=!0:t==="front"?g=k/2:h=!0;const m=new Zt;m.translate(k/2),m.perspective(Q),m.translate(-k/2),m.translate(g,G);let R=0;o>.5&&(R=-(o-.5)*2*180),a==="left"&&(R=-R),t==="back"&&(R+=180),R&&(h&&m.translate(P),m.rotateY(R),h&&m.translate(-P));let v;o<.5?v=o*2*Math.PI:v=(1-(o-.5)*2)*Math.PI,v===0&&(v=1e-9);const J=P/v;let S=0;const y=v/w;let z=y/2/Math.PI*180;const H=y/Math.PI*180;h&&(z=-v/Math.PI*180+H/2),t==="back"&&(z=-z);const It=t==="back"?-H:H;N.current=1/0,Y.current=-1/0;const Z=[];for(let Et=0;Et<w;Et++){const Pn=`${Et/(w-1)*100}% 0px`,vt=m.clone(),je=h?v-S:S;let ee=Math.sin(je)*J;h&&(ee=P-ee);let jt=(1-Math.cos(je))*J;t==="back"&&(jt=-jt),vt.translate3d(ee,0,jt),vt.rotateY(-z);const Ze=vt.transformX(0),Oe=vt.transformX(f);Y.current=Math.max(Math.max(Ze,Oe),Y.current),N.current=Math.min(Math.min(Ze,Oe),N.current);const Rn=Ce(R-z,It);S+=y,z+=It,Z.push({key:t+Et,bgImage:l,lighting:Rn,bgPos:Pn,transform:vt.toString(),z:Math.abs(Math.round(jt))})}return Z},[u,M,P,j,G,k,Q,w,Ce]),ln=n.useMemo(()=>I.direction?[...Jt("front"),...Jt("back")]:[],[I.direction,I.progress,I.frontImage,I.backImage,Jt]),un=n.useCallback(t=>{const e=t.target;D===null&&(Be(e.naturalWidth),Ne(e.naturalHeight));const o=de.current;o.cb&&(o.count++,o.count>=o.target&&(o.cb(),o.cb=null))},[D]),Ft=n.useCallback((t,e)=>{de.current={count:0,target:t,cb:e}},[]),V=n.useCallback((t,e)=>{const o=nt.current,a=zt.current;let l=null,f=null;t!==M?a===1?(l=c[o-1]??null,f=null):(l=c[M==="right"||a===1?o:o+1]??null,f=c[o-a+1]??null):a===1?(l=c[o]??null,f=null):(l=c[M==="left"?o:o+1]??null,f=c[o+a]??null),_({progress:0,direction:t,frontImage:l,backImage:f,auto:!1}),L(()=>{L(()=>{t!==M?a===2&&wt(o-a):a===1?wt(o+a):Wt(o+1+a),e&&Kt(t)})})},[M,c,L]),Kt=n.useCallback(t=>{const e=W.current,o=r*(1-e.progress),a=e.progress;_(m=>({...m,auto:!0}));const l=nt.current,f=c[0]!==null?l+1:Math.max(1,l);t==="left"?me.current?.(f):Me.current?.(f);let g=null;const h=m=>{g===null&&(g=m);const R=m-g;let v=a+R/o;v>1&&(v=1);const J=De(v);if(_(S=>({...S,progress:J})),v<1)L(h);else{const S=zt.current;let y;t!==M?y=nt.current-S:y=nt.current+S,yt(y);const z=c[0]!==null?y+1:Math.max(1,y);t==="left"?be.current?.(z):ke.current?.(z),S===1&&t===M?_(xt):Ft(1,()=>{_(xt)})}};L(h)},[r,M,c,Ft,L]),Te=n.useCallback(()=>{const t=W.current,e=r*t.progress,o=t.progress;_(f=>({...f,auto:!0}));let a=null;const l=f=>{a===null&&(a=f);const g=f-a;let h=o-o*g/e;if(h<0&&(h=0),_(m=>({...m,progress:h})),h>0)L(l);else{const m=nt.current;wt(m),Wt(m+1);const R=zt.current,v=W.current.direction;R===1&&v!==M?_(xt):Ft(1,()=>{_(xt)})}};L(l)},[r,M,Ft,L]),fn=n.useCallback(()=>{pt&&V("left",!0)},[pt,V]),gn=n.useCallback(()=>{mt&&V("right",!0)},[mt,V]),rt=n.useCallback((t,e)=>{const o=s.current;if(!o)return;let a,l;if(e){const H=o.getBoundingClientRect();a=e.pageX-H.left,l=e.pageY-H.top}else a=o.clientWidth/2,l=o.clientHeight/2;const f=dt.current,g=t,h=o.scrollLeft,m=o.scrollTop,R=a+h,v=l+m,J=R/f*g-a,S=v/f*g-l;ae(!0),Ie.current?.(t);let y=null;const z=H=>{y===null&&(y=H);const It=H-y;let Z=It/b;Z>1&&(Z=1),Z=De(Z),Ht(f+(g-f)*Z),ft.current=h+(J-h)*Z,gt.current=m+(S-m)*Z,It<b?L(z):(ve.current?.(t),ae(!1),Ht(t),ft.current=J,gt.current=S)};L(z),g>1&&Gt(!0)},[b,s,Gt,L]),Qt=n.useCallback(t=>{if(!Tt)return;const e=Ct.current+1;Xt(e),rt(F[e],t)},[Tt,F,rt]),te=n.useCallback(t=>{if(!_t)return;const e=Ct.current-1;Xt(e),rt(F[e],t)},[_t,F,rt]),_e=n.useCallback(t=>{const e=(Ct.current+1)%F.length;Xt(e),rt(F[e],t)},[F,rt]),Fe=n.useCallback(t=>{if(t===null||t===Yt)return;let e;c[0]===null?u===2&&t===1?e=0:e=t:e=t-1,(u===2&&e>0&&c[0]===null||u===2&&c[0]!==null)&&(e=e&-2),yt(e),N.current=1/0,Y.current=-1/0},[Yt,c,u]),Ee=n.useCallback((t,e)=>{const o=s.current;o&&(o.scrollLeft=ge.current-t,o.scrollTop=he.current-e,ft.current=o.scrollLeft,gt.current=o.scrollTop)},[s]),ot=n.useCallback(t=>{if(ut.current=t.pageX,fe.current=t.pageY,tt.current=0,dt.current<=1)lt&&(et.current="grab");else{const e=s.current;e&&(ge.current=e.scrollLeft,he.current=e.scrollTop),et.current="all-scroll"}},[lt,s]),st=n.useCallback(t=>{if(ut.current===null)return!1;const e=t.pageX-ut.current,o=t.pageY-fe.current;if(tt.current=Math.max(tt.current,Math.abs(e)),tt.current=Math.max(tt.current,Math.abs(o)),dt.current>1)return E.current||Ee(e,o),!1;if(!lt||Math.abs(o)>Math.abs(e))return!1;et.current="grabbing",ue(l=>l+1);const a=W.current;return e>0?(a.direction===null&&pt&&e>=at&&V("left",!1),W.current.direction==="left"&&_(l=>({...l,progress:Math.min(e/P,1)}))):(a.direction===null&&mt&&e<=-at&&V("right",!1),W.current.direction==="right"&&_(l=>({...l,progress:Math.min(-e/P,1)}))),!0},[lt,pt,mt,at,V,P,Ee]),ct=n.useCallback(t=>{if(ut.current===null)return;Pt&&tt.current<at&&_e(t);const e=W.current;e.direction!==null&&!e.auto&&(e.progress>1/4?Kt(e.direction):Te()),ut.current=null,et.current=null,ue(o=>o+1)},[Pt,at,_e,Kt,Te]),hn=n.useCallback(t=>{E.current=!0,ot(t.changedTouches[0])},[ot]),dn=n.useCallback(t=>{st(t.changedTouches[0])&&t.cancelable&&t.preventDefault()},[st]),pn=n.useCallback(t=>{ct(t.changedTouches[0])},[ct]),mn=n.useCallback(t=>{if(St.current=!0,!E.current&&t.button===0){ot(t);try{t.target.setPointerCapture(t.pointerId)}catch{}}},[ot]),bn=n.useCallback(t=>{E.current||st(t)},[st]),Mn=n.useCallback(t=>{if(!E.current){ct(t);try{t.target.releasePointerCapture(t.pointerId)}catch{}}},[ct]),kn=n.useCallback(t=>{E.current||St.current||t.button===0&&ot(t)},[ot]),In=n.useCallback(t=>{E.current||St.current||st(t)},[st]),vn=n.useCallback(t=>{E.current||St.current||ct(t)},[ct]),xn=n.useCallback(t=>{if(Ot==="scroll"&&dt.current>1&&!E.current){const e=s.current;e&&(e.scrollLeft+=t.deltaX,e.scrollTop+=t.deltaY,ft.current=e.scrollLeft,gt.current=e.scrollTop),t.cancelable&&t.preventDefault()}Ot==="zoom"&&(t.deltaY>=100?(te(t),t.cancelable&&t.preventDefault()):t.deltaY<=-100&&(Qt(t),t.cancelable&&t.preventDefault()))},[Ot,s,te,Qt]);return n.useEffect(()=>{const t=()=>{const e=s.current;if(!e)return;Xe(e.clientWidth),$e(e.clientHeight);const o=e.clientWidth>e.clientHeight&&!re?2:1;Ye(o),o===2&&yt(a=>{const l=a&-2;return l===0&&c[0]===null?a:l}),N.current=1/0,Y.current=-1/0};return window.addEventListener("resize",t,{passive:!0}),t(),()=>window.removeEventListener("resize",t)},[re,s]),n.useEffect(()=>{wt(x),Wt(x+1),Gt()},[x]),n.useEffect(()=>{if(ht.current||$t===null)return;ht.current=!0;let t;const e=()=>{t=requestAnimationFrame(()=>{Bt(o=>{const a=we.current;if(o===null)return ht.current=!1,a;const l=a-o;return Math.abs(l)<.5?(ht.current=!1,a):(e(),o+l*.1)})})};return e(),()=>cancelAnimationFrame(t)},[Mt]),n.useEffect(()=>{const t=s.current;t&&(t.scrollLeft=Se)},[Se,s]),n.useEffect(()=>{const t=s.current;t&&(t.scrollTop=ze)},[ze,s]),n.useEffect(()=>{xe()},[c,xe]),n.useEffect(()=>{Fe(oe)},[oe]),n.useEffect(()=>{Ht(F[0])},[]),n.useEffect(()=>{const t=Nt.current;return()=>{t.forEach(cancelAnimationFrame),t.clear()}},[]),{viewWidth:k,viewHeight:$,pageWidth:P,pageHeight:A,xMargin:j,yMargin:G,displayedPages:u,zoom:p,centerOffsetSmoothed:kt,page:Yt,numPages:Ge,leftPage:qt,rightPage:Vt,showLeftPage:qe,showRightPage:Ve,pageUrlLoading:At,loadImage:Ut,flip:I,flipOpacity:tn,polygonArray:ln,polygonWidth:Je,polygonHeight:Ke,polygonBgSize:Qe,canFlipLeft:pt,canFlipRight:mt,canZoomIn:Tt,canZoomOut:_t,boundingLeft:q,boundingRight:bt,cursor:en,viewportClass:rn,flipLeft:fn,flipRight:gn,zoomIn:Qt,zoomOut:te,goToPage:Fe,handlers:{onTouchStart:hn,onTouchMove:dn,onTouchEnd:pn,onPointerDown:mn,onPointerMove:bn,onPointerUp:Mn,onMouseDown:kn,onMouseMove:In,onMouseUp:vn,onWheel:xn},onImageLoad:un}}const Yn={display:"flex",flexDirection:"column",width:"100%",height:"100%"},Un=n.forwardRef(function(s,c){const d=n.useRef(null),r=Nn(s,d);return n.useImperativeHandle(c,()=>({flipLeft:r.flipLeft,flipRight:r.flipRight,zoomIn:r.zoomIn,zoomOut:r.zoomOut,goToPage:r.goToPage,canFlipLeft:r.canFlipLeft,canFlipRight:r.canFlipRight,canZoomIn:r.canZoomIn,canZoomOut:r.canZoomOut,page:r.page,numPages:r.numPages}),[r.flipLeft,r.flipRight,r.zoomIn,r.zoomOut,r.goToPage,r.canFlipLeft,r.canFlipRight,r.canZoomIn,r.canZoomOut,r.page,r.numPages]),C.jsxs("div",{style:Yn,children:[s.children?.({canFlipLeft:r.canFlipLeft,canFlipRight:r.canFlipRight,canZoomIn:r.canZoomIn,canZoomOut:r.canZoomOut,page:r.page,numPages:r.numPages,flipLeft:r.flipLeft,flipRight:r.flipRight,zoomIn:r.zoomIn,zoomOut:r.zoomOut,goToPage:r.goToPage}),C.jsx("div",{ref:d,className:r.viewportClass,style:{cursor:r.cursor==="grabbing"?"grabbing":"auto"},onTouchMove:r.handlers.onTouchMove,onPointerMove:r.handlers.onPointerMove,onMouseMove:r.handlers.onMouseMove,onTouchEnd:r.handlers.onTouchEnd,onTouchCancel:r.handlers.onTouchEnd,onPointerUp:r.handlers.onPointerUp,onPointerCancel:r.handlers.onPointerUp,onMouseUp:r.handlers.onMouseUp,onWheel:r.handlers.onWheel,children:C.jsxs("div",{className:T.container,style:{transform:`scale(${r.zoom})`},children:[C.jsx("div",{className:T.clickLeft,style:{cursor:r.canFlipLeft?"pointer":"auto"},onClick:r.flipLeft}),C.jsx("div",{className:T.clickRight,style:{cursor:r.canFlipRight?"pointer":"auto"},onClick:r.flipRight}),C.jsxs("div",{style:{transform:`translateX(${r.centerOffsetSmoothed}px)`},children:[r.showLeftPage&&C.jsx("img",{className:T.page,style:{width:r.pageWidth+"px",height:r.pageHeight+"px",left:r.xMargin+"px",top:r.yMargin+"px"},src:r.pageUrlLoading(r.leftPage,!0)??void 0,onLoad:r.onImageLoad}),r.showRightPage&&C.jsx("img",{className:T.page,style:{width:r.pageWidth+"px",height:r.pageHeight+"px",left:r.viewWidth/2+"px",top:r.yMargin+"px"},src:r.pageUrlLoading(r.rightPage,!0)??void 0,onLoad:r.onImageLoad}),C.jsx("div",{style:{opacity:r.flipOpacity},children:r.polygonArray.map(b=>C.jsx("div",{className:b.bgImage?T.polygon:T.polygonBlank,style:{backgroundImage:b.bgImage?`url(${r.loadImage(b.bgImage)})`:void 0,backgroundSize:r.polygonBgSize,backgroundPosition:b.bgPos,width:r.polygonWidth,height:r.polygonHeight,transform:b.transform,zIndex:b.z},children:b.lighting&&C.jsx("div",{className:T.lighting,style:{backgroundImage:b.lighting}})},b.key))}),C.jsx("div",{className:T.boundingBox,style:{left:r.boundingLeft+"px",top:r.yMargin+"px",width:r.boundingRight-r.boundingLeft+"px",height:r.pageHeight+"px",cursor:r.cursor},onTouchStart:r.handlers.onTouchStart,onPointerDown:r.handlers.onPointerDown,onMouseDown:r.handlers.onMouseDown})]})]})})]})});exports.Flipbook=Un;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const W=require("react/jsx-runtime"),t=require("react");function ht(c){if(c&&c.constructor===Array){var o=c.filter(function(b){return typeof b=="number"}).filter(function(b){return!isNaN(b)});if(c.length===6&&o.length===6){var s=$e();return s[0]=o[0],s[1]=o[1],s[4]=o[2],s[5]=o[3],s[12]=o[4],s[13]=o[5],s}else if(c.length===16&&o.length===16)return c}throw new TypeError("Expected a `number[]` with length 6 or 16.")}function $e(){for(var c=[],o=0;o<16;o++)o%5==0?c.push(1):c.push(0);return c}function _n(c,o){for(var s=ht(c),b=ht(o),w=[],v=0;v<4;v++)for(var D=[s[v],s[v+4],s[v+8],s[v+12]],L=0;L<4;L++){var y=L*4,j=[b[y],b[y+1],b[y+2],b[y+3]],C=D[0]*j[0]+D[1]*j[1]+D[2]*j[2]+D[3]*j[3];w[v+y]=C}return w}function Tn(c){var o=$e();return o[11]=-1/c,o}function jn(c){var o=Math.PI/180*c,s=$e();return s[0]=s[10]=Math.cos(o),s[2]=s[8]=Math.sin(o),s[2]*=-1,s}function Fn(c){return"matrix3d("+ht(c).join(", ")+")"}function Yt(c,o,s){var b=$e();return c!==void 0&&o!==void 0&&s!==void 0&&(b[12]=c,b[13]=o,b[14]=s),b}class tt{constructor(o){o?o instanceof tt?this.m=[...o.m]:this.m=[...o]:this.m=$e()}clone(){return new tt(this)}multiply(o){this.m=_n(this.m,o)}perspective(o){this.multiply(Tn(o))}transformX(o){return(o*this.m[0]+this.m[12])/(o*this.m[3]+this.m[15])}translate(o,s){this.multiply(Yt(o,s??0,0))}translate3d(o,s,b){this.multiply(Yt(o,s,b))}rotateY(o){this.multiply(jn(o))}toString(){return Fn(this.m)}}function En(c,o,s){const[b,w]=t.useState(0),[v,D]=t.useState(0),[L,y]=t.useState(1),[j,C]=t.useState(0);return t.useEffect(()=>{const S=()=>{const X=c.current;if(!X)return;w(X.clientWidth),D(X.clientHeight);const g=X.clientWidth>X.clientHeight&&!o?2:1;y(g),g===2&&C(Q=>Q+1)};return window.addEventListener("resize",S,{passive:!0}),S(),()=>window.removeEventListener("resize",S)},[o,c]),{viewWidth:b,viewHeight:v,rawDisplayedPages:L,pageAlignmentTick:j}}function Dn(c,o,s,b,w,v,D){const[L,y]=t.useState(null),[j,C]=t.useState(null),[S,X]=t.useState({}),g=t.useRef({}),Q=t.useRef({count:0,target:0,cb:null}),re=t.useRef(new Set),oe=t.useCallback((f,d=!1)=>{if(d&&w>1&&!v){const i=o[f];if(i)return i}return c[f]??null},[c,o,w,v]),U=t.useCallback(f=>L===null||S[f]?f:(g.current[f]||(g.current[f]=null,re.current.add(f)),D),[L,S,D]);t.useEffect(()=>{const f=re.current;f.size!==0&&(f.forEach(d=>{if(g.current[d])return;const i=new Image;g.current[d]=i,i.onload=()=>{X(_=>({..._,[d]:!0}))},i.src=d}),f.clear())});const z=t.useCallback((f,d=!1)=>{const i=oe(f,d);return d&&w>1&&!v?i:i?U(i):null},[oe,U,w,v]),se=t.useCallback((f=!1)=>{for(let d=s-3;d<=s+3;d++)z(d);if(f)for(let d=s;d<s+b;d++){const i=o[d];if(i&&!g.current[i]){const _=new Image;g.current[i]=_,_.src=i}}},[s,b,o,z]),J=t.useCallback(f=>{const d=f.target;L===null&&(y(d.naturalWidth),C(d.naturalHeight));const i=Q.current;i.cb&&(i.count++,i.count>=i.target&&(i.cb(),i.cb=null))},[L]),ee=t.useCallback((f,d)=>{Q.current={count:0,target:f,cb:d}},[]);return{imageWidth:L,imageHeight:j,loadedImages:S,pageUrl:oe,loadImage:U,pageUrlLoading:z,preloadImages:se,onImageLoad:J,setImageLoadCallback:ee}}const zn="data:image/svg+xml,%3c?xml%20version='1.0'?%3e%3csvg%20xmlns='http://www.w3.org/2000/svg'%20width='500'%20height='500'%20viewBox='0%200%20500%20500'%20fill='transparent'%20style='background-color:%20%23fff'%3e%3ccircle%20cx='250'%20cy='250'%20r='48'%20stroke='%23333'%20stroke-width='2'%20stroke-dasharray='271%2030'%20%3e%3canimateTransform%20attributeName='transform'%20attributeType='XML'%20type='rotate'%20from='0%20250%20250'%20to='360%20250%20250'%20dur='1s'%20repeatCount='indefinite'%20/%3e%3c/circle%3e%3c/svg%3e",On="_root_jjdx8_1",Zn="_viewport_jjdx8_8",Wn="_viewportZoom_jjdx8_16 _viewport_jjdx8_8",Nn="_viewportZoomDragToScroll_jjdx8_22 _viewportZoom_jjdx8_16 _viewport_jjdx8_8",$n="_container_jjdx8_27",Xn="_clickLeft_jjdx8_43 _clickToFlip_jjdx8_35",Hn="_clickRight_jjdx8_48 _clickToFlip_jjdx8_35",Bn="_boundingBox_jjdx8_53",Un="_page_jjdx8_58",Yn="_polygon_jjdx8_63",An="_polygonBlank_jjdx8_72 _polygon_jjdx8_63",Gn="_lighting_jjdx8_77",Kn="_srOnly_jjdx8_82",T={root:On,viewport:Zn,viewportZoom:Wn,viewportZoomDragToScroll:Nn,container:$n,clickLeft:Xn,clickRight:Hn,boundingBox:Bn,page:Un,polygon:Yn,polygonBlank:An,lighting:Gn,srOnly:Kn};function Gt(c){return c*c}function qn(c){return 1-Gt(1-c)}function At(c){return c<.5?Gt(c*2)/2:.5+qn((c-.5)*2)/2}const Ne={progress:0,direction:null,frontImage:null,backImage:null,auto:!1};function Vn(c,o){const{pages:s,pagesHiRes:b=[],flipDuration:w=1e3,zoomDuration:v=500,zooms:D=[1,2,4],perspective:L=2400,nPolygons:y=10,ambient:j=.4,gloss:C=.6,swipeMin:S=3,singlePage:X=!1,forwardDirection:g="right",centering:Q=!0,startPage:re=null,loadingImage:oe=zn,clickToZoom:U=!0,dragToFlip:z=!0,wheel:se="scroll",page:J,onPageChange:ee}=c,f=D??[1],d=s[0]===null,{viewWidth:i,viewHeight:_,rawDisplayedPages:pe,pageAlignmentTick:nt}=En(o,X),[rt,Xe]=t.useState(0),we=J!==void 0,F=we?J:rt,H=t.useCallback(e=>{if(we){const r=typeof e=="function"?e(J):e;ee?.(r)}else Xe(e)},[we,J,ee]),[He,n]=t.useState(0),[Le,Ce]=t.useState(1),[l,ot]=t.useState(f[0]),[Be,st]=t.useState(0),[Se,pt]=t.useState(!1),[I,B]=t.useState(Ne),[Ue,at]=t.useState(null),[,mt]=t.useState(0),h=pe===2&&(d&&(F===0||F===1))?1:pe,Kt=Dn(s,b,F,h,l,Se,oe),{imageWidth:me,imageHeight:Ye,pageUrl:_e,loadImage:qt,pageUrlLoading:Vt,preloadImages:Ae,onImageLoad:Qt,setImageLoadCallback:Ge}=Kt,be=t.useRef(null),bt=t.useRef(null),ke=t.useRef(0),xe=t.useRef(null),Y=t.useRef(!1),Ke=t.useRef(!1),ae=t.useRef(1/0),ce=t.useRef(-1/0),kt=t.useRef(0),xt=t.useRef(0),Te=t.useRef(0),je=t.useRef(0),Fe=t.useRef(!1),q=t.useRef(I);q.current=I;const Re=t.useRef(F);Re.current=F;const qe=t.useRef(h);qe.current=h;const ve=t.useRef(l);ve.current=l;const Ve=t.useRef(Be);Ve.current=Be;const Rt=t.useRef(c.onFlipLeftStart);Rt.current=c.onFlipLeftStart;const vt=t.useRef(c.onFlipLeftEnd);vt.current=c.onFlipLeftEnd;const Pt=t.useRef(c.onFlipRightStart);Pt.current=c.onFlipRightStart;const yt=t.useRef(c.onFlipRightEnd);yt.current=c.onFlipRightEnd;const It=t.useRef(c.onZoomStart);It.current=c.onZoomStart;const Mt=t.useRef(c.onZoomEnd);Mt.current=c.onZoomEnd;const Jt=t.useRef(ee);Jt.current=ee;const wt=t.useRef(H);wt.current=H;const ct=t.useRef(new Set),E=t.useCallback(e=>{const r=requestAnimationFrame(a=>{ct.current.delete(r),e(a)});return ct.current.add(r),r},[]),Lt=d?s.length-1:s.length,Qe=d?Math.max(1,F):F+1,Ct=t.useRef({canFlipLeft:!1,canFlipRight:!1,canZoomIn:!1,canZoomOut:!1,page:0,numPages:0}),St=t.useCallback(()=>{H(e=>h===1&&e===0&&s.length>0&&!s[0]?1:e)},[h,s,H]),_t=!I.direction&&F<s.length-h,Tt=!I.direction&&F>=h&&!(h===1&&!_e(He-1)),te=g==="left"?_t:Tt,ne=g==="right"?_t:Tt,ie=!Se&&Be<f.length-1,le=!Se&&Be>0;Ct.current={canFlipLeft:te,canFlipRight:ne,canZoomIn:ie,canZoomOut:le,page:Qe,numPages:Lt};const it=g==="right"||h===1?He:Le,lt=g==="left"?He:Le,en=!!_e(it),tn=!!_e(lt)&&h===2,jt=me&&Ye?Math.min(i/h/me,_/Ye,1):1,P=me?Math.round(me*jt):0,ue=Ye?Math.round(Ye*jt):0,A=(i-P*h)/2,fe=(_-ue)/2,nn=Math.ceil(P/y+1/l)+"px",rn=ue+"px",on=`${P}px ${ue}px`,sn=t.useMemo(()=>{if(!I.direction||h!==1)return 1;let e=I.progress;return I.direction!==g&&(e=1-e),e>.7?1-(e-.7)/.3:1},[I.direction,I.progress,h,g]),ge=(()=>{if(h===1)return A;const e=_e(it)?A:i/2;return I.direction?e<ae.current?e:ae.current:e})(),Ee=(()=>{if(h===1)return i-A;const e=_e(lt)?i-A:i/2;return I.direction?e>ce.current?e:ce.current:e})(),de=Q?Math.round(i/2-(ge+Ee)/2):0,Ft=t.useRef(de);Ft.current=de;const Et=t.useRef(h);t.useEffect(()=>{Ue===null&&me!==null&&at(de)},[Ue,me,de]),t.useEffect(()=>{Et.current!==h&&(Et.current=h,at(de),Fe.current=!1)},[h,de]);const De=Math.round(Ue??0),an=xe.current?xe.current:U&&ie?"zoom-in":U&&le?"zoom-out":z?"grab":"auto",cn=!Y.current,ln=(Se||l>1)&&cn?T.viewportZoomDragToScroll:Se||l>1?T.viewportZoom:T.viewport,un=(()=>{const e=(Ee-ge)*l;return e<i?(ge+De)*l-(i-e)/2:(ge+De)*l})(),fn=(()=>{const e=(Ee-ge)*l;return e<i?(ge+De)*l-(i-e)/2:(Ee+De)*l-i})(),gn=(()=>{const e=ue*l;return e<_?fe*l-(_-e)/2:fe*l})(),dn=(()=>{const e=ue*l;return e<_?fe*l-(_-e)/2:(fe+ue)*l-_})(),Dt=Math.min(fn,Math.max(un,Te.current)),zt=Math.min(dn,Math.max(gn,je.current)),Ot=t.useCallback((e,r)=>{const a=[],u=[-.5,-.25,0,.25,.5];if(j<1){const p=1-j,m=u.map(k=>(1-Math.cos((e-r*k)/180*Math.PI))*p);a.push(`linear-gradient(to right,rgba(0,0,0,${m[0]}),rgba(0,0,0,${m[1]}) 25%,rgba(0,0,0,${m[2]}) 50%,rgba(0,0,0,${m[3]}) 75%,rgba(0,0,0,${m[4]}))`)}if(C>0){const k=u.map(x=>Math.max(Math.pow(Math.cos((e+30-r*x)/180*Math.PI),200),Math.pow(Math.cos((e-30-r*x)/180*Math.PI),200)));a.push(`linear-gradient(to right,rgba(255,255,255,${k[0]*C}),rgba(255,255,255,${k[1]*C}) 25%,rgba(255,255,255,${k[2]*C}) 50%,rgba(255,255,255,${k[3]*C}) 75%,rgba(255,255,255,${k[4]*C}))`)}return a.join(",")},[j,C]),ut=t.useCallback(e=>{const r=q.current;if(!r.direction)return[];if(!Number.isFinite(P)||P<=0||y<=0)return[];let a=r.progress,u=r.direction;if(!Number.isFinite(a))return[];a<0&&(a=0),a>1&&(a=1),h===1&&u!==g&&(a=1-a,u=g);const p=e==="front"?r.frontImage:r.backImage,m=P/y;let k=A,x=!1;h===1?g==="right"?e==="back"&&(x=!0,k=A-P):u==="left"?e==="back"?k=P-A:x=!0:e==="front"?k=P-A:x=!0:u==="left"?e==="back"?k=i/2:x=!0:e==="front"?k=i/2:x=!0;const R=new tt;R.translate(i/2),R.perspective(L),R.translate(-i/2),R.translate(k,fe);let O=0;a>.5&&(O=-(a-.5)*2*180),u==="left"&&(O=-O),e==="back"&&(O+=180),O&&(x&&R.translate(P),R.rotateY(O),x&&R.translate(-P));let M;a<.5?M=a*2*Math.PI:M=(1-(a-.5)*2)*Math.PI,M===0&&(M=1e-9);const he=P/M;let N=0;const Z=M/y;let $=Z/2/Math.PI*180;const V=Z/Math.PI*180;x&&($=-M/Math.PI*180+V/2),e==="back"&&($=-$);const Ze=e==="back"?-V:V;ae.current=1/0,ce.current=-1/0;const K=[];for(let Je=0;Je<y;Je++){const Cn=`${Je/(y-1)*100}% 0px`,We=R.clone(),Ht=x?M-N:N;let dt=Math.sin(Ht)*he;x&&(dt=P-dt);let et=(1-Math.cos(Ht))*he;e==="back"&&(et=-et),We.translate3d(dt,0,et),We.rotateY(-$);const Bt=We.transformX(0),Ut=We.transformX(m);ce.current=Math.max(Math.max(Bt,Ut),ce.current),ae.current=Math.min(Math.min(Bt,Ut),ae.current);const Sn=Ot(O-$,Ze);N+=Z,$+=Ze,K.push({key:e+Je,bgImage:p,lighting:Sn,bgPos:Cn,transform:We.toString(),z:Math.abs(Math.round(et))})}return K},[h,g,P,A,fe,i,L,y,Ot]),hn=t.useMemo(()=>I.direction?[...ut("front"),...ut("back")]:[],[I.direction,I.progress,I.frontImage,I.backImage,ut]),G=t.useCallback((e,r)=>{const a=Re.current,u=qe.current;let p=null,m=null;e!==g?u===1?(p=s[a-1]??null,m=null):(p=s[g==="right"||u===1?a:a+1]??null,m=s[a-u+1]??null):u===1?(p=s[a]??null,m=null):(p=s[g==="left"?a:a+1]??null,m=s[a+u]??null),B({progress:0,direction:e,frontImage:p,backImage:m,auto:!1}),E(()=>{E(()=>{e!==g?u===2&&n(a-u):u===1?n(a+u):Ce(a+1+u),r&&ft(e)})})},[g,s,E]),ft=t.useCallback(e=>{const r=q.current,a=w*(1-r.progress),u=r.progress;B(R=>({...R,auto:!0}));const p=Re.current,m=s[0]!==null?p+1:Math.max(1,p);e==="left"?Rt.current?.(m):Pt.current?.(m);let k=null;const x=R=>{k===null&&(k=R);const O=R-k;let M=u+O/a;M>1&&(M=1);const he=At(M);if(B(N=>({...N,progress:he})),M<1)E(x);else{const N=qe.current;let Z;e!==g?Z=Re.current-N:Z=Re.current+N,wt.current(Z);const $=s[0]!==null?Z+1:Math.max(1,Z);e==="left"?vt.current?.($):yt.current?.($),N===1&&e===g?B(Ne):Ge(1,()=>{B(Ne)})}};E(x)},[w,g,s,Ge,E]),Zt=t.useCallback(()=>{const e=q.current,r=w*e.progress,a=e.progress;B(m=>({...m,auto:!0}));let u=null;const p=m=>{u===null&&(u=m);const k=m-u;let x=a-a*k/r;if(x<0&&(x=0),B(R=>({...R,progress:x})),x>0)E(p);else{const R=Re.current;n(R),Ce(R+1);const O=qe.current,M=q.current.direction;O===1&&M!==g?B(Ne):Ge(1,()=>{B(Ne)})}};E(p)},[w,g,Ge,E]),pn=t.useCallback(()=>{te&&G("left",!0)},[te,G]),mn=t.useCallback(()=>{ne&&G("right",!0)},[ne,G]),Pe=t.useCallback((e,r)=>{const a=o.current;if(!a)return;let u,p;if(r){const V=a.getBoundingClientRect();u=r.pageX-V.left,p=r.pageY-V.top}else u=a.clientWidth/2,p=a.clientHeight/2;const m=ve.current,k=e,x=a.scrollLeft,R=a.scrollTop,O=u+x,M=p+R,he=O/m*k-u,N=M/m*k-p;pt(!0),It.current?.(e);let Z=null;const $=V=>{Z===null&&(Z=V);const Ze=V-Z;let K=Ze/v;K>1&&(K=1),K=At(K),ot(m+(k-m)*K),Te.current=x+(he-x)*K,je.current=R+(N-R)*K,Ze<v?E($):(Mt.current?.(e),pt(!1),ot(e),Te.current=he,je.current=N)};E($),k>1&&Ae(!0)},[v,o,Ae,E]),ze=t.useCallback(e=>{if(!ie)return;const r=Ve.current+1;st(r),Pe(f[r],e)},[ie,f,Pe]),Oe=t.useCallback(e=>{if(!le)return;const r=Ve.current-1;st(r),Pe(f[r],e)},[le,f,Pe]),Wt=t.useCallback(e=>{const r=(Ve.current+1)%f.length;st(r),Pe(f[r],e)},[f,Pe]),gt=t.useCallback(e=>{if(e===null||e===Qe)return;let r;s[0]===null?h===2&&e===1?r=0:r=e:r=e-1,(h===2&&r>0&&s[0]===null||h===2&&s[0]!==null)&&(r=r&-2),H(r),ae.current=1/0,ce.current=-1/0},[Qe,s,h,H]),Nt=t.useRef(gt);Nt.current=gt;const $t=t.useCallback((e,r)=>{const a=o.current;a&&(a.scrollLeft=kt.current-e,a.scrollTop=xt.current-r,Te.current=a.scrollLeft,je.current=a.scrollTop)},[o]),ye=t.useCallback(e=>{if(be.current=e.pageX,bt.current=e.pageY,ke.current=0,ve.current<=1)z&&(xe.current="grab");else{const r=o.current;r&&(kt.current=r.scrollLeft,xt.current=r.scrollTop),xe.current="all-scroll"}},[z,o]),Ie=t.useCallback(e=>{if(be.current===null)return!1;const r=e.pageX-be.current,a=e.pageY-bt.current;if(ke.current=Math.max(ke.current,Math.abs(r)),ke.current=Math.max(ke.current,Math.abs(a)),ve.current>1)return Y.current||$t(r,a),!1;if(!z||Math.abs(a)>Math.abs(r)||!Number.isFinite(P)||P<=0)return!1;xe.current="grabbing",mt(p=>p+1);const u=q.current;return r>0?(u.direction===null&&te&&r>=S&&G("left",!1),q.current.direction==="left"&&B(p=>({...p,progress:Math.min(r/P,1)}))):(u.direction===null&&ne&&r<=-S&&G("right",!1),q.current.direction==="right"&&B(p=>({...p,progress:Math.min(-r/P,1)}))),!0},[z,te,ne,S,G,P,$t]),Me=t.useCallback(e=>{if(be.current===null)return;U&&ke.current<S&&Wt(e);const r=q.current;r.direction!==null&&!r.auto&&(r.progress>1/4?ft(r.direction):Zt()),be.current=null,xe.current=null,mt(a=>a+1)},[U,S,Wt,ft,Zt]),bn=t.useCallback(e=>{Y.current=!0,ye(e.changedTouches[0])},[ye]),kn=t.useCallback(e=>{if(Ie(e.changedTouches[0])){e.cancelable&&e.preventDefault();return}z&&ve.current<=1&&be.current!==null&&e.cancelable&&e.preventDefault()},[z,Ie]),xn=t.useCallback(e=>{Me(e.changedTouches[0])},[Me]),Rn=t.useCallback(e=>{if(Ke.current=!0,!Y.current&&e.button===0){ye(e);try{e.target.setPointerCapture(e.pointerId)}catch{}}},[ye]),vn=t.useCallback(e=>{Y.current||Ie(e)},[Ie]),Pn=t.useCallback(e=>{if(!Y.current){Me(e);try{e.target.releasePointerCapture(e.pointerId)}catch{}}},[Me]),yn=t.useCallback(e=>{Y.current||Ke.current||e.button===0&&ye(e)},[ye]),In=t.useCallback(e=>{Y.current||Ke.current||Ie(e)},[Ie]),Mn=t.useCallback(e=>{Y.current||Ke.current||Me(e)},[Me]),wn=t.useCallback(e=>{if(se==="scroll"&&ve.current>1&&!Y.current){const r=o.current;r&&(r.scrollLeft+=e.deltaX,r.scrollTop+=e.deltaY,Te.current=r.scrollLeft,je.current=r.scrollTop),e.cancelable&&e.preventDefault()}se==="zoom"&&(e.deltaY>=100?(Oe(e),e.cancelable&&e.preventDefault()):e.deltaY<=-100&&(ze(e),e.cancelable&&e.preventDefault()))},[se,o,Oe,ze]),Ln=t.useCallback(e=>{switch(e.key){case"ArrowLeft":e.preventDefault(),te&&G("left",!0);break;case"ArrowRight":e.preventDefault(),ne&&G("right",!0);break;case"+":case"=":e.preventDefault(),ie&&ze();break;case"-":e.preventDefault(),le&&Oe();break}},[te,ne,ie,le,G,ze,Oe]);t.useEffect(()=>{pe===2&&H(e=>{const r=e&-2;return r===0&&d?e:r}),ae.current=1/0,ce.current=-1/0},[nt,pe,d,H]);const Xt=t.useRef(Ae);return Xt.current=Ae,t.useEffect(()=>{n(F),Ce(F+1),Xt.current()},[F]),t.useEffect(()=>{if(Fe.current||Ue===null)return;Fe.current=!0;const e=()=>{E(()=>{at(r=>{const a=Ft.current;if(r===null)return Fe.current=!1,a;const u=a-r;return Math.abs(u)<.5?(Fe.current=!1,a):(e(),r+u*.1)})})};e()},[de,E]),t.useEffect(()=>{const e=o.current;e&&(e.scrollLeft=Dt)},[Dt,o]),t.useEffect(()=>{const e=o.current;e&&(e.scrollTop=zt)},[zt,o]),t.useEffect(()=>{St()},[s,St]),t.useEffect(()=>{Nt.current(re)},[re]),t.useEffect(()=>{ot(f[0])},[]),t.useEffect(()=>{const e=ct.current;return()=>{e.forEach(cancelAnimationFrame),e.clear()}},[]),{viewWidth:i,viewHeight:_,pageWidth:P,pageHeight:ue,xMargin:A,yMargin:fe,displayedPages:h,zoom:l,centerOffsetSmoothed:De,page:Qe,numPages:Lt,leftPage:it,rightPage:lt,showLeftPage:en,showRightPage:tn,pageUrlLoading:Vt,loadImage:qt,flip:I,flipOpacity:sn,polygonArray:hn,polygonWidth:nn,polygonHeight:rn,polygonBgSize:on,canFlipLeft:te,canFlipRight:ne,canZoomIn:ie,canZoomOut:le,boundingLeft:ge,boundingRight:Ee,cursor:an,viewportClass:ln,flipLeft:pn,flipRight:mn,zoomIn:ze,zoomOut:Oe,goToPage:gt,apiRef:Ct,handlers:{onTouchStart:bn,onTouchMove:kn,onTouchEnd:xn,onPointerDown:Rn,onPointerMove:vn,onPointerUp:Pn,onMouseDown:yn,onMouseMove:In,onMouseUp:Mn,onWheel:wn,onKeyDown:Ln},onImageLoad:Qt}}const Qn=t.forwardRef(function({pages:o,pagesHiRes:s,pageLabels:b,flipDuration:w,zoomDuration:v,zooms:D,perspective:L,nPolygons:y,ambient:j,gloss:C,swipeMin:S,singlePage:X,forwardDirection:g,centering:Q,startPage:re,loadingImage:oe,clickToZoom:U,dragToFlip:z,wheel:se,page:J,onPageChange:ee,onFlipLeftStart:f,onFlipLeftEnd:d,onFlipRightStart:i,onFlipRightEnd:_,onZoomStart:pe,onZoomEnd:nt,children:rt,className:Xe,...we},F){const H=t.useRef(null),n=Vn({pages:o,pagesHiRes:s,flipDuration:w,zoomDuration:v,zooms:D,perspective:L,nPolygons:y,ambient:j,gloss:C,swipeMin:S,singlePage:X,forwardDirection:g,centering:Q,startPage:re,loadingImage:oe,clickToZoom:U,dragToFlip:z,wheel:se,page:J,onPageChange:ee,onFlipLeftStart:f,onFlipLeftEnd:d,onFlipRightStart:i,onFlipRightEnd:_,onZoomStart:pe,onZoomEnd:nt},H);t.useImperativeHandle(F,()=>({get flipLeft(){return n.flipLeft},get flipRight(){return n.flipRight},get zoomIn(){return n.zoomIn},get zoomOut(){return n.zoomOut},get goToPage(){return n.goToPage},get canFlipLeft(){return n.apiRef.current.canFlipLeft},get canFlipRight(){return n.apiRef.current.canFlipRight},get canZoomIn(){return n.apiRef.current.canZoomIn},get canZoomOut(){return n.apiRef.current.canZoomOut},get page(){return n.apiRef.current.page},get numPages(){return n.apiRef.current.numPages}}),[n.flipLeft,n.flipRight,n.zoomIn,n.zoomOut,n.goToPage,n.apiRef]);const Le=l=>b&&b[l]?b[l]:`Page ${l+1}`,Ce=Xe?`${T.root} ${Xe}`:T.root;return W.jsxs("div",{...we,className:Ce,role:"document","aria-label":`Book viewer, page ${n.page} of ${n.numPages}`,"aria-roledescription":"flipbook",children:[rt?.({canFlipLeft:n.canFlipLeft,canFlipRight:n.canFlipRight,canZoomIn:n.canZoomIn,canZoomOut:n.canZoomOut,page:n.page,numPages:n.numPages,flipLeft:n.flipLeft,flipRight:n.flipRight,zoomIn:n.zoomIn,zoomOut:n.zoomOut,goToPage:n.goToPage}),W.jsx("div",{ref:H,className:n.viewportClass,style:{cursor:n.cursor==="grabbing"?"grabbing":"auto"},tabIndex:0,onKeyDown:n.handlers.onKeyDown,onTouchMove:n.handlers.onTouchMove,onPointerMove:n.handlers.onPointerMove,onMouseMove:n.handlers.onMouseMove,onTouchEnd:n.handlers.onTouchEnd,onTouchCancel:n.handlers.onTouchEnd,onPointerUp:n.handlers.onPointerUp,onPointerCancel:n.handlers.onPointerUp,onMouseUp:n.handlers.onMouseUp,onWheel:n.handlers.onWheel,children:W.jsxs("div",{className:T.container,style:{transform:`scale(${n.zoom})`},children:[W.jsx("div",{role:"button",tabIndex:n.canFlipLeft?0:-1,"aria-label":"Previous page","aria-disabled":!n.canFlipLeft,className:T.clickLeft,style:{cursor:n.canFlipLeft?"pointer":"auto"},onClick:n.flipLeft,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),n.flipLeft())}}),W.jsx("div",{role:"button",tabIndex:n.canFlipRight?0:-1,"aria-label":"Next page","aria-disabled":!n.canFlipRight,className:T.clickRight,style:{cursor:n.canFlipRight?"pointer":"auto"},onClick:n.flipRight,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),n.flipRight())}}),W.jsxs("div",{style:{transform:`translateX(${n.centerOffsetSmoothed}px)`},children:[n.showLeftPage&&W.jsx("img",{className:T.page,style:{width:n.pageWidth+"px",height:n.pageHeight+"px",left:n.xMargin+"px",top:n.yMargin+"px"},src:n.pageUrlLoading(n.leftPage,!0)??void 0,alt:Le(n.leftPage),onLoad:n.onImageLoad}),n.showRightPage&&W.jsx("img",{className:T.page,style:{width:n.pageWidth+"px",height:n.pageHeight+"px",left:n.viewWidth/2+"px",top:n.yMargin+"px"},src:n.pageUrlLoading(n.rightPage,!0)??void 0,alt:Le(n.rightPage),onLoad:n.onImageLoad}),W.jsx("div",{style:{opacity:n.flipOpacity},children:n.polygonArray.map(l=>W.jsx("div",{className:l.bgImage?T.polygon:T.polygonBlank,style:{backgroundImage:l.bgImage?`url(${n.loadImage(l.bgImage)})`:void 0,backgroundSize:n.polygonBgSize,backgroundPosition:l.bgPos,width:n.polygonWidth,height:n.polygonHeight,transform:l.transform,zIndex:l.z},children:l.lighting&&W.jsx("div",{className:T.lighting,style:{backgroundImage:l.lighting}})},l.key))}),W.jsx("div",{className:T.boundingBox,style:{left:n.boundingLeft+"px",top:n.yMargin+"px",width:n.boundingRight-n.boundingLeft+"px",height:n.pageHeight+"px",cursor:n.cursor},onTouchStart:n.handlers.onTouchStart,onPointerDown:n.handlers.onPointerDown,onMouseDown:n.handlers.onMouseDown})]})]})}),W.jsxs("div",{role:"status","aria-live":"polite","aria-atomic":"true",className:T.srOnly,children:["Page ",n.page," of ",n.numPages]})]})});exports.Flipbook=Qn;
|
package/dist/react-flipbook.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.
|
|
1
|
+
._root_jjdx8_1{display:flex;flex-direction:column;width:100%;height:100%}._viewport_jjdx8_8{width:100%;flex:1;min-height:0;touch-action:none;overscroll-behavior:contain}._viewportZoom_jjdx8_16{overflow:scroll;touch-action:pan-x pan-y}._viewportZoomDragToScroll_jjdx8_22{overflow:hidden}._container_jjdx8_27{position:relative;width:100%;height:100%;transform-origin:top left;-webkit-user-select:none;user-select:none}._clickToFlip_jjdx8_35{position:absolute;width:50%;height:100%;top:0;-webkit-user-select:none;user-select:none}._clickLeft_jjdx8_43{left:0}._clickRight_jjdx8_48{right:0}._boundingBox_jjdx8_53{position:absolute;-webkit-user-select:none;user-select:none}._page_jjdx8_58{position:absolute;backface-visibility:hidden}._polygon_jjdx8_63{position:absolute;top:0;left:0;background-repeat:no-repeat;backface-visibility:hidden;transform-origin:center left}._polygonBlank_jjdx8_72{background-color:var(--flipbook-blank-page-bg, #ddd)}._lighting_jjdx8_77{width:100%;height:100%}._srOnly_jjdx8_82{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}
|