flipbookengine 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -157,7 +157,24 @@ FlipbookEngine features fully custom-property-based styling compatible with mode
157
157
  }
158
158
  ```
159
159
 
160
- ## 🆚 FlipbookEngine vs. The Industry
160
+ ## 🚀 Performance & Bundle Metrics
161
+
162
+ FlipbookEngine is engineered for high performance, utilizing hardware-accelerated CSS 3D transforms instead of heavy WebGL, ensuring a smooth **60 FPS** experience even on low-end mobile devices.
163
+
164
+ ### 📦 Bundle Size (Zero-Config PDF Engine)
165
+ Unlike other libraries that require complex external PDF.js worker configurations, FlipbookEngine ships as an **"All-in-One"** package. It includes the Core Engine, UI layout, StPageFlip, and the full PDF.js rendering engine out of the box.
166
+
167
+ * **Core + PDF Engine (Gzipped):** `~788 KB` *(A single drop-in script, no external workers needed)*
168
+ * **Styles (CSS Gzipped):** `~2.9 KB`
169
+ * **React / Vue Wrappers (Gzipped):** `< 1 KB`
170
+
171
+ ### ⚡ Performance Highlights
172
+ * **Hardware Accelerated:** Uses purely CSS-based 3D transformations (`transform: rotateY`, `translateZ`) which offloads rendering to the GPU. No heavy WebGL overhead.
173
+ * **Smart Memory Management (Lazy Loading):** Automatically unloads hidden pages from the DOM and destroys unused PDF blobs to prevent memory leaks on large catalogs.
174
+ * **Zero-CLS Layouts:** Prevents Cumulative Layout Shift (CLS) by utilizing highly optimized `AbortController` bound resize event listeners and native CSS `aspect-ratio` calculations.
175
+ * **Eco-Friendly Standby:** Stops running layout calculations when the catalog is not actively being dragged or flipped.
176
+
177
+ ## 🥊 FlipbookEngine vs. The Industry
161
178
 
162
179
  When choosing a flipbook library, here is how we compare to other solutions:
163
180
 
@@ -19236,11 +19236,11 @@ const Bl = class Bl {
19236
19236
  if (!this.pageViewport || !this.ui.bookWrapper || !this.ui.bookSizer) return;
19237
19237
  const I = this.ui.bookWrapper.clientWidth, g = this.ui.bookWrapper.clientHeight;
19238
19238
  if (I === 0 || g === 0) return;
19239
- const C = this.pageViewport.width, A = this.pageViewport.height, Z = !this.state.isSingle && this.state.orientation === "landscape" ? C * 2 / A : C / A;
19240
- let d = g * Z, s = g;
19241
- d > I && (d = I, s = I / Z);
19242
- let c = Math.ceil(d);
19243
- c % 2 !== 0 && (c += 1), this.ui.bookSizer.style.width = `${c}px`, this.ui.bookSizer.style.height = `${Math.floor(s)}px`, this.ui.bookSizer.style.aspectRatio = "";
19239
+ const C = this.pageViewport.width, A = this.pageViewport.height, i = I < g, d = !this.state.isSingle && !i ? C * 2 / A : C / A;
19240
+ let s = g * d, c = g;
19241
+ s > I && (s = I, c = I / d);
19242
+ let G = Math.ceil(s);
19243
+ G % 2 !== 0 && (G += 1), this.ui.bookSizer.style.width = `${G}px`, this.ui.bookSizer.style.height = `${Math.floor(c)}px`, this.ui.bookSizer.style.aspectRatio = "";
19244
19244
  }
19245
19245
  playSound() {
19246
19246
  if (this.options.soundEnabled)
@@ -19263,10 +19263,14 @@ const Bl = class Bl {
19263
19263
  renderPagesIntoDOM() {
19264
19264
  const I = this.ui.book, g = this.ui.thumbs;
19265
19265
  this.pages.forEach((C, A) => {
19266
- const i = this.createPageImage(C, "low"), Z = A % 2 === 0 ? "bz-page--right" : "bz-page--left", s = A === 0 || A === this.pages.length - 1 ? "bz-page--cover" : "", c = U("div", { class: "page-shadow" }), G = U("div", { class: `bz-page ${Z} ${s}`, dataset: { idx: A.toString() } }, [i, c]);
19267
- I.appendChild(G);
19268
- const m = this.createThumbnailImage(C), W = U("span", null, [C.pageNumber.toString()]), a = U("div", { class: `thumb-item ${A === 0 ? "active" : ""}`, dataset: { pageIndex: A.toString() } }, [m, W]);
19269
- g.appendChild(a);
19266
+ const i = A < 2, Z = this.createPageImage(C, "low", i), d = A % 2 === 0 ? "bz-page--right" : "bz-page--left", c = A === 0 || A === this.pages.length - 1 ? "bz-page--cover" : "", G = U("div", { class: "page-shadow" }), m = U("div", {
19267
+ class: `bz-page ${d} ${c}`,
19268
+ style: i ? "" : "display: none;",
19269
+ dataset: { idx: A.toString() }
19270
+ }, [Z, G]);
19271
+ I.appendChild(m);
19272
+ const W = this.createThumbnailImage(C, !1), a = U("span", null, [C.pageNumber.toString()]), t = U("div", { class: `thumb-item ${A === 0 ? "active" : ""}`, dataset: { pageIndex: A.toString() } }, [W, a]);
19273
+ g.appendChild(t);
19270
19274
  });
19271
19275
  }
19272
19276
  initPageFlip() {
@@ -19295,19 +19299,21 @@ const Bl = class Bl {
19295
19299
  this.ui.book.querySelector(".empty-cover") !== null ? this.state.currentPage = A.data - 1 : this.state.currentPage = A.data, this.state.currentPage < 0 && (this.state.currentPage = 0), this.syncUI(), this.playSound(), this.emitPageChange();
19296
19300
  });
19297
19301
  }
19298
- createPageImage(I, g) {
19299
- const C = U("img", {
19302
+ createPageImage(I, g, C = !1) {
19303
+ const A = U("img", {
19300
19304
  class: this.getPageImageClassName(I.cropMode),
19301
- dataset: { cropMode: I.cropMode }
19305
+ dataset: { cropMode: I.cropMode },
19306
+ loading: C ? "eager" : "lazy"
19302
19307
  });
19303
- return this.ensurePageSrc(I, g, C), C;
19308
+ return this.ensurePageSrc(I, g, A), A;
19304
19309
  }
19305
- createThumbnailImage(I) {
19306
- const g = U("img", {
19310
+ createThumbnailImage(I, g = !1) {
19311
+ const C = U("img", {
19307
19312
  class: this.getThumbnailImageClassName(I.cropMode),
19308
- dataset: { cropMode: I.cropMode }
19313
+ dataset: { cropMode: I.cropMode },
19314
+ loading: g ? "eager" : "lazy"
19309
19315
  });
19310
- return this.ensurePageSrc(I, "thumb", g), g;
19316
+ return this.ensurePageSrc(I, "thumb", C), C;
19311
19317
  }
19312
19318
  async ensurePageSrc(I, g, C) {
19313
19319
  var d;
@@ -19322,7 +19328,7 @@ const Bl = class Bl {
19322
19328
  C.src = this.pdfPagesCache.get(Z);
19323
19329
  return;
19324
19330
  }
19325
- C.src = 'data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="141" viewBox="0 0 100 141"><rect width="100" height="141" fill="%231e293b"/><text x="50" y="75" fill="%2364748b" font-family="sans-serif" font-size="10" text-anchor="middle">Loading...</text></svg>';
19331
+ C.src = 'data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 141" width="100%" height="100%"><rect width="100" height="141" fill="%231e293b"/><circle cx="50" cy="70" r="10" fill="none" stroke="%2364748b" stroke-width="2" stroke-dasharray="15 15"><animateTransform attributeName="transform" type="rotate" from="0 50 70" to="360 50 70" dur="1s" repeatCount="indefinite"/></circle></svg>';
19326
19332
  try {
19327
19333
  const s = await this.pdfDoc.getPage(i);
19328
19334
  let c = 1;