@kaktos/flipbook-react 1.0.0 → 1.0.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/README.md +197 -3
- package/dist/react-flipbook.cjs +1 -1
- package/dist/react-flipbook.css +1 -1
- package/dist/react-flipbook.js +856 -691
- 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 Z=require("react/jsx-runtime"),e=require("react");function he(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=$t();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 $t(){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=he(c),b=he(o),x=[],v=0;v<4;v++)for(var j=[s[v],s[v+4],s[v+8],s[v+12]],L=0;L<4;L++){var I=L*4,F=[b[I],b[I+1],b[I+2],b[I+3]],C=j[0]*F[0]+j[1]*F[1]+j[2]*F[2]+j[3]*F[3];x[v+I]=C}return x}function Tn(c){var o=$t();return o[11]=-1/c,o}function Fn(c){var o=Math.PI/180*c,s=$t();return s[0]=s[10]=Math.cos(o),s[2]=s[8]=Math.sin(o),s[2]*=-1,s}function En(c){return"matrix3d("+he(c).join(", ")+")"}function Ye(c,o,s){var b=$t();return c!==void 0&&o!==void 0&&s!==void 0&&(b[12]=c,b[13]=o,b[14]=s),b}class ee{constructor(o){o?o instanceof ee?this.m=[...o.m]:this.m=[...o]:this.m=$t()}clone(){return new ee(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(Ye(o,s??0,0))}translate3d(o,s,b){this.multiply(Ye(o,s,b))}rotateY(o){this.multiply(Fn(o))}toString(){return En(this.m)}}function Dn(c,o,s){const[b,x]=e.useState(0),[v,j]=e.useState(0),[L,I]=e.useState(1),[F,C]=e.useState(0);return e.useEffect(()=>{const S=()=>{const $=c.current;if(!$)return;x($.clientWidth),j($.clientHeight);const g=$.clientWidth>$.clientHeight&&!o?2:1;I(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:F}}function jn(c,o,s,b,x,v,j){const[L,I]=e.useState(null),[F,C]=e.useState(null),[S,$]=e.useState({}),g=e.useRef({}),Q=e.useRef({count:0,target:0,cb:null}),rt=e.useRef(new Set),ot=e.useCallback((f,d=!1)=>{if(d&&x>1&&!v){const i=o[f];if(i)return i}return c[f]??null},[c,o,x,v]),U=e.useCallback(f=>L===null||S[f]?f:(g.current[f]||(g.current[f]=null,rt.current.add(f)),j),[L,S,j]);e.useEffect(()=>{const f=rt.current;f.size!==0&&(f.forEach(d=>{if(g.current[d])return;const i=new Image;g.current[d]=i,i.onload=()=>{$(_=>({..._,[d]:!0}))},i.src=d}),f.clear())});const X=e.useCallback((f,d=!1)=>{const i=ot(f,d);return d&&x>1&&!v?i:i?U(i):null},[ot,U,x,v]),st=e.useCallback((f=!1)=>{for(let d=s-3;d<=s+3;d++)X(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,X]),J=e.useCallback(f=>{const d=f.target;L===null&&(I(d.naturalWidth),C(d.naturalHeight));const i=Q.current;i.cb&&(i.count++,i.count>=i.target&&(i.cb(),i.cb=null))},[L]),tt=e.useCallback((f,d)=>{Q.current={count:0,target:f,cb:d}},[]);return{imageWidth:L,imageHeight:F,loadedImages:S,pageUrl:ot,loadImage:U,pageUrlLoading:X,preloadImages:st,onImageLoad:J,setImageLoadCallback:tt}}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_1ydjt_1",Zn="_viewport_1ydjt_8",Wn="_viewportZoom_1ydjt_14 _viewport_1ydjt_8",Nn="_viewportZoomDragToScroll_1ydjt_19 _viewportZoom_1ydjt_14 _viewport_1ydjt_8",$n="_container_1ydjt_24",Xn="_clickLeft_1ydjt_40 _clickToFlip_1ydjt_32",Hn="_clickRight_1ydjt_45 _clickToFlip_1ydjt_32",Bn="_boundingBox_1ydjt_50",Un="_page_1ydjt_55",Yn="_polygon_1ydjt_60",An="_polygonBlank_1ydjt_69 _polygon_1ydjt_60",Gn="_lighting_1ydjt_74",Kn="_srOnly_1ydjt_79",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 Ge(c){return c*c}function qn(c){return 1-Ge(1-c)}function Ae(c){return c<.5?Ge(c*2)/2:.5+qn((c-.5)*2)/2}const Nt={progress:0,direction:null,frontImage:null,backImage:null,auto:!1};function Vn(c,o){const{pages:s,pagesHiRes:b=[],flipDuration:x=1e3,zoomDuration:v=500,zooms:j=[1,2,4],perspective:L=2400,nPolygons:I=10,ambient:F=.4,gloss:C=.6,swipeMin:S=3,singlePage:$=!1,forwardDirection:g="right",centering:Q=!0,startPage:rt=null,loadingImage:ot=zn,clickToZoom:U=!0,dragToFlip:X=!0,wheel:st="scroll",page:J,onPageChange:tt}=c,f=j??[1],d=s[0]===null,{viewWidth:i,viewHeight:_,rawDisplayedPages:pt,pageAlignmentTick:ne}=Dn(o,$),[re,Xt]=e.useState(0),Mt=J!==void 0,E=Mt?J:re,H=e.useCallback(t=>{if(Mt){const r=typeof t=="function"?t(J):t;tt?.(r)}else Xt(t)},[Mt,J,tt]),[Ht,n]=e.useState(0),[wt,xt]=e.useState(1),[l,oe]=e.useState(f[0]),[Bt,se]=e.useState(0),[Lt,pe]=e.useState(!1),[M,B]=e.useState(Nt),[Ut,ae]=e.useState(null),[,me]=e.useState(0),h=pt===2&&(d&&(E===0||E===1))?1:pt,Ke=jn(s,b,E,h,l,Lt,ot),{imageWidth:mt,imageHeight:Yt,pageUrl:Ct,loadImage:qe,pageUrlLoading:Ve,preloadImages:At,onImageLoad:Qe,setImageLoadCallback:Gt}=Ke,St=e.useRef(null),be=e.useRef(null),bt=e.useRef(0),yt=e.useRef(null),Y=e.useRef(!1),Kt=e.useRef(!1),at=e.useRef(1/0),ct=e.useRef(-1/0),ye=e.useRef(0),ke=e.useRef(0),_t=e.useRef(0),Tt=e.useRef(0),Ft=e.useRef(!1),q=e.useRef(M);q.current=M;const kt=e.useRef(E);kt.current=E;const qt=e.useRef(h);qt.current=h;const Et=e.useRef(l);Et.current=l;const Vt=e.useRef(Bt);Vt.current=Bt;const Re=e.useRef(c.onFlipLeftStart);Re.current=c.onFlipLeftStart;const ve=e.useRef(c.onFlipLeftEnd);ve.current=c.onFlipLeftEnd;const Pe=e.useRef(c.onFlipRightStart);Pe.current=c.onFlipRightStart;const Ie=e.useRef(c.onFlipRightEnd);Ie.current=c.onFlipRightEnd;const Me=e.useRef(c.onZoomStart);Me.current=c.onZoomStart;const we=e.useRef(c.onZoomEnd);we.current=c.onZoomEnd;const Je=e.useRef(tt);Je.current=tt;const xe=e.useRef(H);xe.current=H;const ce=e.useRef(new Set),D=e.useCallback(t=>{const r=requestAnimationFrame(a=>{ce.current.delete(r),t(a)});return ce.current.add(r),r},[]),Le=d?s.length-1:s.length,Qt=d?Math.max(1,E):E+1,Ce=e.useRef({canFlipLeft:!1,canFlipRight:!1,canZoomIn:!1,canZoomOut:!1,page:0,numPages:0}),Se=e.useCallback(()=>{H(t=>h===1&&t===0&&s.length>0&&!s[0]?1:t)},[h,s,H]),_e=!M.direction&&E<s.length-h,Te=!M.direction&&E>=h&&!(h===1&&!Ct(Ht-1)),et=g==="left"?_e:Te,nt=g==="right"?_e:Te,it=!Lt&&Bt<f.length-1,lt=!Lt&&Bt>0;Ce.current={canFlipLeft:et,canFlipRight:nt,canZoomIn:it,canZoomOut:lt,page:Qt,numPages:Le};const ie=g==="right"||h===1?Ht:wt,le=g==="left"?Ht:wt,tn=!!Ct(ie),en=!!Ct(le)&&h===2,Fe=mt&&Yt?Math.min(i/h/mt,_/Yt,1):1,P=mt?Math.round(mt*Fe):0,ut=Yt?Math.round(Yt*Fe):0,A=(i-P*h)/2,ft=(_-ut)/2,nn=Math.ceil(P/I+1/l)+"px",rn=ut+"px",on=`${P}px ${ut}px`,sn=e.useMemo(()=>{if(!M.direction||h!==1)return 1;let t=M.progress;return M.direction!==g&&(t=1-t),t>.7?1-(t-.7)/.3:1},[M.direction,M.progress,h,g]),gt=(()=>{if(h===1)return A;const t=Ct(ie)?A:i/2;return M.direction?t<at.current?t:at.current:t})(),Dt=(()=>{if(h===1)return i-A;const t=Ct(le)?i-A:i/2;return M.direction?t>ct.current?t:ct.current:t})(),dt=Q?Math.round(i/2-(gt+Dt)/2):0,Ee=e.useRef(dt);Ee.current=dt;const De=e.useRef(h);e.useEffect(()=>{Ut===null&&mt!==null&&ae(dt)},[Ut,mt,dt]),e.useEffect(()=>{De.current!==h&&(De.current=h,ae(dt),Ft.current=!1)},[h,dt]);const jt=Math.round(Ut??0),an=yt.current?yt.current:U&&it?"zoom-in":U&<?"zoom-out":X?"grab":"auto",cn=!Y.current,ln=(Lt||l>1)&&cn?T.viewportZoomDragToScroll:Lt||l>1?T.viewportZoom:T.viewport,un=(()=>{const t=(Dt-gt)*l;return t<i?(gt+jt)*l-(i-t)/2:(gt+jt)*l})(),fn=(()=>{const t=(Dt-gt)*l;return t<i?(gt+jt)*l-(i-t)/2:(Dt+jt)*l-i})(),gn=(()=>{const t=ut*l;return t<_?ft*l-(_-t)/2:ft*l})(),dn=(()=>{const t=ut*l;return t<_?ft*l-(_-t)/2:(ft+ut)*l-_})(),je=Math.min(fn,Math.max(un,_t.current)),ze=Math.min(dn,Math.max(gn,Tt.current)),Oe=e.useCallback((t,r)=>{const a=[],u=[-.5,-.25,0,.25,.5];if(F<1){const p=1-F,m=u.map(y=>(1-Math.cos((t-r*y)/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 y=u.map(k=>Math.max(Math.pow(Math.cos((t+30-r*k)/180*Math.PI),200),Math.pow(Math.cos((t-30-r*k)/180*Math.PI),200)));a.push(`linear-gradient(to right,rgba(255,255,255,${y[0]*C}),rgba(255,255,255,${y[1]*C}) 25%,rgba(255,255,255,${y[2]*C}) 50%,rgba(255,255,255,${y[3]*C}) 75%,rgba(255,255,255,${y[4]*C}))`)}return a.join(",")},[F,C]),ue=e.useCallback(t=>{const r=q.current;if(!r.direction)return[];if(!Number.isFinite(P)||P<=0||I<=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=t==="front"?r.frontImage:r.backImage,m=P/I;let y=A,k=!1;h===1?g==="right"?t==="back"&&(k=!0,y=A-P):u==="left"?t==="back"?y=P-A:k=!0:t==="front"?y=P-A:k=!0:u==="left"?t==="back"?y=i/2:k=!0:t==="front"?y=i/2:k=!0;const R=new ee;R.translate(i/2),R.perspective(L),R.translate(-i/2),R.translate(y,ft);let z=0;a>.5&&(z=-(a-.5)*2*180),u==="left"&&(z=-z),t==="back"&&(z+=180),z&&(k&&R.translate(P),R.rotateY(z),k&&R.translate(-P));let w;a<.5?w=a*2*Math.PI:w=(1-(a-.5)*2)*Math.PI,w===0&&(w=1e-9);const ht=P/w;let W=0;const O=w/I;let N=O/2/Math.PI*180;const V=O/Math.PI*180;k&&(N=-w/Math.PI*180+V/2),t==="back"&&(N=-N);const Zt=t==="back"?-V:V;at.current=1/0,ct.current=-1/0;const K=[];for(let Jt=0;Jt<I;Jt++){const Cn=`${Jt/(I-1)*100}% 0px`,Wt=R.clone(),He=k?w-W:W;let de=Math.sin(He)*ht;k&&(de=P-de);let te=(1-Math.cos(He))*ht;t==="back"&&(te=-te),Wt.translate3d(de,0,te),Wt.rotateY(-N);const Be=Wt.transformX(0),Ue=Wt.transformX(m);ct.current=Math.max(Math.max(Be,Ue),ct.current),at.current=Math.min(Math.min(Be,Ue),at.current);const Sn=Oe(z-N,Zt);W+=O,N+=Zt,K.push({key:t+Jt,bgImage:p,lighting:Sn,bgPos:Cn,transform:Wt.toString(),z:Math.abs(Math.round(te))})}return K},[h,g,P,A,ft,i,L,I,Oe]),hn=e.useMemo(()=>M.direction?[...ue("front"),...ue("back")]:[],[M.direction,M.progress,M.frontImage,M.backImage,ue]),G=e.useCallback((t,r)=>{const a=kt.current,u=qt.current;let p=null,m=null;t!==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:t,frontImage:p,backImage:m,auto:!1}),D(()=>{D(()=>{t!==g?u===2&&n(a-u):u===1?n(a+u):xt(a+1+u),r&&fe(t)})})},[g,s,D]),fe=e.useCallback(t=>{const r=q.current,a=x*(1-r.progress),u=r.progress;B(R=>({...R,auto:!0}));const p=kt.current,m=s[0]!==null?p+1:Math.max(1,p);t==="left"?Re.current?.(m):Pe.current?.(m);let y=null;const k=R=>{y===null&&(y=R);const z=R-y;let w=u+z/a;w>1&&(w=1);const ht=Ae(w);if(B(W=>({...W,progress:ht})),w<1)D(k);else{const W=qt.current;let O;t!==g?O=kt.current-W:O=kt.current+W,xe.current(O);const N=s[0]!==null?O+1:Math.max(1,O);t==="left"?ve.current?.(N):Ie.current?.(N),W===1&&t===g?B(Nt):Gt(1,()=>{B(Nt)})}};D(k)},[x,g,s,Gt,D]),Ze=e.useCallback(()=>{const t=q.current,r=x*t.progress,a=t.progress;B(m=>({...m,auto:!0}));let u=null;const p=m=>{u===null&&(u=m);const y=m-u;let k=a-a*y/r;if(k<0&&(k=0),B(R=>({...R,progress:k})),k>0)D(p);else{const R=kt.current;n(R),xt(R+1);const z=qt.current,w=q.current.direction;z===1&&w!==g?B(Nt):Gt(1,()=>{B(Nt)})}};D(p)},[x,g,Gt,D]),pn=e.useCallback(()=>{et&&G("left",!0)},[et,G]),mn=e.useCallback(()=>{nt&&G("right",!0)},[nt,G]),Rt=e.useCallback((t,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=Et.current,y=t,k=a.scrollLeft,R=a.scrollTop,z=u+k,w=p+R,ht=z/m*y-u,W=w/m*y-p;pe(!0),Me.current?.(t);let O=null;const N=V=>{O===null&&(O=V);const Zt=V-O;let K=Zt/v;K>1&&(K=1),K=Ae(K),oe(m+(y-m)*K),_t.current=k+(ht-k)*K,Tt.current=R+(W-R)*K,Zt<v?D(N):(we.current?.(t),pe(!1),oe(t),_t.current=ht,Tt.current=W)};D(N),y>1&&At(!0)},[v,o,At,D]),zt=e.useCallback(t=>{if(!it)return;const r=Vt.current+1;se(r),Rt(f[r],t)},[it,f,Rt]),Ot=e.useCallback(t=>{if(!lt)return;const r=Vt.current-1;se(r),Rt(f[r],t)},[lt,f,Rt]),We=e.useCallback(t=>{const r=(Vt.current+1)%f.length;se(r),Rt(f[r],t)},[f,Rt]),ge=e.useCallback(t=>{if(t===null||t===Qt)return;let r;s[0]===null?h===2&&t===1?r=0:r=t:r=t-1,(h===2&&r>0&&s[0]===null||h===2&&s[0]!==null)&&(r=r&-2),H(r),at.current=1/0,ct.current=-1/0},[Qt,s,h,H]),Ne=e.useRef(ge);Ne.current=ge;const $e=e.useCallback((t,r)=>{const a=o.current;a&&(a.scrollLeft=ye.current-t,a.scrollTop=ke.current-r,_t.current=a.scrollLeft,Tt.current=a.scrollTop)},[o]),vt=e.useCallback(t=>{if(St.current=t.pageX,be.current=t.pageY,bt.current=0,Et.current<=1)X&&(yt.current="grab");else{const r=o.current;r&&(ye.current=r.scrollLeft,ke.current=r.scrollTop),yt.current="all-scroll"}},[X,o]),Pt=e.useCallback(t=>{if(St.current===null)return!1;const r=t.pageX-St.current,a=t.pageY-be.current;if(bt.current=Math.max(bt.current,Math.abs(r)),bt.current=Math.max(bt.current,Math.abs(a)),Et.current>1)return Y.current||$e(r,a),!1;if(!X||Math.abs(a)>Math.abs(r)||!Number.isFinite(P)||P<=0)return!1;yt.current="grabbing",me(p=>p+1);const u=q.current;return r>0?(u.direction===null&&et&&r>=S&&G("left",!1),q.current.direction==="left"&&B(p=>({...p,progress:Math.min(r/P,1)}))):(u.direction===null&&nt&&r<=-S&&G("right",!1),q.current.direction==="right"&&B(p=>({...p,progress:Math.min(-r/P,1)}))),!0},[X,et,nt,S,G,P,$e]),It=e.useCallback(t=>{if(St.current===null)return;U&&bt.current<S&&We(t);const r=q.current;r.direction!==null&&!r.auto&&(r.progress>1/4?fe(r.direction):Ze()),St.current=null,yt.current=null,me(a=>a+1)},[U,S,We,fe,Ze]),bn=e.useCallback(t=>{Y.current=!0,vt(t.changedTouches[0])},[vt]),yn=e.useCallback(t=>{Pt(t.changedTouches[0])&&t.cancelable&&t.preventDefault()},[Pt]),kn=e.useCallback(t=>{It(t.changedTouches[0])},[It]),Rn=e.useCallback(t=>{if(Kt.current=!0,!Y.current&&t.button===0){vt(t);try{t.target.setPointerCapture(t.pointerId)}catch{}}},[vt]),vn=e.useCallback(t=>{Y.current||Pt(t)},[Pt]),Pn=e.useCallback(t=>{if(!Y.current){It(t);try{t.target.releasePointerCapture(t.pointerId)}catch{}}},[It]),In=e.useCallback(t=>{Y.current||Kt.current||t.button===0&&vt(t)},[vt]),Mn=e.useCallback(t=>{Y.current||Kt.current||Pt(t)},[Pt]),wn=e.useCallback(t=>{Y.current||Kt.current||It(t)},[It]),xn=e.useCallback(t=>{if(st==="scroll"&&Et.current>1&&!Y.current){const r=o.current;r&&(r.scrollLeft+=t.deltaX,r.scrollTop+=t.deltaY,_t.current=r.scrollLeft,Tt.current=r.scrollTop),t.cancelable&&t.preventDefault()}st==="zoom"&&(t.deltaY>=100?(Ot(t),t.cancelable&&t.preventDefault()):t.deltaY<=-100&&(zt(t),t.cancelable&&t.preventDefault()))},[st,o,Ot,zt]),Ln=e.useCallback(t=>{switch(t.key){case"ArrowLeft":t.preventDefault(),et&&G("left",!0);break;case"ArrowRight":t.preventDefault(),nt&&G("right",!0);break;case"+":case"=":t.preventDefault(),it&&zt();break;case"-":t.preventDefault(),lt&&Ot();break}},[et,nt,it,lt,G,zt,Ot]);e.useEffect(()=>{pt===2&&H(t=>{const r=t&-2;return r===0&&d?t:r}),at.current=1/0,ct.current=-1/0},[ne,pt,d,H]);const Xe=e.useRef(At);return Xe.current=At,e.useEffect(()=>{n(E),xt(E+1),Xe.current()},[E]),e.useEffect(()=>{if(Ft.current||Ut===null)return;Ft.current=!0;const t=()=>{D(()=>{ae(r=>{const a=Ee.current;if(r===null)return Ft.current=!1,a;const u=a-r;return Math.abs(u)<.5?(Ft.current=!1,a):(t(),r+u*.1)})})};t()},[dt,D]),e.useEffect(()=>{const t=o.current;t&&(t.scrollLeft=je)},[je,o]),e.useEffect(()=>{const t=o.current;t&&(t.scrollTop=ze)},[ze,o]),e.useEffect(()=>{Se()},[s,Se]),e.useEffect(()=>{Ne.current(rt)},[rt]),e.useEffect(()=>{oe(f[0])},[]),e.useEffect(()=>{const t=ce.current;return()=>{t.forEach(cancelAnimationFrame),t.clear()}},[]),{viewWidth:i,viewHeight:_,pageWidth:P,pageHeight:ut,xMargin:A,yMargin:ft,displayedPages:h,zoom:l,centerOffsetSmoothed:jt,page:Qt,numPages:Le,leftPage:ie,rightPage:le,showLeftPage:tn,showRightPage:en,pageUrlLoading:Ve,loadImage:qe,flip:M,flipOpacity:sn,polygonArray:hn,polygonWidth:nn,polygonHeight:rn,polygonBgSize:on,canFlipLeft:et,canFlipRight:nt,canZoomIn:it,canZoomOut:lt,boundingLeft:gt,boundingRight:Dt,cursor:an,viewportClass:ln,flipLeft:pn,flipRight:mn,zoomIn:zt,zoomOut:Ot,goToPage:ge,apiRef:Ce,handlers:{onTouchStart:bn,onTouchMove:yn,onTouchEnd:kn,onPointerDown:Rn,onPointerMove:vn,onPointerUp:Pn,onMouseDown:In,onMouseMove:Mn,onMouseUp:wn,onWheel:xn,onKeyDown:Ln},onImageLoad:Qe}}const Qn=e.forwardRef(function({pages:o,pagesHiRes:s,pageLabels:b,flipDuration:x,zoomDuration:v,zooms:j,perspective:L,nPolygons:I,ambient:F,gloss:C,swipeMin:S,singlePage:$,forwardDirection:g,centering:Q,startPage:rt,loadingImage:ot,clickToZoom:U,dragToFlip:X,wheel:st,page:J,onPageChange:tt,onFlipLeftStart:f,onFlipLeftEnd:d,onFlipRightStart:i,onFlipRightEnd:_,onZoomStart:pt,onZoomEnd:ne,children:re,className:Xt,...Mt},E){const H=e.useRef(null),n=Vn({pages:o,pagesHiRes:s,flipDuration:x,zoomDuration:v,zooms:j,perspective:L,nPolygons:I,ambient:F,gloss:C,swipeMin:S,singlePage:$,forwardDirection:g,centering:Q,startPage:rt,loadingImage:ot,clickToZoom:U,dragToFlip:X,wheel:st,page:J,onPageChange:tt,onFlipLeftStart:f,onFlipLeftEnd:d,onFlipRightStart:i,onFlipRightEnd:_,onZoomStart:pt,onZoomEnd:ne},H);e.useImperativeHandle(E,()=>({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 wt=l=>b&&b[l]?b[l]:`Page ${l+1}`,xt=Xt?`${T.root} ${Xt}`:T.root;return Z.jsxs("div",{...Mt,className:xt,role:"document","aria-label":`Book viewer, page ${n.page} of ${n.numPages}`,"aria-roledescription":"flipbook",children:[re?.({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}),Z.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:Z.jsxs("div",{className:T.container,style:{transform:`scale(${n.zoom})`},children:[Z.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())}}),Z.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())}}),Z.jsxs("div",{style:{transform:`translateX(${n.centerOffsetSmoothed}px)`},children:[n.showLeftPage&&Z.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:wt(n.leftPage),onLoad:n.onImageLoad}),n.showRightPage&&Z.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:wt(n.rightPage),onLoad:n.onImageLoad}),Z.jsx("div",{style:{opacity:n.flipOpacity},children:n.polygonArray.map(l=>Z.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&&Z.jsx("div",{className:T.lighting,style:{backgroundImage:l.lighting}})},l.key))}),Z.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})]})]})}),Z.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_1ydjt_1{display:flex;flex-direction:column;width:100%;height:100%}._viewport_1ydjt_8{width:100%;flex:1;min-height:0}._viewportZoom_1ydjt_14{overflow:scroll}._viewportZoomDragToScroll_1ydjt_19{overflow:hidden}._container_1ydjt_24{position:relative;width:100%;height:100%;transform-origin:top left;-webkit-user-select:none;user-select:none}._clickToFlip_1ydjt_32{position:absolute;width:50%;height:100%;top:0;-webkit-user-select:none;user-select:none}._clickLeft_1ydjt_40{left:0}._clickRight_1ydjt_45{right:0}._boundingBox_1ydjt_50{position:absolute;-webkit-user-select:none;user-select:none}._page_1ydjt_55{position:absolute;backface-visibility:hidden}._polygon_1ydjt_60{position:absolute;top:0;left:0;background-repeat:no-repeat;backface-visibility:hidden;transform-origin:center left}._polygonBlank_1ydjt_69{background-color:var(--flipbook-blank-page-bg, #ddd)}._lighting_1ydjt_74{width:100%;height:100%}._srOnly_1ydjt_79{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}
|