html-flip-book-vanilla 0.0.0-alpha.10 → 0.0.0-alpha.15

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.
@@ -4,6 +4,7 @@ import type { FlipPosition, Leaf } from "../leaf";
4
4
  interface LeafTestable {
5
5
  currentAnimation: Promise<void> | null;
6
6
  targetFlipPosition: FlipPosition | null;
7
+ hoverShadow: number;
7
8
  }
8
9
  interface MockLeaf {
9
10
  index: number;
@@ -1 +1 @@
1
- {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/__tests__/test-utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"test-utils.d.ts","sourceRoot":"","sources":["../../src/__tests__/test-utils.ts"],"names":[],"mappings":"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"}
package/dist/flipbook.css CHANGED
@@ -1 +1 @@
1
- .page{position:absolute;backface-visibility:hidden;transform-style:preserve-3d}.page>*{max-width:100%;max-height:100%;height:100%;width:100%;box-sizing:border-box}.flipbook{height:100%;width:100%;overflow:hidden}.flipbook-debug-bar{position:absolute;bottom:0;left:0;width:100%;background-color:#00000080;color:#fff;padding:10px;box-sizing:border-box;display:flex;flex-wrap:wrap;justify-content:space-between;z-index:9999}
1
+ .page{position:absolute;backface-visibility:hidden;transform-style:preserve-3d;--inner-shadow-shadow: 0;--inner-shadow-highlight: 0;--inner-shadow-lift: 0px;--inner-shadow-edge: right}.page:before,.page:after{content:"";position:absolute;inset:0;pointer-events:none;backface-visibility:hidden;transform-style:preserve-3d;transition:opacity .12s ease,transform .12s ease;will-change:opacity,transform}.page:before{background:linear-gradient(to var(--inner-shadow-edge),rgba(0,0,0,calc(.35 * var(--inner-shadow-shadow))) 0%,rgba(0,0,0,0) 40%);opacity:var(--inner-shadow-shadow);mix-blend-mode:multiply;transform:translateZ(var(--inner-shadow-lift))}.page:after{background:linear-gradient(to var(--inner-shadow-edge),rgba(255,255,255,calc(.4 * var(--inner-shadow-highlight))) 0%,rgba(255,255,255,0) 45%);opacity:var(--inner-shadow-highlight);transform:translateZ(calc(var(--inner-shadow-lift) * .6))}.page>*{max-width:100%;max-height:100%;height:100%;width:100%;box-sizing:border-box}.flipbook{height:100%;width:100%;overflow:hidden}.flipbook-debug-bar{position:absolute;bottom:0;left:0;width:100%;background-color:#00000080;color:#fff;padding:10px;box-sizing:border-box;display:flex;flex-wrap:wrap;justify-content:space-between;z-index:9999}
@@ -18,6 +18,8 @@ declare class FlipBook {
18
18
  private activeFlips;
19
19
  private pendingFlipStartingPos;
20
20
  private pendingFlipDirection;
21
+ private isDragging;
22
+ private hoveredLeaf;
21
23
  touchStartingPos: {
22
24
  x: number;
23
25
  y: number;
@@ -37,11 +39,15 @@ declare class FlipBook {
37
39
  private onDragEnd;
38
40
  private handleTouchStart;
39
41
  private handleTouchMove;
42
+ private handleMouseMove;
43
+ private handleMouseLeave;
44
+ private clearHoverShadow;
40
45
  private onTurned;
41
46
  get currentPageIndex(): number;
42
47
  get totalPages(): number;
43
48
  get isFirstPage(): boolean;
44
49
  get isLastPage(): boolean;
50
+ private hasActiveAutoFlipInDirection;
45
51
  flipNext(): Promise<void>;
46
52
  flipPrev(): Promise<void>;
47
53
  goToPage(pageIndex: number): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"flipbook.d.ts","sourceRoot":"","sources":["../src/flipbook.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,iBAAiB,CAAC;AAGzB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AActD,cAAM,QAAQ;IACb,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAwC;IACxE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAG/B;IACF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA8B;IACjE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA0B;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAA8B;IAC7D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA4B;IAC1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IACvC,OAAO,CAAC,MAAM,CAAc;IAE5B,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,sBAAsB,CAAK;IACnC,OAAO,CAAC,oBAAoB,CAAqC;IACjE,gBAAgB;;;MAAkB;IAClC,OAAO,CAAC,sBAAsB,CAA0C;IAExE,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,KAAK,KAAK,GAEhB;IAED,OAAO,KAAK,sBAAsB,GAcjC;gBAEW,OAAO,EAAE,eAAe;IAYpC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,UAAQ;IA2JtC,OAAO,CAAC,4BAA4B;IA8BpC,OAAO,CAAC,YAAY;IAqBpB,OAAO,KAAK,iBAAiB,GAO5B;IAMD,OAAO,CAAC,oBAAoB;IAgC5B,OAAO,CAAC,WAAW;IAYnB,OAAO,CAAC,YAAY;IA0EpB,OAAO,CAAC,SAAS;IA+CjB,OAAO,CAAC,gBAAgB,CAMtB;IAEF,OAAO,CAAC,eAAe,CAYrB;IACF,OAAO,CAAC,QAAQ;IAwBhB,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAKD,IAAI,UAAU,IAAI,MAAM,CAEvB;IAKD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAKD,IAAI,UAAU,IAAI,OAAO,CAGxB;IAMK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAwBzB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA0BzB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgChD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAwDnC,OAAO,CAAC,kBAAkB;IA4C1B,OAAO;CAUP;AAED,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"flipbook.d.ts","sourceRoot":"","sources":["../src/flipbook.ts"],"names":[],"mappings":"AAAA,OAAO,cAAc,CAAC;AACtB,OAAO,iBAAiB,CAAC;AAIzB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAqBtD,cAAM,QAAQ;IACb,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAwC;IACxE,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAG/B;IACF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAwB;IAClD,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAA8B;IACjE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA0B;IAC9D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAA8B;IAC7D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA4B;IAC1D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IACvC,OAAO,CAAC,MAAM,CAAc;IAE5B,OAAO,CAAC,WAAW,CAAqC;IACxD,OAAO,CAAC,sBAAsB,CAAK;IACnC,OAAO,CAAC,oBAAoB,CAAqC;IACjE,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,WAAW,CAAmB;IACtC,gBAAgB;;;MAAkB;IAClC,OAAO,CAAC,sBAAsB,CAA0C;IAExE,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,KAAK,KAAK,GAEhB;IAED,OAAO,KAAK,sBAAsB,GAcjC;gBAEW,OAAO,EAAE,eAAe;IAYpC,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,UAAQ;IAgKtC,OAAO,CAAC,4BAA4B;IA8BpC,OAAO,CAAC,YAAY;IAqBpB,OAAO,KAAK,iBAAiB,GAO5B;IAMD,OAAO,CAAC,oBAAoB;IAgC5B,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,YAAY;IA0EpB,OAAO,CAAC,SAAS;IAkDjB,OAAO,CAAC,gBAAgB,CAMtB;IAEF,OAAO,CAAC,eAAe,CAYrB;IAEF,OAAO,CAAC,eAAe,CA2CpB;IAEH,OAAO,CAAC,gBAAgB,CAEtB;IAEF,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,QAAQ;IAwBhB,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAKD,IAAI,UAAU,IAAI,MAAM,CAEvB;IAKD,IAAI,WAAW,IAAI,OAAO,CAEzB;IAKD,IAAI,UAAU,IAAI,OAAO,CAGxB;IAKD,OAAO,CAAC,4BAA4B;IAa9B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BzB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IA+BzB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgChD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAkEnC,OAAO,CAAC,kBAAkB;IAQ1B,OAAO;CAeP;AAED,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,CAAC"}
package/dist/flipbook.js CHANGED
@@ -1,13 +1,15 @@
1
- import $ from "hammerjs";
2
- import { throttle as k } from "throttle-debounce";
3
- var h = /* @__PURE__ */ ((v) => (v.Forward = "Forward", v.Backward = "Backward", v.None = "None", v))(h || {});
4
- class A {
5
- constructor(t, e, s, i, a) {
6
- this.index = t, this.pages = e, this.bookProperties = i, this.onTurned = a, this.wrappedFlipPosition = s ? 1 : 0;
1
+ import M from "hammerjs";
2
+ import { throttle as b } from "throttle-debounce";
3
+ var l = /* @__PURE__ */ ((g) => (g.Forward = "Forward", g.Backward = "Backward", g.None = "None", g))(l || {});
4
+ const A = 1.1, R = 0.9, k = 8;
5
+ class D {
6
+ constructor(t, e, i, s, c) {
7
+ this.index = t, this.pages = e, this.bookProperties = s, this.onTurned = c, this.wrappedFlipPosition = i ? 1 : 0;
7
8
  }
8
9
  currentAnimation = null;
9
10
  targetFlipPosition = null;
10
11
  wrappedFlipPosition;
12
+ hoverShadow = 0;
11
13
  get isTurned() {
12
14
  return this.flipPosition === 1;
13
15
  }
@@ -29,56 +31,63 @@ class A {
29
31
  get flipPosition() {
30
32
  return this.wrappedFlipPosition;
31
33
  }
34
+ setHoverShadow(t) {
35
+ const e = Math.max(0, Math.min(1, t));
36
+ this.hoverShadow !== e && (this.hoverShadow = e, this.applyTransform(this.flipPosition));
37
+ }
32
38
  async flipToPosition(t, e = 225) {
33
- return this.currentAnimation && await this.currentAnimation, this.flipPosition === t ? Promise.resolve() : this.targetFlipPosition === t ? this.currentAnimation ?? Promise.resolve() : (this.targetFlipPosition = t, this.currentAnimation = new Promise((s) => {
34
- const i = this.flipPosition, l = Math.abs(t - i) * 180 / e * 1e3, r = performance.now(), c = (m) => {
35
- const d = m - r;
39
+ return this.currentAnimation && await this.currentAnimation, this.flipPosition === t ? Promise.resolve() : this.targetFlipPosition === t ? this.currentAnimation ?? Promise.resolve() : (this.targetFlipPosition = t, this.currentAnimation = new Promise((i) => {
40
+ const s = this.flipPosition, r = Math.abs(t - s) * 180 / e * 1e3, n = performance.now(), h = (f) => {
41
+ const d = f - n;
36
42
  if (d < 0) {
37
- requestAnimationFrame(c);
43
+ requestAnimationFrame(h);
38
44
  return;
39
45
  }
40
- const o = Math.min(d / l, 1), n = i + o * (t - i);
41
- this.pages.forEach((f, b) => {
42
- const u = this.bookProperties.isLTR;
43
- if (f) {
44
- const p = b % 2 + 1 === 1, P = `${p ? u ? n > 0.5 ? 180 - n * 180 : -n * 180 : n > 0.5 ? -(180 - n * 180) : n * 180 : u ? n < 0.5 ? -n * 180 : 180 - n * 180 : n < 0.5 ? n * 180 : -(180 - n * 180)}deg`, g = `${p ? u ? "100%" : "-100%" : "0px"}`, L = p ? n > 0.5 ? -1 : 1 : n < 0.5 ? -1 : 1;
45
- f.style.transform = `translateX(${g})rotateY(${P})scaleX(${L})`, f.style.transformOrigin = p ? `${u ? "left" : "right"}` : `${u ? "right" : "left"}`, f.style.zIndex = `${n > 0.5 ? f.dataset.pageIndex : this.bookProperties.pagesCount - f.dataset.pageIndex}`;
46
- }
47
- }), this.flipPosition = Math.max(0, Math.min(1, n)), (this.flipPosition === 1 || this.flipPosition === 0) && this.onTurned(this.flipPosition === 1 ? h.Forward : h.Backward), o < 1 ? requestAnimationFrame(c) : (this.currentAnimation = null, this.targetFlipPosition = null, s());
46
+ const o = Math.min(d / r, 1), a = s + o * (t - s);
47
+ this.applyTransform(a), this.flipPosition = Math.max(0, Math.min(1, a)), (this.flipPosition === 1 || this.flipPosition === 0) && this.onTurned(this.flipPosition === 1 ? l.Forward : l.Backward), o < 1 ? requestAnimationFrame(h) : (this.currentAnimation = null, this.targetFlipPosition = null, i());
48
48
  };
49
- requestAnimationFrame(c);
49
+ requestAnimationFrame(h);
50
50
  }), this.currentAnimation);
51
51
  }
52
52
  async efficientFlipToPosition(t, e = 2e4) {
53
- return k(1, this.flipToPosition.bind(this))(t, e);
53
+ return b(1, this.flipToPosition.bind(this))(t, e);
54
+ }
55
+ applyTransform(t) {
56
+ const e = Math.max(0, Math.min(1, t)), i = Math.sin(e * Math.PI), s = Math.max(i, this.hoverShadow), c = Math.min(1, s * A), r = Math.min(1, s * R), n = `${(s * k).toFixed(3)}px`;
57
+ this.pages.forEach((h, f) => {
58
+ const d = this.bookProperties.isLTR;
59
+ if (!h) return;
60
+ const o = f % 2 + 1 === 1, u = `${o ? d ? e > 0.5 ? 180 - e * 180 : -e * 180 : e > 0.5 ? -(180 - e * 180) : e * 180 : d ? e < 0.5 ? -e * 180 : 180 - e * 180 : e < 0.5 ? e * 180 : -(180 - e * 180)}deg`, T = `${o ? d ? "100%" : "-100%" : "0px"}`, p = o ? e > 0.5 ? -1 : 1 : e < 0.5 ? -1 : 1, m = o ? d ? "left" : "right" : d ? "right" : "left", w = m === "left" ? "right" : "left";
61
+ h.style.transform = `translateX(${T})rotateY(${u})scaleX(${p})`, h.style.transformOrigin = m, h.style.zIndex = `${e > 0.5 ? h.dataset.pageIndex : this.bookProperties.pagesCount - h.dataset.pageIndex}`, h.style.setProperty("--inner-shadow-shadow", c.toFixed(3)), h.style.setProperty("--inner-shadow-highlight", r.toFixed(3)), h.style.setProperty("--inner-shadow-lift", n), h.style.setProperty("--inner-shadow-edge", w);
62
+ });
54
63
  }
55
64
  }
56
- class F {
65
+ class L {
57
66
  constructor(t, e) {
58
67
  this.width = t, this.height = e;
59
68
  }
60
69
  static from(t) {
61
- return new F(t.width, t.height);
70
+ return new L(t.width, t.height);
62
71
  }
63
72
  get value() {
64
73
  return this.width / this.height;
65
74
  }
66
75
  }
67
- class T {
76
+ class P {
68
77
  constructor(t, e) {
69
- this.width = t, this.height = e, this.aspectRatio = new F(t, e);
78
+ this.width = t, this.height = e, this.aspectRatio = new L(t, e);
70
79
  }
71
80
  aspectRatio;
72
81
  aspectRatioFit(t) {
73
- const e = F.from(t).value;
74
- return this.aspectRatio.value > e ? new T(this.height * e, this.height) : new T(this.width, this.width / e);
82
+ const e = L.from(t).value;
83
+ return this.aspectRatio.value > e ? new P(this.height * e, this.height) : new P(this.width, this.width / e);
75
84
  }
76
85
  get asString() {
77
86
  return `${this.width}x${this.height}`;
78
87
  }
79
88
  }
80
- const R = 500;
81
- class D {
89
+ const E = 500, C = 0.18, $ = 0.12, I = 16;
90
+ class H {
82
91
  bookElement;
83
92
  pageElements = [];
84
93
  pagesCount;
@@ -88,7 +97,7 @@ class D {
88
97
  height: 3.15
89
98
  };
90
99
  direction = "ltr";
91
- fastDeltaThreshold = R;
100
+ fastDeltaThreshold = E;
92
101
  initialTurnedLeaves = /* @__PURE__ */ new Set();
93
102
  onPageChanged;
94
103
  pageSemantics;
@@ -97,7 +106,9 @@ class D {
97
106
  // flipping state - supports concurrent page flipping
98
107
  activeFlips = /* @__PURE__ */ new Map();
99
108
  pendingFlipStartingPos = 0;
100
- pendingFlipDirection = h.None;
109
+ pendingFlipDirection = l.None;
110
+ isDragging = !1;
111
+ hoveredLeaf;
101
112
  touchStartingPos = { x: 0, y: 0 };
102
113
  prevVisiblePageIndices;
103
114
  // Hammer instance for cleanup
@@ -108,9 +119,9 @@ class D {
108
119
  get currentOrTurningLeaves() {
109
120
  let t = -1;
110
121
  for (let e = this.leaves.length - 1; e >= 0; e--) {
111
- const s = this.leaves[e];
112
- if (s.isTurned || s.isTurning) {
113
- t = s.index + 1;
122
+ const i = this.leaves[e];
123
+ if (i.isTurned || i.isTurning) {
124
+ t = i.index + 1;
114
125
  break;
115
126
  }
116
127
  }
@@ -120,61 +131,64 @@ class D {
120
131
  this.pagesCount = t.pagesCount, this.leafAspectRatio = t.leafAspectRatio || this.leafAspectRatio, this.coverAspectRatio = t.coverAspectRatio || this.coverAspectRatio, this.direction = t.direction || this.direction, this.fastDeltaThreshold = t.fastDeltaThreshold ?? this.fastDeltaThreshold, this.initialTurnedLeaves = new Set(t.initialTurnedLeaves ?? []), this.pageSemantics = t.pageSemantics, this.onPageChanged = t.onPageChanged, this.leavesBuffer = t.leavesBuffer;
121
132
  }
122
133
  render(t, e = !1) {
123
- const s = document.querySelector(t);
124
- if (!s)
134
+ const i = document.querySelector(t);
135
+ if (!i)
125
136
  throw new Error(`Couldn't find container with selector: ${t}`);
126
- this.bookElement = s, this.bookElement.classList.contains("flipbook") || this.bookElement.classList.add("flipbook");
127
- const i = s.querySelectorAll(".page");
128
- if (!i.length)
137
+ this.bookElement = i, this.bookElement.classList.contains("flipbook") || this.bookElement.classList.add("flipbook");
138
+ const s = i.querySelectorAll(".page");
139
+ if (!s.length)
129
140
  throw new Error("No pages found in flipbook");
130
- this.pageElements = Array.from(i), this.leaves.splice(0, this.leaves.length);
131
- const a = Math.ceil(this.pagesCount / 2), r = new T(this.bookElement.clientWidth / 2, this.bookElement.clientHeight).aspectRatioFit(this.coverAspectRatio), c = new T(
132
- r.width * this.leafAspectRatio.width / this.coverAspectRatio.width,
133
- r.height * this.leafAspectRatio.height / this.coverAspectRatio.height
141
+ this.pageElements = Array.from(s), this.leaves.splice(0, this.leaves.length);
142
+ const c = Math.ceil(this.pagesCount / 2), n = new P(this.bookElement.clientWidth / 2, this.bookElement.clientHeight).aspectRatioFit(this.coverAspectRatio), h = new P(
143
+ n.width * this.leafAspectRatio.width / this.coverAspectRatio.width,
144
+ n.height * this.leafAspectRatio.height / this.coverAspectRatio.height
134
145
  );
135
- this.bookElement.style.perspective = `${Math.min(c.width * 2, c.height) * 2}px`, this.pageElements.forEach((o, n) => {
136
- o.style.width = `${c.width}px`, o.style.height = `${c.height}px`, o.style.zIndex = `${this.pagesCount - n}`, o.dataset.pageIndex = n.toString(), o.style[this.isLTR ? "left" : "right"] = `${(s.clientWidth - 2 * c.width) / 2}px`, o.style.top = `${(s.clientHeight - c.height) / 2}px`, o.dataset.pageSemanticName = this.pageSemantics?.indexToSemanticName(n) ?? "", o.dataset.pageTitle = this.pageSemantics?.indexToTitle(n) ?? "";
137
- const f = Math.floor(n / 2), b = (n + 1) % 2 === 1, u = this.initialTurnedLeaves.has(f), p = this.initialTurnedLeaves.size > 0 ? Math.max(...this.initialTurnedLeaves) + 1 : 0, w = f === p || f === p - 1 && u;
146
+ this.bookElement.style.perspective = `${Math.min(h.width * 2, h.height) * 2}px`, this.pageElements.forEach((o, a) => {
147
+ o.style.width = `${h.width}px`, o.style.height = `${h.height}px`, o.style.zIndex = `${this.pagesCount - a}`, o.dataset.pageIndex = a.toString(), o.style[this.isLTR ? "left" : "right"] = `${(i.clientWidth - 2 * h.width) / 2}px`, o.style.top = `${(i.clientHeight - h.height) / 2}px`, o.dataset.pageSemanticName = this.pageSemantics?.indexToSemanticName(a) ?? "", o.dataset.pageTitle = this.pageSemantics?.indexToTitle(a) ?? "";
148
+ const u = Math.floor(a / 2), T = (a + 1) % 2 === 1, p = this.initialTurnedLeaves.has(u), m = this.initialTurnedLeaves.size > 0 ? Math.max(...this.initialTurnedLeaves) + 1 : 0, w = u === m || u === m - 1 && p;
138
149
  if (o.classList.add(
139
- b ? "odd" : "even",
150
+ T ? "odd" : "even",
140
151
  ...w ? ["current-page"] : []
141
- ), b) {
142
- if (u) {
143
- const g = `translateX(${this.isLTR ? "100%" : "-100%"})rotateY(${this.isLTR ? "180deg" : "-180deg"})scaleX(-1)`;
144
- o.style.transform = g, o.style.transformOrigin = this.isLTR ? "left" : "right", o.style.zIndex = `${n}`;
152
+ ), T) {
153
+ if (p) {
154
+ const v = `translateX(${this.isLTR ? "100%" : "-100%"})rotateY(${this.isLTR ? "180deg" : "-180deg"})scaleX(-1)`;
155
+ o.style.transform = v, o.style.transformOrigin = this.isLTR ? "left" : "right", o.style.zIndex = `${a}`;
145
156
  } else
146
- o.style.transform = `translateX(${this.isLTR ? "" : "-"}100%)`, o.style.zIndex = `${this.pagesCount - n}`;
147
- this.leaves[f] = new A(
148
- f,
149
- [o, void 0],
157
+ o.style.transform = `translateX(${this.isLTR ? "" : "-"}100%)`, o.style.zIndex = `${this.pagesCount - a}`;
158
+ this.leaves[u] = new D(
150
159
  u,
160
+ [o, void 0],
161
+ p,
151
162
  {
152
163
  isLTR: this.isLTR,
153
- leavesCount: a,
164
+ leavesCount: c,
154
165
  pagesCount: this.pagesCount
155
166
  },
156
- (P) => {
157
- const g = P === h.Forward ? n + 2 === this.pagesCount ? [n + 1] : [n + 1, n + 2] : n === 0 ? [n] : [n - 1, n];
158
- if (this.prevVisiblePageIndices && this.prevVisiblePageIndices.length === g.length && g.every((x, y) => x === this.prevVisiblePageIndices?.[y]))
167
+ (F) => {
168
+ const v = F === l.Forward ? a + 2 === this.pagesCount ? [a + 1] : [a + 1, a + 2] : a === 0 ? [a] : [a - 1, a];
169
+ if (this.prevVisiblePageIndices && this.prevVisiblePageIndices.length === v.length && v.every((y, x) => y === this.prevVisiblePageIndices?.[x]))
159
170
  return;
160
- const L = this.prevVisiblePageIndices;
161
- this.prevVisiblePageIndices = g, this.onTurned(g, L);
171
+ const S = this.prevVisiblePageIndices;
172
+ this.prevVisiblePageIndices = v, this.onTurned(v, S);
162
173
  }
163
174
  );
164
175
  } else
165
- u ? (o.style.transform = `translateX(0px)rotateY(${this.isLTR ? "180deg" : "-180deg"})scaleX(1)`, o.style.transformOrigin = this.isLTR ? "right" : "left", o.style.zIndex = `${n}`) : (o.style.transform = `scaleX(-1)translateX(${this.isLTR ? "-" : ""}100%)`, o.style.zIndex = `${this.pagesCount - n}`), this.leaves[f].pages[1] = o;
176
+ p ? (o.style.transform = `translateX(0px)rotateY(${this.isLTR ? "180deg" : "-180deg"})scaleX(1)`, o.style.transformOrigin = this.isLTR ? "right" : "left", o.style.zIndex = `${a}`) : (o.style.transform = `scaleX(-1)translateX(${this.isLTR ? "-" : ""}100%)`, o.style.zIndex = `${this.pagesCount - a}`), this.leaves[u].pages[1] = o;
166
177
  });
167
178
  const d = (this.initialTurnedLeaves.size > 0 ? Math.max(...this.initialTurnedLeaves) + 1 : 0) * 2;
168
179
  if (d >= this.pagesCount) {
169
- const n = (Math.ceil(this.pagesCount / 2) - 1) * 2;
170
- this.prevVisiblePageIndices = n + 1 < this.pagesCount ? [n, n + 1] : [n];
180
+ const a = (Math.ceil(this.pagesCount / 2) - 1) * 2;
181
+ this.prevVisiblePageIndices = a + 1 < this.pagesCount ? [a, a + 1] : [a];
171
182
  } else
172
183
  this.prevVisiblePageIndices = d + 1 < this.pagesCount ? [d, d + 1] : [d];
173
- this.hammer = new $(this.bookElement), this.hammer.on("panstart", this.onDragStart.bind(this)), this.hammer.on("panmove", this.onDragUpdate.bind(this)), this.hammer.on("panend", this.onDragEnd.bind(this)), this.bookElement.addEventListener("touchstart", this.handleTouchStart.bind(this), {
184
+ this.hammer = new M(this.bookElement), this.hammer.on("panstart", this.onDragStart.bind(this)), this.hammer.on("panmove", this.onDragUpdate.bind(this)), this.hammer.on("panend", this.onDragEnd.bind(this)), this.bookElement.addEventListener("touchstart", this.handleTouchStart.bind(this), {
174
185
  passive: !1
175
186
  }), this.bookElement.addEventListener("touchmove", this.handleTouchMove.bind(this), {
176
187
  passive: !1
177
- }), this.updateLeavesBufferVisibility(), e && this.fillDebugBar();
188
+ }), this.bookElement.addEventListener(
189
+ "mousemove",
190
+ this.handleMouseMove
191
+ ), this.bookElement.addEventListener("mouseleave", this.handleMouseLeave), this.updateLeavesBufferVisibility(), e && this.fillDebugBar();
178
192
  }
179
193
  /**
180
194
  * Update visibility of leaves based on the buffer setting.
@@ -185,17 +199,17 @@ class D {
185
199
  return;
186
200
  const t = this.leaves.length;
187
201
  if (t === 0) return;
188
- const [e, s] = this.currentOrTurningLeaves, i = s?.index ?? e?.index ?? 0, a = Math.max(0, i - this.leavesBuffer), l = Math.min(t - 1, i + this.leavesBuffer);
189
- for (let r = 0; r < t; r++) {
190
- const c = this.leaves[r], m = r >= a && r <= l;
191
- for (const d of c.pages)
192
- d && (d.style.display = m ? "" : "none");
202
+ const [e, i] = this.currentOrTurningLeaves, s = i?.index ?? e?.index ?? 0, c = Math.max(0, s - this.leavesBuffer), r = Math.min(t - 1, s + this.leavesBuffer);
203
+ for (let n = 0; n < t; n++) {
204
+ const h = this.leaves[n], f = n >= c && n <= r;
205
+ for (const d of h.pages)
206
+ d && (d.style.display = f ? "" : "none");
193
207
  }
194
208
  }
195
209
  fillDebugBar() {
196
210
  const t = document.createElement("div");
197
211
  t.className = "flipbook-debug-bar", this.bookElement?.appendChild(t), setInterval(() => {
198
- const e = Array.from(this.activeFlips.entries()).map(([s, i]) => `${s}:${i.leaf.flipPosition.toFixed(2)}`).join(", ");
212
+ const e = Array.from(this.activeFlips.entries()).map(([i, s]) => `${i}:${s.leaf.flipPosition.toFixed(2)}`).join(", ");
199
213
  t.innerHTML = `
200
214
  <div>Direction: ${this.isLTR ? "LTR" : "RTL"}</div>
201
215
  <div>Active Flips: ${this.activeFlips.size} [${e}]</div>
@@ -217,65 +231,65 @@ class D {
217
231
  * Excludes leaves that are already being flipped.
218
232
  */
219
233
  getNextAvailableLeaf(t) {
220
- if (t === h.Forward) {
234
+ if (t === l.Forward) {
221
235
  const [, e] = this.currentOrTurningLeaves;
222
236
  if (!e) return;
223
- for (let s = e.index; s < this.leaves.length; s++) {
224
- const i = this.leaves[s];
225
- if (!this.activeFlips.has(i.index) && !i.isTurned)
226
- return i;
237
+ for (let i = e.index; i < this.leaves.length; i++) {
238
+ const s = this.leaves[i];
239
+ if (!this.activeFlips.has(s.index) && !s.isTurned)
240
+ return s;
227
241
  }
228
242
  return;
229
- } else if (t === h.Backward) {
243
+ } else if (t === l.Backward) {
230
244
  const [e] = this.currentOrTurningLeaves;
231
245
  if (!e) return;
232
- for (let s = e.index; s >= 0; s--) {
233
- const i = this.leaves[s];
234
- if (!this.activeFlips.has(i.index) && (i.isTurned || i.isTurning))
235
- return i;
246
+ for (let i = e.index; i >= 0; i--) {
247
+ const s = this.leaves[i];
248
+ if (!this.activeFlips.has(s.index) && (s.isTurned || s.isTurning))
249
+ return s;
236
250
  }
237
251
  return;
238
252
  }
239
253
  }
240
254
  onDragStart(t) {
241
255
  if (this.currentManualFlip) {
242
- this.pendingFlipDirection = h.None, this.pendingFlipStartingPos = 0;
256
+ this.pendingFlipDirection = l.None, this.pendingFlipStartingPos = 0;
243
257
  return;
244
258
  }
245
- this.pendingFlipStartingPos = t.center.x, this.pendingFlipDirection = h.None;
259
+ this.isDragging = !0, this.clearHoverShadow(), this.pendingFlipStartingPos = t.center.x, this.pendingFlipDirection = l.None;
246
260
  }
247
261
  onDragUpdate(t) {
248
262
  let e = this.currentManualFlip;
249
- const s = t.center.x, i = this.bookElement?.clientWidth ?? 0, a = this.isLTR ? this.pendingFlipStartingPos - s : s - this.pendingFlipStartingPos;
250
- if (Math.abs(a) > i || a === 0) return;
251
- const l = this.pendingFlipDirection !== h.None ? this.pendingFlipDirection : a > 0 ? h.Forward : h.Backward;
252
- if (this.pendingFlipDirection === h.None && (this.pendingFlipDirection = l), !e) {
253
- for (const r of this.activeFlips.values())
254
- if (r.isDuringAutoFlip && r.direction !== l)
263
+ const i = t.center.x, s = this.bookElement?.clientWidth ?? 0, c = this.isLTR ? this.pendingFlipStartingPos - i : i - this.pendingFlipStartingPos;
264
+ if (Math.abs(c) > s || c === 0) return;
265
+ const r = this.pendingFlipDirection !== l.None ? this.pendingFlipDirection : c > 0 ? l.Forward : l.Backward;
266
+ if (this.pendingFlipDirection === l.None && (this.pendingFlipDirection = r), !e) {
267
+ for (const n of this.activeFlips.values())
268
+ if (n.isDuringAutoFlip && n.direction !== r)
255
269
  return;
256
270
  }
257
271
  if (!e) {
258
- const r = this.getNextAvailableLeaf(l);
259
- if (!r) return;
272
+ const n = this.getNextAvailableLeaf(r);
273
+ if (!n) return;
260
274
  e = {
261
- leaf: r,
262
- direction: l,
275
+ leaf: n,
276
+ direction: r,
263
277
  startingPos: this.pendingFlipStartingPos,
264
278
  delta: 0,
265
279
  isDuringAutoFlip: !1
266
- }, this.activeFlips.set(r.index, e);
280
+ }, this.activeFlips.set(n.index, e);
267
281
  }
268
- switch (e.delta = a, e.direction) {
269
- case h.Forward: {
270
- const r = a / i;
271
- if (r > 1 || a < 0) return;
272
- e.leaf.efficientFlipToPosition(r);
282
+ switch (e.delta = c, e.direction) {
283
+ case l.Forward: {
284
+ const n = c / s;
285
+ if (n > 1 || c < 0) return;
286
+ e.leaf.efficientFlipToPosition(n);
273
287
  break;
274
288
  }
275
- case h.Backward: {
276
- const r = 1 - Math.abs(a) / i;
277
- if (r < 0 || a > 0) return;
278
- e.leaf.efficientFlipToPosition(r);
289
+ case l.Backward: {
290
+ const n = 1 - Math.abs(c) / s;
291
+ if (n < 0 || c > 0) return;
292
+ e.leaf.efficientFlipToPosition(n);
279
293
  break;
280
294
  }
281
295
  }
@@ -283,22 +297,22 @@ class D {
283
297
  onDragEnd(t) {
284
298
  const e = this.currentManualFlip;
285
299
  if (!e) {
286
- this.pendingFlipDirection = h.None, this.pendingFlipStartingPos = 0;
300
+ this.pendingFlipDirection = l.None, this.pendingFlipStartingPos = 0, this.isDragging = !1, this.clearHoverShadow();
287
301
  return;
288
302
  }
289
- const s = t.velocityX * 1e3;
290
- let i;
303
+ const i = t.velocityX * 1e3;
304
+ let s;
291
305
  switch (e.direction) {
292
- case h.Forward:
293
- (this.isLTR ? s < -this.fastDeltaThreshold : s > this.fastDeltaThreshold) || e.leaf.flipPosition >= 0.5 ? i = 1 : i = 0;
306
+ case l.Forward:
307
+ (this.isLTR ? i < -this.fastDeltaThreshold : i > this.fastDeltaThreshold) || e.leaf.flipPosition >= 0.5 ? s = 1 : s = 0;
294
308
  break;
295
- case h.Backward:
296
- (this.isLTR ? s > this.fastDeltaThreshold : s < -this.fastDeltaThreshold) || e.leaf.flipPosition <= 0.5 ? i = 0 : i = 1;
309
+ case l.Backward:
310
+ (this.isLTR ? i > this.fastDeltaThreshold : i < -this.fastDeltaThreshold) || e.leaf.flipPosition <= 0.5 ? s = 0 : s = 1;
297
311
  break;
298
312
  default:
299
313
  return;
300
314
  }
301
- e.isDuringAutoFlip = !0, this.pendingFlipDirection = h.None, this.pendingFlipStartingPos = 0, e.leaf.flipToPosition(i).then(() => {
315
+ e.isDuringAutoFlip = !0, this.pendingFlipDirection = l.None, this.pendingFlipStartingPos = 0, this.isDragging = !1, e.leaf.flipToPosition(s).then(() => {
302
316
  this.activeFlips.delete(e.leaf.index);
303
317
  });
304
318
  }
@@ -311,13 +325,40 @@ class D {
311
325
  handleTouchMove = (t) => {
312
326
  if (t.touches.length > 1)
313
327
  return;
314
- const e = t.touches[0], s = e.pageX - this.touchStartingPos.x, i = e.pageY - this.touchStartingPos.y;
315
- Math.abs(s) > Math.abs(i) && t.preventDefault();
328
+ const e = t.touches[0], i = e.pageX - this.touchStartingPos.x, s = e.pageY - this.touchStartingPos.y;
329
+ Math.abs(i) > Math.abs(s) && t.preventDefault();
330
+ };
331
+ handleMouseMove = b(I, (t) => {
332
+ if (!this.bookElement) return;
333
+ if (this.isDragging || this.currentManualFlip || this.activeFlips.size > 0) {
334
+ this.clearHoverShadow();
335
+ return;
336
+ }
337
+ const e = this.bookElement.getBoundingClientRect();
338
+ if (e.width <= 0) return;
339
+ const i = t.clientX - e.left, s = e.width * C, c = i <= s, r = i >= e.width - s;
340
+ if (!c && !r) {
341
+ this.clearHoverShadow();
342
+ return;
343
+ }
344
+ const n = this.isLTR ? r : c, h = n ? l.Forward : l.Backward, f = this.getNextAvailableLeaf(h);
345
+ if (!f) {
346
+ this.clearHoverShadow();
347
+ return;
348
+ }
349
+ const d = n ? this.isLTR ? e.width - i : i : this.isLTR ? i : e.width - i, a = (1 - Math.min(1, d / s)) * $;
350
+ this.hoveredLeaf && this.hoveredLeaf !== f && this.hoveredLeaf.setHoverShadow(0), this.hoveredLeaf = f, f.setHoverShadow(a);
351
+ });
352
+ handleMouseLeave = () => {
353
+ this.clearHoverShadow();
316
354
  };
355
+ clearHoverShadow() {
356
+ this.hoveredLeaf && (this.hoveredLeaf.setHoverShadow(0), this.hoveredLeaf = void 0);
357
+ }
317
358
  onTurned(t, e) {
318
- for (let s = 0; s < this.pageElements.length; s++) {
319
- const i = this.pageElements[s], a = t.includes(s), l = e?.includes(s);
320
- (a ? i.classList.add : !e || !l ? () => null : i.classList.remove).bind(i.classList)("current-page");
359
+ for (let i = 0; i < this.pageElements.length; i++) {
360
+ const s = this.pageElements[i], c = t.includes(i), r = e?.includes(i);
361
+ (c ? s.classList.add : !e || !r ? () => null : s.classList.remove).bind(s.classList)("current-page");
321
362
  }
322
363
  this.updateLeavesBufferVisibility();
323
364
  }
@@ -347,16 +388,27 @@ class D {
347
388
  const t = this.pagesCount - 1;
348
389
  return this.prevVisiblePageIndices?.includes(t) ?? !1;
349
390
  }
391
+ /**
392
+ * Check if there's an active auto-flip in the given direction.
393
+ */
394
+ hasActiveAutoFlipInDirection(t) {
395
+ for (const e of this.activeFlips.values())
396
+ if (e.isDuringAutoFlip && e.direction === t)
397
+ return !0;
398
+ return !1;
399
+ }
350
400
  /**
351
401
  * Animate flip to the next page.
352
402
  * @returns Promise that resolves when the flip animation completes
353
403
  */
354
404
  async flipNext() {
355
- const t = this.getNextAvailableLeaf(h.Forward);
405
+ if (this.hasActiveAutoFlipInDirection(l.Backward))
406
+ return;
407
+ const t = this.getNextAvailableLeaf(l.Forward);
356
408
  if (!t) return;
357
409
  const e = {
358
410
  leaf: t,
359
- direction: h.Forward,
411
+ direction: l.Forward,
360
412
  startingPos: 0,
361
413
  delta: 0,
362
414
  isDuringAutoFlip: !0
@@ -373,11 +425,13 @@ class D {
373
425
  * @returns Promise that resolves when the flip animation completes
374
426
  */
375
427
  async flipPrev() {
376
- const t = this.getNextAvailableLeaf(h.Backward);
428
+ if (this.hasActiveAutoFlipInDirection(l.Forward))
429
+ return;
430
+ const t = this.getNextAvailableLeaf(l.Backward);
377
431
  if (!t) return;
378
432
  const e = {
379
433
  leaf: t,
380
- direction: h.Backward,
434
+ direction: l.Backward,
381
435
  startingPos: 0,
382
436
  delta: 0,
383
437
  isDuringAutoFlip: !0
@@ -402,13 +456,13 @@ class D {
402
456
  );
403
457
  return;
404
458
  }
405
- const e = Math.floor(t / 2), s = Math.floor(this.currentPageIndex / 2);
406
- if (e !== s)
407
- if (e > s)
408
- for (let i = s; i < e; i++)
459
+ const e = Math.floor(t / 2), i = Math.floor(this.currentPageIndex / 2);
460
+ if (e !== i)
461
+ if (e > i)
462
+ for (let s = i; s < e; s++)
409
463
  await this.flipNext();
410
464
  else
411
- for (let i = s; i > e; i--)
465
+ for (let s = i; s > e; s--)
412
466
  await this.flipPrev();
413
467
  }
414
468
  /**
@@ -422,16 +476,20 @@ class D {
422
476
  );
423
477
  return;
424
478
  }
425
- const e = Math.floor(t / 2);
426
- for (let i = 0; i < this.leaves.length; i++) {
427
- const a = this.leaves[i], l = i < e;
428
- l && !a.isTurned ? (a.flipPosition = 1, this.applyLeafTransform(a, 1)) : !l && a.isTurned && (a.flipPosition = 0, this.applyLeafTransform(a, 0));
479
+ const e = Math.floor(t / 2), i = t === this.pagesCount - 1, s = t % 2 === 1, c = i && s;
480
+ for (let r = 0; r < this.leaves.length; r++) {
481
+ const n = this.leaves[r], h = r < e || c && r === e;
482
+ h && !n.isTurned ? (n.flipPosition = 1, this.applyLeafTransform(n, 1)) : !h && n.isTurned && (n.flipPosition = 0, this.applyLeafTransform(n, 0));
429
483
  }
430
- const s = e * 2;
431
- this.prevVisiblePageIndices = s + 1 < this.pagesCount ? [s, s + 1] : [s];
432
- for (let i = 0; i < this.pageElements.length; i++) {
433
- const a = this.pageElements[i];
434
- this.prevVisiblePageIndices.includes(i) ? a.classList.add("current-page") : a.classList.remove("current-page");
484
+ if (c)
485
+ this.prevVisiblePageIndices = [t];
486
+ else {
487
+ const r = e * 2;
488
+ this.prevVisiblePageIndices = r + 1 < this.pagesCount ? [r, r + 1] : [r];
489
+ }
490
+ for (let r = 0; r < this.pageElements.length; r++) {
491
+ const n = this.pageElements[r];
492
+ this.prevVisiblePageIndices.includes(r) ? n.classList.add("current-page") : n.classList.remove("current-page");
435
493
  }
436
494
  this.updateLeavesBufferVisibility(), this.onPageChanged && this.onPageChanged(this.currentPageIndex);
437
495
  }
@@ -440,23 +498,20 @@ class D {
440
498
  * Used for instant positioning (jumpToPage).
441
499
  */
442
500
  applyLeafTransform(t, e) {
443
- const s = this.isLTR;
444
- for (let i = 0; i < t.pages.length; i++) {
445
- const a = t.pages[i];
446
- if (!a) continue;
447
- const l = i % 2 + 1 === 1, c = `${l ? s ? e > 0.5 ? 180 - e * 180 : -e * 180 : e > 0.5 ? -(180 - e * 180) : e * 180 : s ? e < 0.5 ? -e * 180 : 180 - e * 180 : e < 0.5 ? e * 180 : -(180 - e * 180)}deg`, m = `${l ? s ? "100%" : "-100%" : "0px"}`, d = l ? e > 0.5 ? -1 : 1 : e < 0.5 ? -1 : 1;
448
- a.style.transform = `translateX(${m})rotateY(${c})scaleX(${d})`, a.style.transformOrigin = l ? `${s ? "left" : "right"}` : `${s ? "right" : "left"}`, a.style.zIndex = `${e > 0.5 ? a.dataset.pageIndex : this.pagesCount - a.dataset.pageIndex}`;
449
- }
501
+ t.applyTransform(e);
450
502
  }
451
503
  /**
452
504
  * Clean up event listeners and Hammer instance.
453
505
  * Should be called when the FlipBook is no longer needed.
454
506
  */
455
507
  destroy() {
456
- this.hammer && (this.hammer.destroy(), this.hammer = void 0), this.bookElement && (this.bookElement.removeEventListener("touchstart", this.handleTouchStart), this.bookElement.removeEventListener("touchmove", this.handleTouchMove));
508
+ this.hammer && (this.hammer.destroy(), this.hammer = void 0), this.bookElement && (this.bookElement.removeEventListener("touchstart", this.handleTouchStart), this.bookElement.removeEventListener("touchmove", this.handleTouchMove), this.bookElement.removeEventListener(
509
+ "mousemove",
510
+ this.handleMouseMove
511
+ ), this.bookElement.removeEventListener("mouseleave", this.handleMouseLeave));
457
512
  }
458
513
  }
459
514
  export {
460
- D as FlipBook
515
+ H as FlipBook
461
516
  };
462
517
  //# sourceMappingURL=flipbook.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"flipbook.js","sources":["../src/flip-direction.ts","../src/leaf.ts","../src/aspect-ratio.ts","../src/size.ts","../src/flipbook.ts"],"sourcesContent":["export enum FlipDirection {\n\tForward = \"Forward\",\n\tBackward = \"Backward\",\n\tNone = \"None\",\n}\n","import { throttle } from \"throttle-debounce\";\nimport type { IntRange } from \"type-fest\";\nimport { FlipDirection } from \"./flip-direction\";\n\n// number between 1 to infinity\nexport type DegreesPerSecond = IntRange<1, typeof Infinity>;\nexport type FlipPosition = IntRange<0, 2>;\nexport const FLIPPED = true;\nexport const NOT_FLIPPED = false;\nexport class Leaf {\n\tprivate currentAnimation: Promise<void> | null = null;\n\tprivate targetFlipPosition: FlipPosition | null = null;\n\tprivate wrappedFlipPosition: number;\n\n\tconstructor(\n\t\treadonly index: number,\n\t\treadonly pages: [HTMLElement, HTMLElement | undefined],\n\t\tisFlipped: boolean,\n\t\tprivate readonly bookProperties: {\n\t\t\tisLTR: boolean;\n\t\t\tpagesCount: number;\n\t\t\tleavesCount: number;\n\t\t},\n\t\tprivate readonly onTurned: (direction: FlipDirection) => void,\n\t) {\n\t\tthis.wrappedFlipPosition = isFlipped ? 1 : 0;\n\t\t// TODO: rethink this\n\t\t// if(isFlipped) {\n\t\t// // this.flipToPosition(1);\n\t\t// }\n\t}\n\n\tget isTurned(): boolean {\n\t\treturn this.flipPosition === 1;\n\t}\n\tget isTurning(): boolean {\n\t\treturn this.flipPosition !== 0;\n\t}\n\tget isCover(): boolean {\n\t\treturn this.isFirst || this.isLast;\n\t}\n\tget isFirst(): boolean {\n\t\treturn this.index === 0;\n\t}\n\tget isLast(): boolean {\n\t\treturn this.index === this.bookProperties.leavesCount - 1;\n\t}\n\tset flipPosition(value: number) {\n\t\tthis.wrappedFlipPosition = Math.max(0, Math.min(1, value)) as FlipPosition;\n\t}\n\tget flipPosition(): number {\n\t\treturn this.wrappedFlipPosition;\n\t}\n\n\tasync flipToPosition(\n\t\tflipPosition: FlipPosition,\n\t\tvelocity: DegreesPerSecond = 225 as DegreesPerSecond,\n\t) {\n\t\tif (this.currentAnimation) {\n\t\t\tawait this.currentAnimation;\n\t\t}\n\n\t\tif (this.flipPosition === flipPosition) {\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tif (this.targetFlipPosition === flipPosition) {\n\t\t\treturn this.currentAnimation ?? Promise.resolve();\n\t\t}\n\n\t\tthis.targetFlipPosition = flipPosition;\n\n\t\tthis.currentAnimation = new Promise<void>((resolve) => {\n\t\t\tconst currentFlipPosition = this.flipPosition;\n\t\t\tconst distance = Math.abs(flipPosition - currentFlipPosition);\n\t\t\tconst duration = ((distance * 180) / velocity) * 1000; // duration in milliseconds\n\n\t\t\tconst start = performance.now();\n\t\t\tconst step = (timestamp: number) => {\n\t\t\t\tconst elapsed = timestamp - start;\n\n\t\t\t\tif (elapsed < 0) {\n\t\t\t\t\trequestAnimationFrame(step);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst progress = Math.min(elapsed / duration, 1);\n\t\t\t\tconst newPosition = currentFlipPosition + progress * (flipPosition - currentFlipPosition);\n\n\t\t\t\tthis.pages.forEach((page, index) => {\n\t\t\t\t\tconst isLTR = this.bookProperties.isLTR;\n\t\t\t\t\tif (page) {\n\t\t\t\t\t\tconst isOdd = (index % 2) + 1 === 1;\n\t\t\t\t\t\tconst degrees = isOdd\n\t\t\t\t\t\t\t? isLTR\n\t\t\t\t\t\t\t\t? newPosition > 0.5\n\t\t\t\t\t\t\t\t\t? 180 - newPosition * 180\n\t\t\t\t\t\t\t\t\t: -newPosition * 180\n\t\t\t\t\t\t\t\t: newPosition > 0.5\n\t\t\t\t\t\t\t\t\t? -(180 - newPosition * 180)\n\t\t\t\t\t\t\t\t\t: newPosition * 180\n\t\t\t\t\t\t\t: isLTR\n\t\t\t\t\t\t\t\t? newPosition < 0.5\n\t\t\t\t\t\t\t\t\t? -newPosition * 180\n\t\t\t\t\t\t\t\t\t: 180 - newPosition * 180\n\t\t\t\t\t\t\t\t: newPosition < 0.5\n\t\t\t\t\t\t\t\t\t? newPosition * 180\n\t\t\t\t\t\t\t\t\t: -(180 - newPosition * 180);\n\t\t\t\t\t\tconst rotateY = `${degrees}deg`;\n\t\t\t\t\t\tconst translateX = `${isOdd ? (isLTR ? `100%` : `-100%`) : isLTR ? `0px` : `0px`}`;\n\t\t\t\t\t\tconst scaleX = isOdd ? (newPosition > 0.5 ? -1 : 1) : newPosition < 0.5 ? -1 : 1;\n\t\t\t\t\t\tpage.style.transform = `translateX(${translateX})rotateY(${rotateY})scaleX(${scaleX})`;\n\t\t\t\t\t\t// console.log(page.style.transform);\n\t\t\t\t\t\tpage.style.transformOrigin = isOdd\n\t\t\t\t\t\t\t? `${isLTR ? \"left\" : \"right\"}`\n\t\t\t\t\t\t\t: `${isLTR ? \"right\" : \"left\"}`;\n\t\t\t\t\t\tpage.style.zIndex = `${\n\t\t\t\t\t\t\tnewPosition > 0.5\n\t\t\t\t\t\t\t\t? page.dataset.pageIndex\n\t\t\t\t\t\t\t\t: this.bookProperties.pagesCount - (page.dataset.pageIndex as unknown as number)\n\t\t\t\t\t\t}`;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// Ensure the new position is within valid bounds [0, 1]\n\t\t\t\tthis.flipPosition = Math.max(0, Math.min(1, newPosition)) as FlipPosition;\n\t\t\t\tif (this.flipPosition === 1 || this.flipPosition === 0) {\n\t\t\t\t\tthis.onTurned(this.flipPosition === 1 ? FlipDirection.Forward : FlipDirection.Backward);\n\t\t\t\t}\n\t\t\t\t// Detailed log for debugging\n\t\t\t\t// console.log(\n\t\t\t\t// `Timestamp: ${timestamp}, Elapsed: ${elapsed}, Progress: ${progress}, Current Position: ${currentFlipPosition}, Requested Position: ${flipPosition}, New Position: ${this.flipPosition}`\n\t\t\t\t// );\n\n\t\t\t\tif (progress < 1) {\n\t\t\t\t\trequestAnimationFrame(step);\n\t\t\t\t} else {\n\t\t\t\t\tthis.currentAnimation = null;\n\t\t\t\t\tthis.targetFlipPosition = null;\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\trequestAnimationFrame(step);\n\t\t});\n\n\t\treturn this.currentAnimation;\n\t}\n\n\tasync efficientFlipToPosition(\n\t\tflipPosition: FlipPosition,\n\t\tvelocity: DegreesPerSecond = 20000 as DegreesPerSecond,\n\t) {\n\t\treturn throttle(1, this.flipToPosition.bind(this))(flipPosition, velocity);\n\t}\n}\n","export interface AspectRatio {\n\twidth: number;\n\theight: number;\n}\nexport class AspectRatioImpl implements AspectRatio {\n\tstatic from(aspectRatio: AspectRatio) {\n\t\treturn new AspectRatioImpl(aspectRatio.width, aspectRatio.height);\n\t}\n\tconstructor(\n\t\tpublic readonly width: number,\n\t\tpublic readonly height: number,\n\t) {}\n\tget value(): number {\n\t\treturn this.width / this.height;\n\t}\n}\n","import { type AspectRatio, AspectRatioImpl } from \"./aspect-ratio\";\n\nexport class Size {\n\taspectRatio: AspectRatioImpl;\n\taspectRatioFit(rhsAspectRatio: AspectRatio) {\n\t\tconst rhsAspectRatioValue = AspectRatioImpl.from(rhsAspectRatio).value;\n\t\treturn this.aspectRatio.value > rhsAspectRatioValue\n\t\t\t? new Size(this.height * rhsAspectRatioValue, this.height)\n\t\t\t: new Size(this.width, this.width / rhsAspectRatioValue);\n\t}\n\tconstructor(\n\t\tpublic readonly width: number,\n\t\tpublic readonly height: number,\n\t) {\n\t\tthis.aspectRatio = new AspectRatioImpl(width, height);\n\t}\n\tget asString(): string {\n\t\treturn `${this.width}x${this.height}`;\n\t}\n}\n","import \"./pages.scss\";\nimport \"./flipbook.scss\";\nimport Hammer from \"hammerjs\";\nimport type { AspectRatio } from \"./aspect-ratio\";\nimport type { FlipBookOptions } from \"./flip-book-options\";\nimport { FlipDirection } from \"./flip-direction\";\nimport { type FlipPosition, Leaf } from \"./leaf\";\nimport type { PageSemantics } from \"./page-semantics\";\nimport { Size } from \"./size\";\n\n/** Default threshold for fast flip detection (in ms) */\nconst DEFAULT_FAST_DELTA = 500;\n\n/** State for a single flip operation - enables concurrent page flipping */\ninterface FlipState {\n\tleaf: Leaf;\n\tdirection: FlipDirection;\n\tstartingPos: number;\n\tdelta: number;\n\tisDuringAutoFlip: boolean;\n}\nclass FlipBook {\n\tbookElement?: HTMLElement;\n\tprivate pageElements: HTMLElement[] = [];\n\tprivate readonly pagesCount: number;\n\tprivate readonly leafAspectRatio: AspectRatio = { width: 2, height: 3 };\n\tprivate readonly coverAspectRatio: AspectRatio = {\n\t\twidth: 2.15,\n\t\theight: 3.15,\n\t};\n\tprivate readonly direction: \"rtl\" | \"ltr\" = \"ltr\";\n\tprivate readonly fastDeltaThreshold: number = DEFAULT_FAST_DELTA;\n\tprivate readonly initialTurnedLeaves: Set<number> = new Set();\n\tprivate readonly onPageChanged?: (pageIndex: number) => void;\n\tprivate readonly pageSemantics: PageSemantics | undefined;\n\tprivate readonly leavesBuffer?: number;\n\tprivate leaves: Leaf[] = [];\n\t// flipping state - supports concurrent page flipping\n\tprivate activeFlips: Map<number, FlipState> = new Map();\n\tprivate pendingFlipStartingPos = 0;\n\tprivate pendingFlipDirection: FlipDirection = FlipDirection.None;\n\ttouchStartingPos = { x: 0, y: 0 };\n\tprivate prevVisiblePageIndices: [number] | [number, number] | undefined;\n\t// Hammer instance for cleanup\n\tprivate hammer: HammerManager | undefined;\n\tprivate get isLTR(): boolean {\n\t\treturn this.direction === \"ltr\";\n\t}\n\n\tprivate get currentOrTurningLeaves(): [Leaf | undefined, Leaf | undefined] {\n\t\tlet secondLeafIndex = -1;\n\t\tfor (let i = this.leaves.length - 1; i >= 0; i--) {\n\t\t\tconst leaf = this.leaves[i];\n\t\t\tif (leaf.isTurned || leaf.isTurning) {\n\t\t\t\tsecondLeafIndex = leaf.index + 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn secondLeafIndex === -1\n\t\t\t? [undefined, this.leaves[0]]\n\t\t\t: secondLeafIndex === this.leaves.length\n\t\t\t\t? [this.leaves[secondLeafIndex - 1], undefined]\n\t\t\t\t: [this.leaves[secondLeafIndex - 1], this.leaves[secondLeafIndex]];\n\t}\n\n\tconstructor(options: FlipBookOptions) {\n\t\tthis.pagesCount = options.pagesCount;\n\t\tthis.leafAspectRatio = options.leafAspectRatio || this.leafAspectRatio;\n\t\tthis.coverAspectRatio = options.coverAspectRatio || this.coverAspectRatio;\n\t\tthis.direction = options.direction || this.direction;\n\t\tthis.fastDeltaThreshold = options.fastDeltaThreshold ?? this.fastDeltaThreshold;\n\t\tthis.initialTurnedLeaves = new Set(options.initialTurnedLeaves ?? []);\n\t\tthis.pageSemantics = options.pageSemantics;\n\t\tthis.onPageChanged = options.onPageChanged;\n\t\tthis.leavesBuffer = options.leavesBuffer;\n\t}\n\n\trender(selector: string, debug = false) {\n\t\tconst bookElement = document.querySelector(selector);\n\t\tif (!bookElement) {\n\t\t\tthrow new Error(`Couldn't find container with selector: ${selector}`);\n\t\t}\n\t\tthis.bookElement = bookElement as HTMLElement;\n\t\tif (!this.bookElement.classList.contains(\"flipbook\")) {\n\t\t\tthis.bookElement.classList.add(\"flipbook\");\n\t\t}\n\n\t\tconst pageElements = bookElement.querySelectorAll(\".page\");\n\t\tif (!pageElements.length) {\n\t\t\tthrow new Error(\"No pages found in flipbook\");\n\t\t}\n\t\tthis.pageElements = Array.from(pageElements) as HTMLElement[];\n\t\tthis.leaves.splice(0, this.leaves.length);\n\t\tconst leavesCount = Math.ceil(this.pagesCount / 2);\n\t\tconst maxCoverSize = new Size(this.bookElement.clientWidth / 2, this.bookElement.clientHeight);\n\t\tconst coverSize = maxCoverSize.aspectRatioFit(this.coverAspectRatio);\n\t\tconst leafSize = new Size(\n\t\t\t(coverSize.width * this.leafAspectRatio.width) / this.coverAspectRatio.width,\n\t\t\t(coverSize.height * this.leafAspectRatio.height) / this.coverAspectRatio.height,\n\t\t);\n\t\tthis.bookElement.style.perspective = `${Math.min(leafSize.width * 2, leafSize.height) * 2}px`;\n\t\tthis.pageElements.forEach((pageElement, pageIndex) => {\n\t\t\tpageElement.style.width = `${leafSize.width}px`;\n\t\t\tpageElement.style.height = `${leafSize.height}px`;\n\n\t\t\tpageElement.style.zIndex = `${this.pagesCount - pageIndex}`;\n\t\t\tpageElement.dataset.pageIndex = pageIndex.toString();\n\t\t\tpageElement.style[this.isLTR ? \"left\" : \"right\"] =\n\t\t\t\t`${(bookElement.clientWidth - 2 * leafSize.width) / 2}px`;\n\t\t\tpageElement.style.top = `${(bookElement.clientHeight - leafSize.height) / 2}px`;\n\t\t\tpageElement.dataset.pageSemanticName =\n\t\t\t\tthis.pageSemantics?.indexToSemanticName(pageIndex) ?? \"\";\n\t\t\tpageElement.dataset.pageTitle = this.pageSemantics?.indexToTitle(pageIndex) ?? \"\";\n\n\t\t\tconst leafIndex = Math.floor(pageIndex / 2);\n\t\t\tconst isOddPage = (pageIndex + 1) % 2 === 1;\n\t\t\tconst isInitiallyTurned = this.initialTurnedLeaves.has(leafIndex);\n\n\t\t\t// Determine current page based on initial turned leaves\n\t\t\t// Current pages are the first two visible pages after all initially turned leaves\n\t\t\tconst firstVisibleLeafIndex =\n\t\t\t\tthis.initialTurnedLeaves.size > 0 ? Math.max(...this.initialTurnedLeaves) + 1 : 0;\n\t\t\tconst isCurrentPage =\n\t\t\t\tleafIndex === firstVisibleLeafIndex ||\n\t\t\t\t(leafIndex === firstVisibleLeafIndex - 1 && isInitiallyTurned);\n\n\t\t\tpageElement.classList.add(\n\t\t\t\tisOddPage ? \"odd\" : \"even\",\n\t\t\t\t...(isCurrentPage ? [\"current-page\"] : []),\n\t\t\t);\n\t\t\tif (isOddPage) {\n\t\t\t\t// Apply correct initial transform based on turned state\n\t\t\t\tif (isInitiallyTurned) {\n\t\t\t\t\t// Fully turned: rotateY(180) or similar based on direction\n\t\t\t\t\tconst scaleX = -1;\n\t\t\t\t\tconst transform = `translateX(${this.isLTR ? \"100%\" : \"-100%\"})rotateY(${this.isLTR ? \"180deg\" : \"-180deg\"})scaleX(${scaleX})`;\n\t\t\t\t\tpageElement.style.transform = transform;\n\t\t\t\t\tpageElement.style.transformOrigin = this.isLTR ? \"left\" : \"right\";\n\t\t\t\t\tpageElement.style.zIndex = `${pageIndex}`; // Turned pages have lower z-index\n\t\t\t\t} else {\n\t\t\t\t\tpageElement.style.transform = `translateX(${this.isLTR ? `` : `-`}100%)`;\n\t\t\t\t\tpageElement.style.zIndex = `${this.pagesCount - pageIndex}`;\n\t\t\t\t}\n\n\t\t\t\tthis.leaves[leafIndex] = new Leaf(\n\t\t\t\t\tleafIndex,\n\t\t\t\t\t[pageElement, undefined],\n\t\t\t\t\tisInitiallyTurned,\n\t\t\t\t\t{\n\t\t\t\t\t\tisLTR: this.isLTR,\n\t\t\t\t\t\tleavesCount: leavesCount,\n\t\t\t\t\t\tpagesCount: this.pagesCount,\n\t\t\t\t\t},\n\t\t\t\t\t(direction: FlipDirection) => {\n\t\t\t\t\t\tconst currentVisiblePageIndices: [number] | [number, number] =\n\t\t\t\t\t\t\tdirection === FlipDirection.Forward\n\t\t\t\t\t\t\t\t? pageIndex + 2 === this.pagesCount\n\t\t\t\t\t\t\t\t\t? [pageIndex + 1]\n\t\t\t\t\t\t\t\t\t: [pageIndex + 1, pageIndex + 2]\n\t\t\t\t\t\t\t\t: pageIndex === 0\n\t\t\t\t\t\t\t\t\t? [pageIndex]\n\t\t\t\t\t\t\t\t\t: [pageIndex - 1, pageIndex];\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.prevVisiblePageIndices &&\n\t\t\t\t\t\t\tthis.prevVisiblePageIndices.length === currentVisiblePageIndices.length &&\n\t\t\t\t\t\t\tcurrentVisiblePageIndices.every((v, i) => v === this.prevVisiblePageIndices?.[i])\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst prevVisiblePageIndices = this.prevVisiblePageIndices;\n\t\t\t\t\t\tthis.prevVisiblePageIndices = currentVisiblePageIndices;\n\n\t\t\t\t\t\t// TODO expose to outside using https://github.com/open-draft/strict-event-emitter, and just be a consumer internally\n\t\t\t\t\t\tthis.onTurned(currentVisiblePageIndices, prevVisiblePageIndices);\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Even page (back side of leaf)\n\t\t\t\tif (isInitiallyTurned) {\n\t\t\t\t\t// Fully turned: apply matching transform for back side\n\t\t\t\t\tconst scaleX = 1;\n\t\t\t\t\tpageElement.style.transform = `translateX(0px)rotateY(${this.isLTR ? \"180deg\" : \"-180deg\"})scaleX(${scaleX})`;\n\t\t\t\t\tpageElement.style.transformOrigin = this.isLTR ? \"right\" : \"left\";\n\t\t\t\t\tpageElement.style.zIndex = `${pageIndex}`; // Turned pages have lower z-index\n\t\t\t\t} else {\n\t\t\t\t\tpageElement.style.transform = `scaleX(-1)translateX(${this.isLTR ? `-` : ``}100%)`;\n\t\t\t\t\tpageElement.style.zIndex = `${this.pagesCount - pageIndex}`;\n\t\t\t\t}\n\t\t\t\tthis.leaves[leafIndex].pages[1] = pageElement;\n\t\t\t}\n\t\t});\n\n\t\t// Set initial visible page indices based on initially turned leaves\n\t\tconst firstVisibleLeafIndex =\n\t\t\tthis.initialTurnedLeaves.size > 0 ? Math.max(...this.initialTurnedLeaves) + 1 : 0;\n\t\tconst firstVisiblePageIndex = firstVisibleLeafIndex * 2;\n\n\t\t// Handle edge case where all leaves are turned (showing last page only)\n\t\tif (firstVisiblePageIndex >= this.pagesCount) {\n\t\t\t// All leaves are turned - show the last page(s)\n\t\t\tconst lastLeafIndex = Math.ceil(this.pagesCount / 2) - 1;\n\t\t\tconst lastLeafFirstPage = lastLeafIndex * 2;\n\t\t\tthis.prevVisiblePageIndices =\n\t\t\t\tlastLeafFirstPage + 1 < this.pagesCount\n\t\t\t\t\t? [lastLeafFirstPage, lastLeafFirstPage + 1]\n\t\t\t\t\t: [lastLeafFirstPage];\n\t\t} else {\n\t\t\tthis.prevVisiblePageIndices =\n\t\t\t\tfirstVisiblePageIndex + 1 < this.pagesCount\n\t\t\t\t\t? [firstVisiblePageIndex, firstVisiblePageIndex + 1]\n\t\t\t\t\t: [firstVisiblePageIndex];\n\t\t}\n\n\t\tthis.hammer = new Hammer(this.bookElement);\n\t\tthis.hammer.on(\"panstart\", this.onDragStart.bind(this));\n\t\tthis.hammer.on(\"panmove\", this.onDragUpdate.bind(this));\n\t\tthis.hammer.on(\"panend\", this.onDragEnd.bind(this));\n\t\tthis.bookElement.addEventListener(\"touchstart\", this.handleTouchStart.bind(this), {\n\t\t\tpassive: false,\n\t\t});\n\t\tthis.bookElement.addEventListener(\"touchmove\", this.handleTouchMove.bind(this), {\n\t\t\tpassive: false,\n\t\t});\n\t\t// Apply initial leaves buffer visibility\n\t\tthis.updateLeavesBufferVisibility();\n\t\tif (debug) this.fillDebugBar();\n\t}\n\n\t/**\n\t * Update visibility of leaves based on the buffer setting.\n\t * Leaves outside the buffer range are hidden for performance.\n\t */\n\tprivate updateLeavesBufferVisibility(): void {\n\t\tif (this.leavesBuffer === undefined) {\n\t\t\treturn; // No buffer - all leaves stay visible\n\t\t}\n\n\t\tconst leavesCount = this.leaves.length;\n\t\tif (leavesCount === 0) return;\n\n\t\t// Find the current leaf index (the first non-turned leaf, or last leaf if all turned)\n\t\tconst [leftLeaf, rightLeaf] = this.currentOrTurningLeaves;\n\t\tconst currentLeafIndex = rightLeaf?.index ?? leftLeaf?.index ?? 0;\n\n\t\t// Calculate buffer range\n\t\tconst bufferStart = Math.max(0, currentLeafIndex - this.leavesBuffer);\n\t\tconst bufferEnd = Math.min(leavesCount - 1, currentLeafIndex + this.leavesBuffer);\n\n\t\t// Update visibility of all leaves\n\t\tfor (let i = 0; i < leavesCount; i++) {\n\t\t\tconst leaf = this.leaves[i];\n\t\t\tconst isWithinBuffer = i >= bufferStart && i <= bufferEnd;\n\n\t\t\t// Update both pages of the leaf\n\t\t\tfor (const page of leaf.pages) {\n\t\t\t\tif (page) {\n\t\t\t\t\tpage.style.display = isWithinBuffer ? \"\" : \"none\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate fillDebugBar() {\n\t\tconst debugBar = document.createElement(\"div\");\n\t\tdebugBar.className = \"flipbook-debug-bar\";\n\t\tthis.bookElement?.appendChild(debugBar);\n\t\tsetInterval(() => {\n\t\t\t// Populate debug bar with relevant information\n\t\t\tconst activeFlipsInfo = Array.from(this.activeFlips.entries())\n\t\t\t\t.map(([idx, state]) => `${idx}:${state.leaf.flipPosition.toFixed(2)}`)\n\t\t\t\t.join(\", \");\n\t\t\tdebugBar.innerHTML = `\n <div>Direction: ${this.isLTR ? \"LTR\" : \"RTL\"}</div>\n <div>Active Flips: ${this.activeFlips.size} [${activeFlipsInfo}]</div>\n <div>Pending Flip dir: ${this.pendingFlipDirection}</div>\n `;\n\t\t}, 10);\n\t}\n\n\t/**\n\t * Get the current manually-controlled flip state (the one being dragged).\n\t * Returns undefined if no manual flip is in progress.\n\t */\n\tprivate get currentManualFlip(): FlipState | undefined {\n\t\tfor (const state of this.activeFlips.values()) {\n\t\t\tif (!state.isDuringAutoFlip) {\n\t\t\t\treturn state;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Find the next available leaf for flipping in the given direction.\n\t * Excludes leaves that are already being flipped.\n\t */\n\tprivate getNextAvailableLeaf(direction: FlipDirection): Leaf | undefined {\n\t\tif (direction === FlipDirection.Forward) {\n\t\t\t// Find the rightmost leaf that's not already flipping\n\t\t\t// Start from the current right leaf and go forward\n\t\t\tconst [, rightLeaf] = this.currentOrTurningLeaves;\n\t\t\tif (!rightLeaf) return undefined;\n\n\t\t\t// Find a leaf that's not in activeFlips\n\t\t\tfor (let i = rightLeaf.index; i < this.leaves.length; i++) {\n\t\t\t\tconst leaf = this.leaves[i];\n\t\t\t\tif (!this.activeFlips.has(leaf.index) && !leaf.isTurned) {\n\t\t\t\t\treturn leaf;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} else if (direction === FlipDirection.Backward) {\n\t\t\t// Find the leftmost leaf that's not already flipping\n\t\t\tconst [leftLeaf] = this.currentOrTurningLeaves;\n\t\t\tif (!leftLeaf) return undefined;\n\n\t\t\t// Find a leaf that's not in activeFlips\n\t\t\tfor (let i = leftLeaf.index; i >= 0; i--) {\n\t\t\t\tconst leaf = this.leaves[i];\n\t\t\t\tif (!this.activeFlips.has(leaf.index) && (leaf.isTurned || leaf.isTurning)) {\n\t\t\t\t\treturn leaf;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate onDragStart(event: HammerInput) {\n\t\t// Allow starting a new flip even if others are in auto-flip mode\n\t\t// Only block if we already have a manual flip in progress\n\t\tif (this.currentManualFlip) {\n\t\t\tthis.pendingFlipDirection = FlipDirection.None;\n\t\t\tthis.pendingFlipStartingPos = 0;\n\t\t\treturn;\n\t\t}\n\t\tthis.pendingFlipStartingPos = event.center.x;\n\t\tthis.pendingFlipDirection = FlipDirection.None;\n\t}\n\n\tprivate onDragUpdate(event: HammerInput) {\n\t\t// Get or create the current manual flip state\n\t\tlet flipState = this.currentManualFlip;\n\n\t\tconst currentPos = event.center.x;\n\t\tconst bookWidth = this.bookElement?.clientWidth ?? 0;\n\n\t\t// Calculate delta\n\t\tconst delta = this.isLTR\n\t\t\t? this.pendingFlipStartingPos - currentPos\n\t\t\t: currentPos - this.pendingFlipStartingPos;\n\n\t\tif (Math.abs(delta) > bookWidth) return;\n\t\tif (delta === 0) return;\n\n\t\t// Determine direction on first meaningful movement\n\t\tconst direction =\n\t\t\tthis.pendingFlipDirection !== FlipDirection.None\n\t\t\t\t? this.pendingFlipDirection\n\t\t\t\t: delta > 0\n\t\t\t\t\t? FlipDirection.Forward\n\t\t\t\t\t: FlipDirection.Backward;\n\n\t\t// Lock in direction for this flip\n\t\tif (this.pendingFlipDirection === FlipDirection.None) {\n\t\t\tthis.pendingFlipDirection = direction;\n\t\t}\n\n\t\t// Block starting a new flip in opposite direction while auto-flip is in progress\n\t\t// This prevents visual glitches when swiping backward while a forward flip is animating\n\t\tif (!flipState) {\n\t\t\tfor (const state of this.activeFlips.values()) {\n\t\t\t\tif (state.isDuringAutoFlip && state.direction !== direction) {\n\t\t\t\t\t// There's an auto-flip in the opposite direction - block this new flip\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we don't have a flip state yet, create one\n\t\tif (!flipState) {\n\t\t\tconst leaf = this.getNextAvailableLeaf(direction);\n\t\t\tif (!leaf) return;\n\n\t\t\tflipState = {\n\t\t\t\tleaf,\n\t\t\t\tdirection,\n\t\t\t\tstartingPos: this.pendingFlipStartingPos,\n\t\t\t\tdelta: 0,\n\t\t\t\tisDuringAutoFlip: false,\n\t\t\t};\n\t\t\tthis.activeFlips.set(leaf.index, flipState);\n\t\t}\n\n\t\t// Update delta\n\t\tflipState.delta = delta;\n\n\t\t// Calculate and apply flip position\n\t\tswitch (flipState.direction) {\n\t\t\tcase FlipDirection.Forward: {\n\t\t\t\tconst posForward = (delta / bookWidth) as FlipPosition;\n\t\t\t\tif (posForward > 1 || delta < 0) return;\n\t\t\t\tflipState.leaf.efficientFlipToPosition(posForward);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase FlipDirection.Backward: {\n\t\t\t\tconst posBackward = (1 - Math.abs(delta) / bookWidth) as FlipPosition;\n\t\t\t\tif (posBackward < 0 || delta > 0) return;\n\t\t\t\tflipState.leaf.efficientFlipToPosition(posBackward);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate onDragEnd(event: HammerInput) {\n\t\tconst flipState = this.currentManualFlip;\n\t\tif (!flipState) {\n\t\t\tthis.pendingFlipDirection = FlipDirection.None;\n\t\t\tthis.pendingFlipStartingPos = 0;\n\t\t\treturn;\n\t\t}\n\n\t\tconst ppsX = event.velocityX * 1000; // pixels per second\n\t\tlet flipTo: FlipPosition;\n\n\t\tswitch (flipState.direction) {\n\t\t\tcase FlipDirection.Forward:\n\t\t\t\tif (\n\t\t\t\t\t(this.isLTR ? ppsX < -this.fastDeltaThreshold : ppsX > this.fastDeltaThreshold) ||\n\t\t\t\t\tflipState.leaf.flipPosition >= 0.5\n\t\t\t\t) {\n\t\t\t\t\tflipTo = 1;\n\t\t\t\t} else {\n\t\t\t\t\tflipTo = 0;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase FlipDirection.Backward:\n\t\t\t\tif (\n\t\t\t\t\t(this.isLTR ? ppsX > this.fastDeltaThreshold : ppsX < -this.fastDeltaThreshold) ||\n\t\t\t\t\tflipState.leaf.flipPosition <= 0.5\n\t\t\t\t) {\n\t\t\t\t\tflipTo = 0;\n\t\t\t\t} else {\n\t\t\t\t\tflipTo = 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\n\t\t// Mark as auto-flip and reset pending state\n\t\tflipState.isDuringAutoFlip = true;\n\t\tthis.pendingFlipDirection = FlipDirection.None;\n\t\tthis.pendingFlipStartingPos = 0;\n\n\t\t// Complete the flip asynchronously - don't block new flips!\n\t\tflipState.leaf.flipToPosition(flipTo).then(() => {\n\t\t\tthis.activeFlips.delete(flipState.leaf.index);\n\t\t});\n\t}\n\n\tprivate handleTouchStart = (e: TouchEvent) => {\n\t\tif (e.touches.length > 1) {\n\t\t\treturn;\n\t\t}\n\t\tconst touch = e.touches[0];\n\t\tthis.touchStartingPos = { x: touch.pageX, y: touch.pageY };\n\t};\n\n\tprivate handleTouchMove = (e: TouchEvent) => {\n\t\tif (e.touches.length > 1) {\n\t\t\treturn;\n\t\t}\n\t\tconst touch = e.touches[0];\n\t\tconst deltaX = touch.pageX - this.touchStartingPos.x;\n\t\tconst deltaY = touch.pageY - this.touchStartingPos.y;\n\t\t// only allow vertical scrolling, as if allowing horizontal scrolling, it will interfere with the flip gesture (for touch devices)\n\t\t// TODO: allow horizontal scrolling if the user is not trying to flip, say if is scrolling an overflowed element\n\t\tif (Math.abs(deltaX) > Math.abs(deltaY)) {\n\t\t\te.preventDefault();\n\t\t}\n\t};\n\tprivate onTurned(\n\t\tcurrentVisiblePageIndices: [number] | [number, number],\n\t\tprevVisibilePageIndices?: [number] | [number, number],\n\t) {\n\t\tfor (let i = 0; i < this.pageElements.length; i++) {\n\t\t\tconst pageElement = this.pageElements[i];\n\t\t\tconst inCurrent = currentVisiblePageIndices.includes(i);\n\t\t\tconst inPrev = prevVisibilePageIndices?.includes(i);\n\t\t\tconst action = inCurrent\n\t\t\t\t? pageElement.classList.add\n\t\t\t\t: !prevVisibilePageIndices || !inPrev\n\t\t\t\t\t? () => null\n\t\t\t\t\t: pageElement.classList.remove;\n\t\t\taction.bind(pageElement.classList)(\"current-page\");\n\t\t}\n\t\t// Update leaves buffer visibility after turn completes\n\t\tthis.updateLeavesBufferVisibility();\n\t\t// TODO expose to outside using https://github.com/open-draft/strict-event-emitter, and just be a consumer internally.\n\t\t// TODO: set prev-page / next-page classes for prev/next pages as accordingally\n\t}\n\t/**\n\t * Get the index of the current (leftmost visible) page.\n\t * Returns 0 if no pages are visible.\n\t */\n\tget currentPageIndex(): number {\n\t\treturn this.prevVisiblePageIndices?.[0] ?? 0;\n\t}\n\n\t/**\n\t * Get the total number of pages in the flipbook.\n\t */\n\tget totalPages(): number {\n\t\treturn this.pagesCount;\n\t}\n\n\t/**\n\t * Check if the book is currently showing the first page(s).\n\t */\n\tget isFirstPage(): boolean {\n\t\treturn this.currentPageIndex === 0;\n\t}\n\n\t/**\n\t * Check if the book is currently showing the last page(s).\n\t */\n\tget isLastPage(): boolean {\n\t\tconst lastPageIndex = this.pagesCount - 1;\n\t\treturn this.prevVisiblePageIndices?.includes(lastPageIndex) ?? false;\n\t}\n\n\t/**\n\t * Animate flip to the next page.\n\t * @returns Promise that resolves when the flip animation completes\n\t */\n\tasync flipNext(): Promise<void> {\n\t\tconst leaf = this.getNextAvailableLeaf(FlipDirection.Forward);\n\t\tif (!leaf) return;\n\n\t\tconst flipState: FlipState = {\n\t\t\tleaf,\n\t\t\tdirection: FlipDirection.Forward,\n\t\t\tstartingPos: 0,\n\t\t\tdelta: 0,\n\t\t\tisDuringAutoFlip: true,\n\t\t};\n\t\tthis.activeFlips.set(leaf.index, flipState);\n\n\t\ttry {\n\t\t\tawait leaf.flipToPosition(1);\n\t\t} finally {\n\t\t\tthis.activeFlips.delete(leaf.index);\n\t\t}\n\t}\n\n\t/**\n\t * Animate flip to the previous page.\n\t * @returns Promise that resolves when the flip animation completes\n\t */\n\tasync flipPrev(): Promise<void> {\n\t\tconst leaf = this.getNextAvailableLeaf(FlipDirection.Backward);\n\t\tif (!leaf) return;\n\n\t\tconst flipState: FlipState = {\n\t\t\tleaf,\n\t\t\tdirection: FlipDirection.Backward,\n\t\t\tstartingPos: 0,\n\t\t\tdelta: 0,\n\t\t\tisDuringAutoFlip: true,\n\t\t};\n\t\tthis.activeFlips.set(leaf.index, flipState);\n\n\t\ttry {\n\t\t\tawait leaf.flipToPosition(0);\n\t\t} finally {\n\t\t\tthis.activeFlips.delete(leaf.index);\n\t\t}\n\t}\n\n\t/**\n\t * Animate to a specific page index.\n\t * Flips through pages sequentially to reach the target.\n\t * @param pageIndex - The target page index (0-based)\n\t * @returns Promise that resolves when all flip animations complete\n\t */\n\tasync goToPage(pageIndex: number): Promise<void> {\n\t\tif (pageIndex < 0 || pageIndex >= this.pagesCount) {\n\t\t\tconsole.warn(\n\t\t\t\t`goToPage: Invalid page index ${pageIndex}. Must be between 0 and ${this.pagesCount - 1}.`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst targetLeafIndex = Math.floor(pageIndex / 2);\n\t\tconst currentLeafIndex = Math.floor(this.currentPageIndex / 2);\n\n\t\tif (targetLeafIndex === currentLeafIndex) {\n\t\t\treturn; // Already at the target page\n\t\t}\n\n\t\tif (targetLeafIndex > currentLeafIndex) {\n\t\t\t// Flip forward\n\t\t\tfor (let i = currentLeafIndex; i < targetLeafIndex; i++) {\n\t\t\t\tawait this.flipNext();\n\t\t\t}\n\t\t} else {\n\t\t\t// Flip backward\n\t\t\tfor (let i = currentLeafIndex; i > targetLeafIndex; i--) {\n\t\t\t\tawait this.flipPrev();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Jump to a specific page instantly without animation.\n\t * @param pageIndex - The target page index (0-based)\n\t */\n\tjumpToPage(pageIndex: number): void {\n\t\tif (pageIndex < 0 || pageIndex >= this.pagesCount) {\n\t\t\tconsole.warn(\n\t\t\t\t`jumpToPage: Invalid page index ${pageIndex}. Must be between 0 and ${this.pagesCount - 1}.`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst targetLeafIndex = Math.floor(pageIndex / 2);\n\n\t\t// Set all leaves before target as turned, all after as not turned\n\t\tfor (let i = 0; i < this.leaves.length; i++) {\n\t\t\tconst leaf = this.leaves[i];\n\t\t\tconst shouldBeTurned = i < targetLeafIndex;\n\n\t\t\tif (shouldBeTurned && !leaf.isTurned) {\n\t\t\t\t// Turn this leaf instantly\n\t\t\t\tleaf.flipPosition = 1;\n\t\t\t\tthis.applyLeafTransform(leaf, 1);\n\t\t\t} else if (!shouldBeTurned && leaf.isTurned) {\n\t\t\t\t// Unturn this leaf instantly\n\t\t\t\tleaf.flipPosition = 0;\n\t\t\t\tthis.applyLeafTransform(leaf, 0);\n\t\t\t}\n\t\t}\n\n\t\t// Update visible page indices\n\t\tconst firstVisiblePageIndex = targetLeafIndex * 2;\n\t\tthis.prevVisiblePageIndices =\n\t\t\tfirstVisiblePageIndex + 1 < this.pagesCount\n\t\t\t\t? [firstVisiblePageIndex, firstVisiblePageIndex + 1]\n\t\t\t\t: [firstVisiblePageIndex];\n\n\t\t// Update current-page classes\n\t\tfor (let i = 0; i < this.pageElements.length; i++) {\n\t\t\tconst pageElement = this.pageElements[i];\n\t\t\tif (this.prevVisiblePageIndices.includes(i)) {\n\t\t\t\tpageElement.classList.add(\"current-page\");\n\t\t\t} else {\n\t\t\t\tpageElement.classList.remove(\"current-page\");\n\t\t\t}\n\t\t}\n\n\t\t// Update leaves buffer visibility\n\t\tthis.updateLeavesBufferVisibility();\n\n\t\t// Notify callback\n\t\tif (this.onPageChanged) {\n\t\t\tthis.onPageChanged(this.currentPageIndex);\n\t\t}\n\t}\n\n\t/**\n\t * Apply transform styles to a leaf's pages for a given flip position.\n\t * Used for instant positioning (jumpToPage).\n\t */\n\tprivate applyLeafTransform(leaf: Leaf, position: number): void {\n\t\tconst isLTR = this.isLTR;\n\n\t\tfor (let index = 0; index < leaf.pages.length; index++) {\n\t\t\tconst page = leaf.pages[index];\n\t\t\tif (!page) continue;\n\n\t\t\tconst isOdd = (index % 2) + 1 === 1;\n\t\t\tconst degrees = isOdd\n\t\t\t\t? isLTR\n\t\t\t\t\t? position > 0.5\n\t\t\t\t\t\t? 180 - position * 180\n\t\t\t\t\t\t: -position * 180\n\t\t\t\t\t: position > 0.5\n\t\t\t\t\t\t? -(180 - position * 180)\n\t\t\t\t\t\t: position * 180\n\t\t\t\t: isLTR\n\t\t\t\t\t? position < 0.5\n\t\t\t\t\t\t? -position * 180\n\t\t\t\t\t\t: 180 - position * 180\n\t\t\t\t\t: position < 0.5\n\t\t\t\t\t\t? position * 180\n\t\t\t\t\t\t: -(180 - position * 180);\n\n\t\t\tconst rotateY = `${degrees}deg`;\n\t\t\tconst translateX = `${isOdd ? (isLTR ? \"100%\" : \"-100%\") : isLTR ? \"0px\" : \"0px\"}`;\n\t\t\tconst scaleX = isOdd ? (position > 0.5 ? -1 : 1) : position < 0.5 ? -1 : 1;\n\n\t\t\tpage.style.transform = `translateX(${translateX})rotateY(${rotateY})scaleX(${scaleX})`;\n\t\t\tpage.style.transformOrigin = isOdd\n\t\t\t\t? `${isLTR ? \"left\" : \"right\"}`\n\t\t\t\t: `${isLTR ? \"right\" : \"left\"}`;\n\t\t\tpage.style.zIndex = `${\n\t\t\t\tposition > 0.5\n\t\t\t\t\t? page.dataset.pageIndex\n\t\t\t\t\t: this.pagesCount - (page.dataset.pageIndex as unknown as number)\n\t\t\t}`;\n\t\t}\n\t}\n\n\t/**\n\t * Clean up event listeners and Hammer instance.\n\t * Should be called when the FlipBook is no longer needed.\n\t */\n\tdestroy() {\n\t\tif (this.hammer) {\n\t\t\tthis.hammer.destroy();\n\t\t\tthis.hammer = undefined;\n\t\t}\n\t\tif (this.bookElement) {\n\t\t\tthis.bookElement.removeEventListener(\"touchstart\", this.handleTouchStart as EventListener);\n\t\t\tthis.bookElement.removeEventListener(\"touchmove\", this.handleTouchMove as EventListener);\n\t\t}\n\t}\n}\n\nexport { FlipBook, type PageSemantics };\n"],"names":["FlipDirection","Leaf","index","pages","isFlipped","bookProperties","onTurned","value","flipPosition","velocity","resolve","currentFlipPosition","duration","start","step","timestamp","elapsed","progress","newPosition","page","isLTR","isOdd","rotateY","translateX","scaleX","throttle","AspectRatioImpl","width","height","aspectRatio","Size","rhsAspectRatio","rhsAspectRatioValue","DEFAULT_FAST_DELTA","FlipBook","secondLeafIndex","i","leaf","options","selector","debug","bookElement","pageElements","leavesCount","coverSize","leafSize","pageElement","pageIndex","leafIndex","isOddPage","isInitiallyTurned","firstVisibleLeafIndex","isCurrentPage","transform","direction","currentVisiblePageIndices","v","prevVisiblePageIndices","firstVisiblePageIndex","lastLeafFirstPage","Hammer","leftLeaf","rightLeaf","currentLeafIndex","bufferStart","bufferEnd","isWithinBuffer","debugBar","activeFlipsInfo","idx","state","event","flipState","currentPos","bookWidth","delta","posForward","posBackward","ppsX","flipTo","e","touch","deltaX","deltaY","prevVisibilePageIndices","inCurrent","inPrev","lastPageIndex","targetLeafIndex","shouldBeTurned","position"],"mappings":"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"}
1
+ {"version":3,"file":"flipbook.js","sources":["../src/flip-direction.ts","../src/leaf.ts","../src/aspect-ratio.ts","../src/size.ts","../src/flipbook.ts"],"sourcesContent":["export enum FlipDirection {\n\tForward = \"Forward\",\n\tBackward = \"Backward\",\n\tNone = \"None\",\n}\n","import { throttle } from \"throttle-debounce\";\nimport type { IntRange } from \"type-fest\";\nimport { FlipDirection } from \"./flip-direction\";\n\n/** Multiplier for shadow intensity (slightly stronger than base) */\nconst SHADOW_STRENGTH_MULTIPLIER = 1.1;\n/** Multiplier for highlight intensity (slightly weaker than base) */\nconst HIGHLIGHT_STRENGTH_MULTIPLIER = 0.9;\n/** Maximum lift in pixels for the shadow effect */\nconst SHADOW_LIFT_PX = 8;\n\n// number between 1 to infinity\nexport type DegreesPerSecond = IntRange<1, typeof Infinity>;\nexport type FlipPosition = IntRange<0, 2>;\nexport const FLIPPED = true;\nexport const NOT_FLIPPED = false;\nexport class Leaf {\n\tprivate currentAnimation: Promise<void> | null = null;\n\tprivate targetFlipPosition: FlipPosition | null = null;\n\tprivate wrappedFlipPosition: number;\n\tprivate hoverShadow = 0;\n\n\tconstructor(\n\t\treadonly index: number,\n\t\treadonly pages: [HTMLElement, HTMLElement | undefined],\n\t\tisFlipped: boolean,\n\t\tprivate readonly bookProperties: {\n\t\t\tisLTR: boolean;\n\t\t\tpagesCount: number;\n\t\t\tleavesCount: number;\n\t\t},\n\t\tprivate readonly onTurned: (direction: FlipDirection) => void,\n\t) {\n\t\tthis.wrappedFlipPosition = isFlipped ? 1 : 0;\n\t\t// TODO: rethink this\n\t\t// if(isFlipped) {\n\t\t// // this.flipToPosition(1);\n\t\t// }\n\t}\n\n\tget isTurned(): boolean {\n\t\treturn this.flipPosition === 1;\n\t}\n\tget isTurning(): boolean {\n\t\treturn this.flipPosition !== 0;\n\t}\n\tget isCover(): boolean {\n\t\treturn this.isFirst || this.isLast;\n\t}\n\tget isFirst(): boolean {\n\t\treturn this.index === 0;\n\t}\n\tget isLast(): boolean {\n\t\treturn this.index === this.bookProperties.leavesCount - 1;\n\t}\n\tset flipPosition(value: number) {\n\t\tthis.wrappedFlipPosition = Math.max(0, Math.min(1, value)) as FlipPosition;\n\t}\n\tget flipPosition(): number {\n\t\treturn this.wrappedFlipPosition;\n\t}\n\n\tsetHoverShadow(progress: number): void {\n\t\tconst clamped = Math.max(0, Math.min(1, progress));\n\t\tif (this.hoverShadow === clamped) return;\n\t\tthis.hoverShadow = clamped;\n\t\tthis.applyTransform(this.flipPosition);\n\t}\n\n\tasync flipToPosition(\n\t\tflipPosition: FlipPosition,\n\t\tvelocity: DegreesPerSecond = 225 as DegreesPerSecond,\n\t) {\n\t\tif (this.currentAnimation) {\n\t\t\tawait this.currentAnimation;\n\t\t}\n\n\t\tif (this.flipPosition === flipPosition) {\n\t\t\treturn Promise.resolve();\n\t\t}\n\n\t\tif (this.targetFlipPosition === flipPosition) {\n\t\t\treturn this.currentAnimation ?? Promise.resolve();\n\t\t}\n\n\t\tthis.targetFlipPosition = flipPosition;\n\n\t\tthis.currentAnimation = new Promise<void>((resolve) => {\n\t\t\tconst currentFlipPosition = this.flipPosition;\n\t\t\tconst distance = Math.abs(flipPosition - currentFlipPosition);\n\t\t\tconst duration = ((distance * 180) / velocity) * 1000; // duration in milliseconds\n\n\t\t\tconst start = performance.now();\n\t\t\tconst step = (timestamp: number) => {\n\t\t\t\tconst elapsed = timestamp - start;\n\n\t\t\t\tif (elapsed < 0) {\n\t\t\t\t\trequestAnimationFrame(step);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst progress = Math.min(elapsed / duration, 1);\n\t\t\t\tconst newPosition = currentFlipPosition + progress * (flipPosition - currentFlipPosition);\n\n\t\t\t\tthis.applyTransform(newPosition);\n\n\t\t\t\t// Ensure the new position is within valid bounds [0, 1]\n\t\t\t\tthis.flipPosition = Math.max(0, Math.min(1, newPosition)) as FlipPosition;\n\t\t\t\tif (this.flipPosition === 1 || this.flipPosition === 0) {\n\t\t\t\t\tthis.onTurned(this.flipPosition === 1 ? FlipDirection.Forward : FlipDirection.Backward);\n\t\t\t\t}\n\t\t\t\t// Detailed log for debugging\n\t\t\t\t// console.log(\n\t\t\t\t// `Timestamp: ${timestamp}, Elapsed: ${elapsed}, Progress: ${progress}, Current Position: ${currentFlipPosition}, Requested Position: ${flipPosition}, New Position: ${this.flipPosition}`\n\t\t\t\t// );\n\n\t\t\t\tif (progress < 1) {\n\t\t\t\t\trequestAnimationFrame(step);\n\t\t\t\t} else {\n\t\t\t\t\tthis.currentAnimation = null;\n\t\t\t\t\tthis.targetFlipPosition = null;\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\n\t\t\trequestAnimationFrame(step);\n\t\t});\n\n\t\treturn this.currentAnimation;\n\t}\n\n\tasync efficientFlipToPosition(\n\t\tflipPosition: FlipPosition,\n\t\tvelocity: DegreesPerSecond = 20000 as DegreesPerSecond,\n\t) {\n\t\treturn throttle(1, this.flipToPosition.bind(this))(flipPosition, velocity);\n\t}\n\n\tapplyTransform(position: number): void {\n\t\tconst clampedPosition = Math.max(0, Math.min(1, position));\n\t\tconst shadowFromFlip = Math.sin(clampedPosition * Math.PI);\n\t\tconst shadowProgress = Math.max(shadowFromFlip, this.hoverShadow);\n\t\tconst shadowStrength = Math.min(1, shadowProgress * SHADOW_STRENGTH_MULTIPLIER);\n\t\tconst highlightStrength = Math.min(1, shadowProgress * HIGHLIGHT_STRENGTH_MULTIPLIER);\n\t\tconst lift = `${(shadowProgress * SHADOW_LIFT_PX).toFixed(3)}px`;\n\n\t\tthis.pages.forEach((page, index) => {\n\t\t\tconst isLTR = this.bookProperties.isLTR;\n\t\t\tif (!page) return;\n\n\t\t\tconst isOdd = (index % 2) + 1 === 1;\n\t\t\tconst degrees = isOdd\n\t\t\t\t? isLTR\n\t\t\t\t\t? clampedPosition > 0.5\n\t\t\t\t\t\t? 180 - clampedPosition * 180\n\t\t\t\t\t\t: -clampedPosition * 180\n\t\t\t\t\t: clampedPosition > 0.5\n\t\t\t\t\t\t? -(180 - clampedPosition * 180)\n\t\t\t\t\t\t: clampedPosition * 180\n\t\t\t\t: isLTR\n\t\t\t\t\t? clampedPosition < 0.5\n\t\t\t\t\t\t? -clampedPosition * 180\n\t\t\t\t\t\t: 180 - clampedPosition * 180\n\t\t\t\t\t: clampedPosition < 0.5\n\t\t\t\t\t\t? clampedPosition * 180\n\t\t\t\t\t\t: -(180 - clampedPosition * 180);\n\t\t\tconst rotateY = `${degrees}deg`;\n\t\t\tconst translateX = `${isOdd ? (isLTR ? \"100%\" : \"-100%\") : \"0px\"}`;\n\t\t\tconst scaleX = isOdd ? (clampedPosition > 0.5 ? -1 : 1) : clampedPosition < 0.5 ? -1 : 1;\n\t\t\tconst origin = isOdd ? (isLTR ? \"left\" : \"right\") : isLTR ? \"right\" : \"left\";\n\t\t\tconst edge = origin === \"left\" ? \"right\" : \"left\";\n\n\t\t\tpage.style.transform = `translateX(${translateX})rotateY(${rotateY})scaleX(${scaleX})`;\n\t\t\tpage.style.transformOrigin = origin;\n\t\t\tpage.style.zIndex = `${\n\t\t\t\tclampedPosition > 0.5\n\t\t\t\t\t? page.dataset.pageIndex\n\t\t\t\t\t: this.bookProperties.pagesCount - (page.dataset.pageIndex as unknown as number)\n\t\t\t}`;\n\t\t\tpage.style.setProperty(\"--inner-shadow-shadow\", shadowStrength.toFixed(3));\n\t\t\tpage.style.setProperty(\"--inner-shadow-highlight\", highlightStrength.toFixed(3));\n\t\t\tpage.style.setProperty(\"--inner-shadow-lift\", lift);\n\t\t\tpage.style.setProperty(\"--inner-shadow-edge\", edge);\n\t\t});\n\t}\n}\n","export interface AspectRatio {\n\twidth: number;\n\theight: number;\n}\nexport class AspectRatioImpl implements AspectRatio {\n\tstatic from(aspectRatio: AspectRatio) {\n\t\treturn new AspectRatioImpl(aspectRatio.width, aspectRatio.height);\n\t}\n\tconstructor(\n\t\tpublic readonly width: number,\n\t\tpublic readonly height: number,\n\t) {}\n\tget value(): number {\n\t\treturn this.width / this.height;\n\t}\n}\n","import { type AspectRatio, AspectRatioImpl } from \"./aspect-ratio\";\n\nexport class Size {\n\taspectRatio: AspectRatioImpl;\n\taspectRatioFit(rhsAspectRatio: AspectRatio) {\n\t\tconst rhsAspectRatioValue = AspectRatioImpl.from(rhsAspectRatio).value;\n\t\treturn this.aspectRatio.value > rhsAspectRatioValue\n\t\t\t? new Size(this.height * rhsAspectRatioValue, this.height)\n\t\t\t: new Size(this.width, this.width / rhsAspectRatioValue);\n\t}\n\tconstructor(\n\t\tpublic readonly width: number,\n\t\tpublic readonly height: number,\n\t) {\n\t\tthis.aspectRatio = new AspectRatioImpl(width, height);\n\t}\n\tget asString(): string {\n\t\treturn `${this.width}x${this.height}`;\n\t}\n}\n","import \"./pages.scss\";\nimport \"./flipbook.scss\";\nimport Hammer from \"hammerjs\";\nimport { throttle } from \"throttle-debounce\";\nimport type { AspectRatio } from \"./aspect-ratio\";\nimport type { FlipBookOptions } from \"./flip-book-options\";\nimport { FlipDirection } from \"./flip-direction\";\nimport { type FlipPosition, Leaf } from \"./leaf\";\nimport type { PageSemantics } from \"./page-semantics\";\nimport { Size } from \"./size\";\n\n/** Default threshold for fast flip detection (in ms) */\nconst DEFAULT_FAST_DELTA = 500;\n\n/** Percentage of book width that triggers hover shadow effect */\nconst EDGE_ZONE_RATIO = 0.18;\n/** Maximum hover shadow strength (0-1) */\nconst HOVER_STRENGTH_MAX = 0.12;\n/** Throttle interval for mouse move handler in ms */\nconst MOUSE_MOVE_THROTTLE_MS = 16;\n\n/** State for a single flip operation - enables concurrent page flipping */\ninterface FlipState {\n\tleaf: Leaf;\n\tdirection: FlipDirection;\n\tstartingPos: number;\n\tdelta: number;\n\tisDuringAutoFlip: boolean;\n}\nclass FlipBook {\n\tbookElement?: HTMLElement;\n\tprivate pageElements: HTMLElement[] = [];\n\tprivate readonly pagesCount: number;\n\tprivate readonly leafAspectRatio: AspectRatio = { width: 2, height: 3 };\n\tprivate readonly coverAspectRatio: AspectRatio = {\n\t\twidth: 2.15,\n\t\theight: 3.15,\n\t};\n\tprivate readonly direction: \"rtl\" | \"ltr\" = \"ltr\";\n\tprivate readonly fastDeltaThreshold: number = DEFAULT_FAST_DELTA;\n\tprivate readonly initialTurnedLeaves: Set<number> = new Set();\n\tprivate readonly onPageChanged?: (pageIndex: number) => void;\n\tprivate readonly pageSemantics: PageSemantics | undefined;\n\tprivate readonly leavesBuffer?: number;\n\tprivate leaves: Leaf[] = [];\n\t// flipping state - supports concurrent page flipping\n\tprivate activeFlips: Map<number, FlipState> = new Map();\n\tprivate pendingFlipStartingPos = 0;\n\tprivate pendingFlipDirection: FlipDirection = FlipDirection.None;\n\tprivate isDragging = false;\n\tprivate hoveredLeaf: Leaf | undefined;\n\ttouchStartingPos = { x: 0, y: 0 };\n\tprivate prevVisiblePageIndices: [number] | [number, number] | undefined;\n\t// Hammer instance for cleanup\n\tprivate hammer: HammerManager | undefined;\n\tprivate get isLTR(): boolean {\n\t\treturn this.direction === \"ltr\";\n\t}\n\n\tprivate get currentOrTurningLeaves(): [Leaf | undefined, Leaf | undefined] {\n\t\tlet secondLeafIndex = -1;\n\t\tfor (let i = this.leaves.length - 1; i >= 0; i--) {\n\t\t\tconst leaf = this.leaves[i];\n\t\t\tif (leaf.isTurned || leaf.isTurning) {\n\t\t\t\tsecondLeafIndex = leaf.index + 1;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn secondLeafIndex === -1\n\t\t\t? [undefined, this.leaves[0]]\n\t\t\t: secondLeafIndex === this.leaves.length\n\t\t\t\t? [this.leaves[secondLeafIndex - 1], undefined]\n\t\t\t\t: [this.leaves[secondLeafIndex - 1], this.leaves[secondLeafIndex]];\n\t}\n\n\tconstructor(options: FlipBookOptions) {\n\t\tthis.pagesCount = options.pagesCount;\n\t\tthis.leafAspectRatio = options.leafAspectRatio || this.leafAspectRatio;\n\t\tthis.coverAspectRatio = options.coverAspectRatio || this.coverAspectRatio;\n\t\tthis.direction = options.direction || this.direction;\n\t\tthis.fastDeltaThreshold = options.fastDeltaThreshold ?? this.fastDeltaThreshold;\n\t\tthis.initialTurnedLeaves = new Set(options.initialTurnedLeaves ?? []);\n\t\tthis.pageSemantics = options.pageSemantics;\n\t\tthis.onPageChanged = options.onPageChanged;\n\t\tthis.leavesBuffer = options.leavesBuffer;\n\t}\n\n\trender(selector: string, debug = false) {\n\t\tconst bookElement = document.querySelector(selector);\n\t\tif (!bookElement) {\n\t\t\tthrow new Error(`Couldn't find container with selector: ${selector}`);\n\t\t}\n\t\tthis.bookElement = bookElement as HTMLElement;\n\t\tif (!this.bookElement.classList.contains(\"flipbook\")) {\n\t\t\tthis.bookElement.classList.add(\"flipbook\");\n\t\t}\n\n\t\tconst pageElements = bookElement.querySelectorAll(\".page\");\n\t\tif (!pageElements.length) {\n\t\t\tthrow new Error(\"No pages found in flipbook\");\n\t\t}\n\t\tthis.pageElements = Array.from(pageElements) as HTMLElement[];\n\t\tthis.leaves.splice(0, this.leaves.length);\n\t\tconst leavesCount = Math.ceil(this.pagesCount / 2);\n\t\tconst maxCoverSize = new Size(this.bookElement.clientWidth / 2, this.bookElement.clientHeight);\n\t\tconst coverSize = maxCoverSize.aspectRatioFit(this.coverAspectRatio);\n\t\tconst leafSize = new Size(\n\t\t\t(coverSize.width * this.leafAspectRatio.width) / this.coverAspectRatio.width,\n\t\t\t(coverSize.height * this.leafAspectRatio.height) / this.coverAspectRatio.height,\n\t\t);\n\t\tthis.bookElement.style.perspective = `${Math.min(leafSize.width * 2, leafSize.height) * 2}px`;\n\t\tthis.pageElements.forEach((pageElement, pageIndex) => {\n\t\t\tpageElement.style.width = `${leafSize.width}px`;\n\t\t\tpageElement.style.height = `${leafSize.height}px`;\n\n\t\t\tpageElement.style.zIndex = `${this.pagesCount - pageIndex}`;\n\t\t\tpageElement.dataset.pageIndex = pageIndex.toString();\n\t\t\tpageElement.style[this.isLTR ? \"left\" : \"right\"] =\n\t\t\t\t`${(bookElement.clientWidth - 2 * leafSize.width) / 2}px`;\n\t\t\tpageElement.style.top = `${(bookElement.clientHeight - leafSize.height) / 2}px`;\n\t\t\tpageElement.dataset.pageSemanticName =\n\t\t\t\tthis.pageSemantics?.indexToSemanticName(pageIndex) ?? \"\";\n\t\t\tpageElement.dataset.pageTitle = this.pageSemantics?.indexToTitle(pageIndex) ?? \"\";\n\n\t\t\tconst leafIndex = Math.floor(pageIndex / 2);\n\t\t\tconst isOddPage = (pageIndex + 1) % 2 === 1;\n\t\t\tconst isInitiallyTurned = this.initialTurnedLeaves.has(leafIndex);\n\n\t\t\t// Determine current page based on initial turned leaves\n\t\t\t// Current pages are the first two visible pages after all initially turned leaves\n\t\t\tconst firstVisibleLeafIndex =\n\t\t\t\tthis.initialTurnedLeaves.size > 0 ? Math.max(...this.initialTurnedLeaves) + 1 : 0;\n\t\t\tconst isCurrentPage =\n\t\t\t\tleafIndex === firstVisibleLeafIndex ||\n\t\t\t\t(leafIndex === firstVisibleLeafIndex - 1 && isInitiallyTurned);\n\n\t\t\tpageElement.classList.add(\n\t\t\t\tisOddPage ? \"odd\" : \"even\",\n\t\t\t\t...(isCurrentPage ? [\"current-page\"] : []),\n\t\t\t);\n\t\t\tif (isOddPage) {\n\t\t\t\t// Apply correct initial transform based on turned state\n\t\t\t\tif (isInitiallyTurned) {\n\t\t\t\t\t// Fully turned: rotateY(180) or similar based on direction\n\t\t\t\t\tconst scaleX = -1;\n\t\t\t\t\tconst transform = `translateX(${this.isLTR ? \"100%\" : \"-100%\"})rotateY(${this.isLTR ? \"180deg\" : \"-180deg\"})scaleX(${scaleX})`;\n\t\t\t\t\tpageElement.style.transform = transform;\n\t\t\t\t\tpageElement.style.transformOrigin = this.isLTR ? \"left\" : \"right\";\n\t\t\t\t\tpageElement.style.zIndex = `${pageIndex}`; // Turned pages have lower z-index\n\t\t\t\t} else {\n\t\t\t\t\tpageElement.style.transform = `translateX(${this.isLTR ? `` : `-`}100%)`;\n\t\t\t\t\tpageElement.style.zIndex = `${this.pagesCount - pageIndex}`;\n\t\t\t\t}\n\n\t\t\t\tthis.leaves[leafIndex] = new Leaf(\n\t\t\t\t\tleafIndex,\n\t\t\t\t\t[pageElement, undefined],\n\t\t\t\t\tisInitiallyTurned,\n\t\t\t\t\t{\n\t\t\t\t\t\tisLTR: this.isLTR,\n\t\t\t\t\t\tleavesCount: leavesCount,\n\t\t\t\t\t\tpagesCount: this.pagesCount,\n\t\t\t\t\t},\n\t\t\t\t\t(direction: FlipDirection) => {\n\t\t\t\t\t\tconst currentVisiblePageIndices: [number] | [number, number] =\n\t\t\t\t\t\t\tdirection === FlipDirection.Forward\n\t\t\t\t\t\t\t\t? pageIndex + 2 === this.pagesCount\n\t\t\t\t\t\t\t\t\t? [pageIndex + 1]\n\t\t\t\t\t\t\t\t\t: [pageIndex + 1, pageIndex + 2]\n\t\t\t\t\t\t\t\t: pageIndex === 0\n\t\t\t\t\t\t\t\t\t? [pageIndex]\n\t\t\t\t\t\t\t\t\t: [pageIndex - 1, pageIndex];\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tthis.prevVisiblePageIndices &&\n\t\t\t\t\t\t\tthis.prevVisiblePageIndices.length === currentVisiblePageIndices.length &&\n\t\t\t\t\t\t\tcurrentVisiblePageIndices.every((v, i) => v === this.prevVisiblePageIndices?.[i])\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst prevVisiblePageIndices = this.prevVisiblePageIndices;\n\t\t\t\t\t\tthis.prevVisiblePageIndices = currentVisiblePageIndices;\n\n\t\t\t\t\t\t// TODO expose to outside using https://github.com/open-draft/strict-event-emitter, and just be a consumer internally\n\t\t\t\t\t\tthis.onTurned(currentVisiblePageIndices, prevVisiblePageIndices);\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Even page (back side of leaf)\n\t\t\t\tif (isInitiallyTurned) {\n\t\t\t\t\t// Fully turned: apply matching transform for back side\n\t\t\t\t\tconst scaleX = 1;\n\t\t\t\t\tpageElement.style.transform = `translateX(0px)rotateY(${this.isLTR ? \"180deg\" : \"-180deg\"})scaleX(${scaleX})`;\n\t\t\t\t\tpageElement.style.transformOrigin = this.isLTR ? \"right\" : \"left\";\n\t\t\t\t\tpageElement.style.zIndex = `${pageIndex}`; // Turned pages have lower z-index\n\t\t\t\t} else {\n\t\t\t\t\tpageElement.style.transform = `scaleX(-1)translateX(${this.isLTR ? `-` : ``}100%)`;\n\t\t\t\t\tpageElement.style.zIndex = `${this.pagesCount - pageIndex}`;\n\t\t\t\t}\n\t\t\t\tthis.leaves[leafIndex].pages[1] = pageElement;\n\t\t\t}\n\t\t});\n\n\t\t// Set initial visible page indices based on initially turned leaves\n\t\tconst firstVisibleLeafIndex =\n\t\t\tthis.initialTurnedLeaves.size > 0 ? Math.max(...this.initialTurnedLeaves) + 1 : 0;\n\t\tconst firstVisiblePageIndex = firstVisibleLeafIndex * 2;\n\n\t\t// Handle edge case where all leaves are turned (showing last page only)\n\t\tif (firstVisiblePageIndex >= this.pagesCount) {\n\t\t\t// All leaves are turned - show the last page(s)\n\t\t\tconst lastLeafIndex = Math.ceil(this.pagesCount / 2) - 1;\n\t\t\tconst lastLeafFirstPage = lastLeafIndex * 2;\n\t\t\tthis.prevVisiblePageIndices =\n\t\t\t\tlastLeafFirstPage + 1 < this.pagesCount\n\t\t\t\t\t? [lastLeafFirstPage, lastLeafFirstPage + 1]\n\t\t\t\t\t: [lastLeafFirstPage];\n\t\t} else {\n\t\t\tthis.prevVisiblePageIndices =\n\t\t\t\tfirstVisiblePageIndex + 1 < this.pagesCount\n\t\t\t\t\t? [firstVisiblePageIndex, firstVisiblePageIndex + 1]\n\t\t\t\t\t: [firstVisiblePageIndex];\n\t\t}\n\n\t\tthis.hammer = new Hammer(this.bookElement);\n\t\tthis.hammer.on(\"panstart\", this.onDragStart.bind(this));\n\t\tthis.hammer.on(\"panmove\", this.onDragUpdate.bind(this));\n\t\tthis.hammer.on(\"panend\", this.onDragEnd.bind(this));\n\t\tthis.bookElement.addEventListener(\"touchstart\", this.handleTouchStart.bind(this), {\n\t\t\tpassive: false,\n\t\t});\n\t\tthis.bookElement.addEventListener(\"touchmove\", this.handleTouchMove.bind(this), {\n\t\t\tpassive: false,\n\t\t});\n\t\tthis.bookElement.addEventListener(\n\t\t\t\"mousemove\",\n\t\t\tthis.handleMouseMove as unknown as EventListener,\n\t\t);\n\t\tthis.bookElement.addEventListener(\"mouseleave\", this.handleMouseLeave as EventListener);\n\t\t// Apply initial leaves buffer visibility\n\t\tthis.updateLeavesBufferVisibility();\n\t\tif (debug) this.fillDebugBar();\n\t}\n\n\t/**\n\t * Update visibility of leaves based on the buffer setting.\n\t * Leaves outside the buffer range are hidden for performance.\n\t */\n\tprivate updateLeavesBufferVisibility(): void {\n\t\tif (this.leavesBuffer === undefined) {\n\t\t\treturn; // No buffer - all leaves stay visible\n\t\t}\n\n\t\tconst leavesCount = this.leaves.length;\n\t\tif (leavesCount === 0) return;\n\n\t\t// Find the current leaf index (the first non-turned leaf, or last leaf if all turned)\n\t\tconst [leftLeaf, rightLeaf] = this.currentOrTurningLeaves;\n\t\tconst currentLeafIndex = rightLeaf?.index ?? leftLeaf?.index ?? 0;\n\n\t\t// Calculate buffer range\n\t\tconst bufferStart = Math.max(0, currentLeafIndex - this.leavesBuffer);\n\t\tconst bufferEnd = Math.min(leavesCount - 1, currentLeafIndex + this.leavesBuffer);\n\n\t\t// Update visibility of all leaves\n\t\tfor (let i = 0; i < leavesCount; i++) {\n\t\t\tconst leaf = this.leaves[i];\n\t\t\tconst isWithinBuffer = i >= bufferStart && i <= bufferEnd;\n\n\t\t\t// Update both pages of the leaf\n\t\t\tfor (const page of leaf.pages) {\n\t\t\t\tif (page) {\n\t\t\t\t\tpage.style.display = isWithinBuffer ? \"\" : \"none\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate fillDebugBar() {\n\t\tconst debugBar = document.createElement(\"div\");\n\t\tdebugBar.className = \"flipbook-debug-bar\";\n\t\tthis.bookElement?.appendChild(debugBar);\n\t\tsetInterval(() => {\n\t\t\t// Populate debug bar with relevant information\n\t\t\tconst activeFlipsInfo = Array.from(this.activeFlips.entries())\n\t\t\t\t.map(([idx, state]) => `${idx}:${state.leaf.flipPosition.toFixed(2)}`)\n\t\t\t\t.join(\", \");\n\t\t\tdebugBar.innerHTML = `\n <div>Direction: ${this.isLTR ? \"LTR\" : \"RTL\"}</div>\n <div>Active Flips: ${this.activeFlips.size} [${activeFlipsInfo}]</div>\n <div>Pending Flip dir: ${this.pendingFlipDirection}</div>\n `;\n\t\t}, 10);\n\t}\n\n\t/**\n\t * Get the current manually-controlled flip state (the one being dragged).\n\t * Returns undefined if no manual flip is in progress.\n\t */\n\tprivate get currentManualFlip(): FlipState | undefined {\n\t\tfor (const state of this.activeFlips.values()) {\n\t\t\tif (!state.isDuringAutoFlip) {\n\t\t\t\treturn state;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Find the next available leaf for flipping in the given direction.\n\t * Excludes leaves that are already being flipped.\n\t */\n\tprivate getNextAvailableLeaf(direction: FlipDirection): Leaf | undefined {\n\t\tif (direction === FlipDirection.Forward) {\n\t\t\t// Find the rightmost leaf that's not already flipping\n\t\t\t// Start from the current right leaf and go forward\n\t\t\tconst [, rightLeaf] = this.currentOrTurningLeaves;\n\t\t\tif (!rightLeaf) return undefined;\n\n\t\t\t// Find a leaf that's not in activeFlips\n\t\t\tfor (let i = rightLeaf.index; i < this.leaves.length; i++) {\n\t\t\t\tconst leaf = this.leaves[i];\n\t\t\t\tif (!this.activeFlips.has(leaf.index) && !leaf.isTurned) {\n\t\t\t\t\treturn leaf;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn undefined;\n\t\t} else if (direction === FlipDirection.Backward) {\n\t\t\t// Find the leftmost leaf that's not already flipping\n\t\t\tconst [leftLeaf] = this.currentOrTurningLeaves;\n\t\t\tif (!leftLeaf) return undefined;\n\n\t\t\t// Find a leaf that's not in activeFlips\n\t\t\tfor (let i = leftLeaf.index; i >= 0; i--) {\n\t\t\t\tconst leaf = this.leaves[i];\n\t\t\t\tif (!this.activeFlips.has(leaf.index) && (leaf.isTurned || leaf.isTurning)) {\n\t\t\t\t\treturn leaf;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate onDragStart(event: HammerInput) {\n\t\t// Allow starting a new flip even if others are in auto-flip mode\n\t\t// Only block if we already have a manual flip in progress\n\t\tif (this.currentManualFlip) {\n\t\t\tthis.pendingFlipDirection = FlipDirection.None;\n\t\t\tthis.pendingFlipStartingPos = 0;\n\t\t\treturn;\n\t\t}\n\t\tthis.isDragging = true;\n\t\tthis.clearHoverShadow();\n\t\tthis.pendingFlipStartingPos = event.center.x;\n\t\tthis.pendingFlipDirection = FlipDirection.None;\n\t}\n\n\tprivate onDragUpdate(event: HammerInput) {\n\t\t// Get or create the current manual flip state\n\t\tlet flipState = this.currentManualFlip;\n\n\t\tconst currentPos = event.center.x;\n\t\tconst bookWidth = this.bookElement?.clientWidth ?? 0;\n\n\t\t// Calculate delta\n\t\tconst delta = this.isLTR\n\t\t\t? this.pendingFlipStartingPos - currentPos\n\t\t\t: currentPos - this.pendingFlipStartingPos;\n\n\t\tif (Math.abs(delta) > bookWidth) return;\n\t\tif (delta === 0) return;\n\n\t\t// Determine direction on first meaningful movement\n\t\tconst direction =\n\t\t\tthis.pendingFlipDirection !== FlipDirection.None\n\t\t\t\t? this.pendingFlipDirection\n\t\t\t\t: delta > 0\n\t\t\t\t\t? FlipDirection.Forward\n\t\t\t\t\t: FlipDirection.Backward;\n\n\t\t// Lock in direction for this flip\n\t\tif (this.pendingFlipDirection === FlipDirection.None) {\n\t\t\tthis.pendingFlipDirection = direction;\n\t\t}\n\n\t\t// Block starting a new flip in opposite direction while auto-flip is in progress\n\t\t// This prevents visual glitches when swiping backward while a forward flip is animating\n\t\tif (!flipState) {\n\t\t\tfor (const state of this.activeFlips.values()) {\n\t\t\t\tif (state.isDuringAutoFlip && state.direction !== direction) {\n\t\t\t\t\t// There's an auto-flip in the opposite direction - block this new flip\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we don't have a flip state yet, create one\n\t\tif (!flipState) {\n\t\t\tconst leaf = this.getNextAvailableLeaf(direction);\n\t\t\tif (!leaf) return;\n\n\t\t\tflipState = {\n\t\t\t\tleaf,\n\t\t\t\tdirection,\n\t\t\t\tstartingPos: this.pendingFlipStartingPos,\n\t\t\t\tdelta: 0,\n\t\t\t\tisDuringAutoFlip: false,\n\t\t\t};\n\t\t\tthis.activeFlips.set(leaf.index, flipState);\n\t\t}\n\n\t\t// Update delta\n\t\tflipState.delta = delta;\n\n\t\t// Calculate and apply flip position\n\t\tswitch (flipState.direction) {\n\t\t\tcase FlipDirection.Forward: {\n\t\t\t\tconst posForward = (delta / bookWidth) as FlipPosition;\n\t\t\t\tif (posForward > 1 || delta < 0) return;\n\t\t\t\tflipState.leaf.efficientFlipToPosition(posForward);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase FlipDirection.Backward: {\n\t\t\t\tconst posBackward = (1 - Math.abs(delta) / bookWidth) as FlipPosition;\n\t\t\t\tif (posBackward < 0 || delta > 0) return;\n\t\t\t\tflipState.leaf.efficientFlipToPosition(posBackward);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate onDragEnd(event: HammerInput) {\n\t\tconst flipState = this.currentManualFlip;\n\t\tif (!flipState) {\n\t\t\tthis.pendingFlipDirection = FlipDirection.None;\n\t\t\tthis.pendingFlipStartingPos = 0;\n\t\t\tthis.isDragging = false;\n\t\t\tthis.clearHoverShadow();\n\t\t\treturn;\n\t\t}\n\n\t\tconst ppsX = event.velocityX * 1000; // pixels per second\n\t\tlet flipTo: FlipPosition;\n\n\t\tswitch (flipState.direction) {\n\t\t\tcase FlipDirection.Forward:\n\t\t\t\tif (\n\t\t\t\t\t(this.isLTR ? ppsX < -this.fastDeltaThreshold : ppsX > this.fastDeltaThreshold) ||\n\t\t\t\t\tflipState.leaf.flipPosition >= 0.5\n\t\t\t\t) {\n\t\t\t\t\tflipTo = 1;\n\t\t\t\t} else {\n\t\t\t\t\tflipTo = 0;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase FlipDirection.Backward:\n\t\t\t\tif (\n\t\t\t\t\t(this.isLTR ? ppsX > this.fastDeltaThreshold : ppsX < -this.fastDeltaThreshold) ||\n\t\t\t\t\tflipState.leaf.flipPosition <= 0.5\n\t\t\t\t) {\n\t\t\t\t\tflipTo = 0;\n\t\t\t\t} else {\n\t\t\t\t\tflipTo = 1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\n\t\t// Mark as auto-flip and reset pending state\n\t\tflipState.isDuringAutoFlip = true;\n\t\tthis.pendingFlipDirection = FlipDirection.None;\n\t\tthis.pendingFlipStartingPos = 0;\n\t\tthis.isDragging = false;\n\n\t\t// Complete the flip asynchronously - don't block new flips!\n\t\tflipState.leaf.flipToPosition(flipTo).then(() => {\n\t\t\tthis.activeFlips.delete(flipState.leaf.index);\n\t\t});\n\t}\n\n\tprivate handleTouchStart = (e: TouchEvent) => {\n\t\tif (e.touches.length > 1) {\n\t\t\treturn;\n\t\t}\n\t\tconst touch = e.touches[0];\n\t\tthis.touchStartingPos = { x: touch.pageX, y: touch.pageY };\n\t};\n\n\tprivate handleTouchMove = (e: TouchEvent) => {\n\t\tif (e.touches.length > 1) {\n\t\t\treturn;\n\t\t}\n\t\tconst touch = e.touches[0];\n\t\tconst deltaX = touch.pageX - this.touchStartingPos.x;\n\t\tconst deltaY = touch.pageY - this.touchStartingPos.y;\n\t\t// only allow vertical scrolling, as if allowing horizontal scrolling, it will interfere with the flip gesture (for touch devices)\n\t\t// TODO: allow horizontal scrolling if the user is not trying to flip, say if is scrolling an overflowed element\n\t\tif (Math.abs(deltaX) > Math.abs(deltaY)) {\n\t\t\te.preventDefault();\n\t\t}\n\t};\n\n\tprivate handleMouseMove = throttle(MOUSE_MOVE_THROTTLE_MS, (event: MouseEvent) => {\n\t\tif (!this.bookElement) return;\n\t\tif (this.isDragging || this.currentManualFlip || this.activeFlips.size > 0) {\n\t\t\tthis.clearHoverShadow();\n\t\t\treturn;\n\t\t}\n\n\t\tconst rect = this.bookElement.getBoundingClientRect();\n\t\tif (rect.width <= 0) return;\n\n\t\tconst x = event.clientX - rect.left;\n\t\tconst edgeZone = rect.width * EDGE_ZONE_RATIO;\n\t\tconst isLeftEdge = x <= edgeZone;\n\t\tconst isRightEdge = x >= rect.width - edgeZone;\n\n\t\tif (!isLeftEdge && !isRightEdge) {\n\t\t\tthis.clearHoverShadow();\n\t\t\treturn;\n\t\t}\n\n\t\tconst isForward = this.isLTR ? isRightEdge : isLeftEdge;\n\t\tconst direction = isForward ? FlipDirection.Forward : FlipDirection.Backward;\n\t\tconst leaf = this.getNextAvailableLeaf(direction);\n\t\tif (!leaf) {\n\t\t\tthis.clearHoverShadow();\n\t\t\treturn;\n\t\t}\n\n\t\tconst distanceFromEdge = isForward\n\t\t\t? this.isLTR\n\t\t\t\t? rect.width - x\n\t\t\t\t: x\n\t\t\t: this.isLTR\n\t\t\t\t? x\n\t\t\t\t: rect.width - x;\n\t\tconst edgeProgress = 1 - Math.min(1, distanceFromEdge / edgeZone);\n\t\tconst hoverStrength = edgeProgress * HOVER_STRENGTH_MAX;\n\n\t\tif (this.hoveredLeaf && this.hoveredLeaf !== leaf) {\n\t\t\tthis.hoveredLeaf.setHoverShadow(0);\n\t\t}\n\t\tthis.hoveredLeaf = leaf;\n\t\tleaf.setHoverShadow(hoverStrength);\n\t});\n\n\tprivate handleMouseLeave = () => {\n\t\tthis.clearHoverShadow();\n\t};\n\n\tprivate clearHoverShadow() {\n\t\tif (this.hoveredLeaf) {\n\t\t\tthis.hoveredLeaf.setHoverShadow(0);\n\t\t\tthis.hoveredLeaf = undefined;\n\t\t}\n\t}\n\tprivate onTurned(\n\t\tcurrentVisiblePageIndices: [number] | [number, number],\n\t\tprevVisibilePageIndices?: [number] | [number, number],\n\t) {\n\t\tfor (let i = 0; i < this.pageElements.length; i++) {\n\t\t\tconst pageElement = this.pageElements[i];\n\t\t\tconst inCurrent = currentVisiblePageIndices.includes(i);\n\t\t\tconst inPrev = prevVisibilePageIndices?.includes(i);\n\t\t\tconst action = inCurrent\n\t\t\t\t? pageElement.classList.add\n\t\t\t\t: !prevVisibilePageIndices || !inPrev\n\t\t\t\t\t? () => null\n\t\t\t\t\t: pageElement.classList.remove;\n\t\t\taction.bind(pageElement.classList)(\"current-page\");\n\t\t}\n\t\t// Update leaves buffer visibility after turn completes\n\t\tthis.updateLeavesBufferVisibility();\n\t\t// TODO expose to outside using https://github.com/open-draft/strict-event-emitter, and just be a consumer internally.\n\t\t// TODO: set prev-page / next-page classes for prev/next pages as accordingally\n\t}\n\t/**\n\t * Get the index of the current (leftmost visible) page.\n\t * Returns 0 if no pages are visible.\n\t */\n\tget currentPageIndex(): number {\n\t\treturn this.prevVisiblePageIndices?.[0] ?? 0;\n\t}\n\n\t/**\n\t * Get the total number of pages in the flipbook.\n\t */\n\tget totalPages(): number {\n\t\treturn this.pagesCount;\n\t}\n\n\t/**\n\t * Check if the book is currently showing the first page(s).\n\t */\n\tget isFirstPage(): boolean {\n\t\treturn this.currentPageIndex === 0;\n\t}\n\n\t/**\n\t * Check if the book is currently showing the last page(s).\n\t */\n\tget isLastPage(): boolean {\n\t\tconst lastPageIndex = this.pagesCount - 1;\n\t\treturn this.prevVisiblePageIndices?.includes(lastPageIndex) ?? false;\n\t}\n\n\t/**\n\t * Check if there's an active auto-flip in the given direction.\n\t */\n\tprivate hasActiveAutoFlipInDirection(direction: FlipDirection): boolean {\n\t\tfor (const state of this.activeFlips.values()) {\n\t\t\tif (state.isDuringAutoFlip && state.direction === direction) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Animate flip to the next page.\n\t * @returns Promise that resolves when the flip animation completes\n\t */\n\tasync flipNext(): Promise<void> {\n\t\t// Block if there's an active auto-flip in the opposite direction\n\t\tif (this.hasActiveAutoFlipInDirection(FlipDirection.Backward)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst leaf = this.getNextAvailableLeaf(FlipDirection.Forward);\n\t\tif (!leaf) return;\n\n\t\tconst flipState: FlipState = {\n\t\t\tleaf,\n\t\t\tdirection: FlipDirection.Forward,\n\t\t\tstartingPos: 0,\n\t\t\tdelta: 0,\n\t\t\tisDuringAutoFlip: true,\n\t\t};\n\t\tthis.activeFlips.set(leaf.index, flipState);\n\n\t\ttry {\n\t\t\tawait leaf.flipToPosition(1);\n\t\t} finally {\n\t\t\tthis.activeFlips.delete(leaf.index);\n\t\t}\n\t}\n\n\t/**\n\t * Animate flip to the previous page.\n\t * @returns Promise that resolves when the flip animation completes\n\t */\n\tasync flipPrev(): Promise<void> {\n\t\t// Block if there's an active auto-flip in the opposite direction\n\t\tif (this.hasActiveAutoFlipInDirection(FlipDirection.Forward)) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst leaf = this.getNextAvailableLeaf(FlipDirection.Backward);\n\t\tif (!leaf) return;\n\n\t\tconst flipState: FlipState = {\n\t\t\tleaf,\n\t\t\tdirection: FlipDirection.Backward,\n\t\t\tstartingPos: 0,\n\t\t\tdelta: 0,\n\t\t\tisDuringAutoFlip: true,\n\t\t};\n\t\tthis.activeFlips.set(leaf.index, flipState);\n\n\t\ttry {\n\t\t\tawait leaf.flipToPosition(0);\n\t\t} finally {\n\t\t\tthis.activeFlips.delete(leaf.index);\n\t\t}\n\t}\n\n\t/**\n\t * Animate to a specific page index.\n\t * Flips through pages sequentially to reach the target.\n\t * @param pageIndex - The target page index (0-based)\n\t * @returns Promise that resolves when all flip animations complete\n\t */\n\tasync goToPage(pageIndex: number): Promise<void> {\n\t\tif (pageIndex < 0 || pageIndex >= this.pagesCount) {\n\t\t\tconsole.warn(\n\t\t\t\t`goToPage: Invalid page index ${pageIndex}. Must be between 0 and ${this.pagesCount - 1}.`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst targetLeafIndex = Math.floor(pageIndex / 2);\n\t\tconst currentLeafIndex = Math.floor(this.currentPageIndex / 2);\n\n\t\tif (targetLeafIndex === currentLeafIndex) {\n\t\t\treturn; // Already at the target page\n\t\t}\n\n\t\tif (targetLeafIndex > currentLeafIndex) {\n\t\t\t// Flip forward\n\t\t\tfor (let i = currentLeafIndex; i < targetLeafIndex; i++) {\n\t\t\t\tawait this.flipNext();\n\t\t\t}\n\t\t} else {\n\t\t\t// Flip backward\n\t\t\tfor (let i = currentLeafIndex; i > targetLeafIndex; i--) {\n\t\t\t\tawait this.flipPrev();\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Jump to a specific page instantly without animation.\n\t * @param pageIndex - The target page index (0-based)\n\t */\n\tjumpToPage(pageIndex: number): void {\n\t\tif (pageIndex < 0 || pageIndex >= this.pagesCount) {\n\t\t\tconsole.warn(\n\t\t\t\t`jumpToPage: Invalid page index ${pageIndex}. Must be between 0 and ${this.pagesCount - 1}.`,\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\n\t\tconst targetLeafIndex = Math.floor(pageIndex / 2);\n\t\tconst isLastPage = pageIndex === this.pagesCount - 1;\n\t\tconst isOddPage = pageIndex % 2 === 1;\n\t\t// If targeting the last page and it's odd (back of leaf), close the book reversed\n\t\tconst closeBookReversed = isLastPage && isOddPage;\n\n\t\t// Set all leaves before target as turned, all after as not turned\n\t\tfor (let i = 0; i < this.leaves.length; i++) {\n\t\t\tconst leaf = this.leaves[i];\n\t\t\t// Turn leaves before target, or the target leaf itself if closing book reversed\n\t\t\tconst shouldBeTurned = i < targetLeafIndex || (closeBookReversed && i === targetLeafIndex);\n\n\t\t\tif (shouldBeTurned && !leaf.isTurned) {\n\t\t\t\t// Turn this leaf instantly\n\t\t\t\tleaf.flipPosition = 1;\n\t\t\t\tthis.applyLeafTransform(leaf, 1);\n\t\t\t} else if (!shouldBeTurned && leaf.isTurned) {\n\t\t\t\t// Unturn this leaf instantly\n\t\t\t\tleaf.flipPosition = 0;\n\t\t\t\tthis.applyLeafTransform(leaf, 0);\n\t\t\t}\n\t\t}\n\n\t\t// Update visible page indices\n\t\tif (closeBookReversed) {\n\t\t\t// Closed reversed: only show the last page\n\t\t\tthis.prevVisiblePageIndices = [pageIndex];\n\t\t} else {\n\t\t\tconst firstVisiblePageIndex = targetLeafIndex * 2;\n\t\t\tthis.prevVisiblePageIndices =\n\t\t\t\tfirstVisiblePageIndex + 1 < this.pagesCount\n\t\t\t\t\t? [firstVisiblePageIndex, firstVisiblePageIndex + 1]\n\t\t\t\t\t: [firstVisiblePageIndex];\n\t\t}\n\n\t\t// Update current-page classes\n\t\tfor (let i = 0; i < this.pageElements.length; i++) {\n\t\t\tconst pageElement = this.pageElements[i];\n\t\t\tif (this.prevVisiblePageIndices.includes(i)) {\n\t\t\t\tpageElement.classList.add(\"current-page\");\n\t\t\t} else {\n\t\t\t\tpageElement.classList.remove(\"current-page\");\n\t\t\t}\n\t\t}\n\n\t\t// Update leaves buffer visibility\n\t\tthis.updateLeavesBufferVisibility();\n\n\t\t// Notify callback\n\t\tif (this.onPageChanged) {\n\t\t\tthis.onPageChanged(this.currentPageIndex);\n\t\t}\n\t}\n\n\t/**\n\t * Apply transform styles to a leaf's pages for a given flip position.\n\t * Used for instant positioning (jumpToPage).\n\t */\n\tprivate applyLeafTransform(leaf: Leaf, position: number): void {\n\t\tleaf.applyTransform(position);\n\t}\n\n\t/**\n\t * Clean up event listeners and Hammer instance.\n\t * Should be called when the FlipBook is no longer needed.\n\t */\n\tdestroy() {\n\t\tif (this.hammer) {\n\t\t\tthis.hammer.destroy();\n\t\t\tthis.hammer = undefined;\n\t\t}\n\t\tif (this.bookElement) {\n\t\t\tthis.bookElement.removeEventListener(\"touchstart\", this.handleTouchStart as EventListener);\n\t\t\tthis.bookElement.removeEventListener(\"touchmove\", this.handleTouchMove as EventListener);\n\t\t\tthis.bookElement.removeEventListener(\n\t\t\t\t\"mousemove\",\n\t\t\t\tthis.handleMouseMove as unknown as EventListener,\n\t\t\t);\n\t\t\tthis.bookElement.removeEventListener(\"mouseleave\", this.handleMouseLeave as EventListener);\n\t\t}\n\t}\n}\n\nexport { FlipBook, type PageSemantics };\n"],"names":["FlipDirection","SHADOW_STRENGTH_MULTIPLIER","HIGHLIGHT_STRENGTH_MULTIPLIER","SHADOW_LIFT_PX","Leaf","index","pages","isFlipped","bookProperties","onTurned","value","progress","clamped","flipPosition","velocity","resolve","currentFlipPosition","duration","start","step","timestamp","elapsed","newPosition","throttle","position","clampedPosition","shadowFromFlip","shadowProgress","shadowStrength","highlightStrength","lift","page","isLTR","isOdd","rotateY","translateX","scaleX","origin","edge","AspectRatioImpl","width","height","aspectRatio","Size","rhsAspectRatio","rhsAspectRatioValue","DEFAULT_FAST_DELTA","EDGE_ZONE_RATIO","HOVER_STRENGTH_MAX","MOUSE_MOVE_THROTTLE_MS","FlipBook","secondLeafIndex","i","leaf","options","selector","debug","bookElement","pageElements","leavesCount","coverSize","leafSize","pageElement","pageIndex","leafIndex","isOddPage","isInitiallyTurned","firstVisibleLeafIndex","isCurrentPage","transform","direction","currentVisiblePageIndices","v","prevVisiblePageIndices","firstVisiblePageIndex","lastLeafFirstPage","Hammer","leftLeaf","rightLeaf","currentLeafIndex","bufferStart","bufferEnd","isWithinBuffer","debugBar","activeFlipsInfo","idx","state","event","flipState","currentPos","bookWidth","delta","posForward","posBackward","ppsX","flipTo","e","touch","deltaX","deltaY","rect","x","edgeZone","isLeftEdge","isRightEdge","isForward","distanceFromEdge","hoverStrength","prevVisibilePageIndices","inCurrent","inPrev","lastPageIndex","targetLeafIndex","isLastPage","closeBookReversed","shouldBeTurned"],"mappings":"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"}
package/dist/leaf.d.ts CHANGED
@@ -12,6 +12,7 @@ export declare class Leaf {
12
12
  private currentAnimation;
13
13
  private targetFlipPosition;
14
14
  private wrappedFlipPosition;
15
+ private hoverShadow;
15
16
  constructor(index: number, pages: [HTMLElement, HTMLElement | undefined], isFlipped: boolean, bookProperties: {
16
17
  isLTR: boolean;
17
18
  pagesCount: number;
@@ -24,7 +25,9 @@ export declare class Leaf {
24
25
  get isLast(): boolean;
25
26
  set flipPosition(value: number);
26
27
  get flipPosition(): number;
28
+ setHoverShadow(progress: number): void;
27
29
  flipToPosition(flipPosition: FlipPosition, velocity?: DegreesPerSecond): Promise<void>;
28
30
  efficientFlipToPosition(flipPosition: FlipPosition, velocity?: DegreesPerSecond): Promise<void>;
31
+ applyTransform(position: number): void;
29
32
  }
30
33
  //# sourceMappingURL=leaf.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"leaf.d.ts","sourceRoot":"","sources":["../src/leaf.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGjD,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,CAAC,EAAE,OAAO,QAAQ,CAAC,CAAC;AAC5D,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC1C,eAAO,MAAM,OAAO,OAAO,CAAC;AAC5B,eAAO,MAAM,WAAW,QAAQ,CAAC;AACjC,qBAAa,IAAI;IAMf,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,QAAQ,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,CAAC;IAEtD,OAAO,CAAC,QAAQ,CAAC,cAAc;IAK/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAb1B,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,mBAAmB,CAAS;gBAG1B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,CAAC,EACtD,SAAS,EAAE,OAAO,EACD,cAAc,EAAE;QAChC,KAAK,EAAE,OAAO,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACpB,EACgB,QAAQ,EAAE,CAAC,SAAS,EAAE,aAAa,KAAK,IAAI;IAS9D,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,SAAS,IAAI,OAAO,CAEvB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,MAAM,IAAI,OAAO,CAEpB;IACD,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAE7B;IACD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAEK,cAAc,CACnB,YAAY,EAAE,YAAY,EAC1B,QAAQ,GAAE,gBAA0C;IA6F/C,uBAAuB,CAC5B,YAAY,EAAE,YAAY,EAC1B,QAAQ,GAAE,gBAA4C;CAIvD"}
1
+ {"version":3,"file":"leaf.d.ts","sourceRoot":"","sources":["../src/leaf.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAUjD,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC,CAAC,EAAE,OAAO,QAAQ,CAAC,CAAC;AAC5D,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC1C,eAAO,MAAM,OAAO,OAAO,CAAC;AAC5B,eAAO,MAAM,WAAW,QAAQ,CAAC;AACjC,qBAAa,IAAI;IAOf,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,QAAQ,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,CAAC;IAEtD,OAAO,CAAC,QAAQ,CAAC,cAAc;IAK/B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAd1B,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,WAAW,CAAK;gBAGd,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,CAAC,EACtD,SAAS,EAAE,OAAO,EACD,cAAc,EAAE;QAChC,KAAK,EAAE,OAAO,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;KACpB,EACgB,QAAQ,EAAE,CAAC,SAAS,EAAE,aAAa,KAAK,IAAI;IAS9D,IAAI,QAAQ,IAAI,OAAO,CAEtB;IACD,IAAI,SAAS,IAAI,OAAO,CAEvB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,OAAO,IAAI,OAAO,CAErB;IACD,IAAI,MAAM,IAAI,OAAO,CAEpB;IACD,IAAI,YAAY,CAAC,KAAK,EAAE,MAAM,EAE7B;IACD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAOhC,cAAc,CACnB,YAAY,EAAE,YAAY,EAC1B,QAAQ,GAAE,gBAA0C;IA4D/C,uBAAuB,CAC5B,YAAY,EAAE,YAAY,EAC1B,QAAQ,GAAE,gBAA4C;IAKvD,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;CA+CtC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "html-flip-book-vanilla",
3
- "version": "0.0.0-alpha.10",
3
+ "version": "0.0.0-alpha.15",
4
4
  "description": "Flipbook component for HTML (vanilla JavaScript)",
5
5
  "author": "DoradSoft",
6
6
  "type": "module",