@pixldocs/canvas-renderer 0.5.16 → 0.5.18

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/dist/index.d.ts CHANGED
@@ -369,6 +369,8 @@ export declare class PixldocsRenderer {
369
369
  renderAllById(templateId: string, formData?: Record<string, any>, options?: Omit<RenderOptions, 'pageIndex'>): Promise<RenderResult[]>;
370
370
  private getExpectedImageCount;
371
371
  private waitForCanvasImages;
372
+ private waitForCanvasScene;
373
+ private waitForRelevantFonts;
372
374
  private getNormalizedGradientStops;
373
375
  private paintPageBackground;
374
376
  private renderPageViaPreviewCanvas;
package/dist/index.js CHANGED
@@ -5670,6 +5670,7 @@ const PageCanvas = forwardRef(
5670
5670
  onDynamicFieldClick,
5671
5671
  canvasUpdateVersion = 0,
5672
5672
  pageChildren,
5673
+ skipFontReadyWait = false,
5673
5674
  onReady
5674
5675
  }, ref) => {
5675
5676
  const isEditorMode = mode === "editor";
@@ -5955,9 +5956,11 @@ const PageCanvas = forwardRef(
5955
5956
  await Promise.all(fontFamilies.map((f) => ensureFontLoaded(f)));
5956
5957
  }
5957
5958
  }
5958
- await waitForFontsReady();
5959
- await waitUntilFontsAvailable(fontFamilies, { timeoutMs: 3500, pollIntervalMs: 60 });
5960
- await new Promise((r) => requestAnimationFrame(() => r()));
5959
+ if (!skipFontReadyWait) {
5960
+ await waitForFontsReady();
5961
+ await waitUntilFontsAvailable(fontFamilies, { timeoutMs: 3500, pollIntervalMs: 60 });
5962
+ await new Promise((r) => requestAnimationFrame(() => r()));
5963
+ }
5961
5964
  clearFabricCharCache();
5962
5965
  clearMeasurementCache();
5963
5966
  setReady(true);
@@ -9394,6 +9397,7 @@ function PreviewCanvas({
9394
9397
  pageIndex = 0,
9395
9398
  zoom = 1,
9396
9399
  absoluteZoom = false,
9400
+ skipFontReadyWait = false,
9397
9401
  className,
9398
9402
  onDynamicFieldClick,
9399
9403
  onReady
@@ -9548,6 +9552,7 @@ function PreviewCanvas({
9548
9552
  selectedIds: [],
9549
9553
  activeTool: "select",
9550
9554
  mode: "preview",
9555
+ skipFontReadyWait,
9551
9556
  dynamicFieldIds,
9552
9557
  onDynamicFieldClick: handleDynamicFieldClick,
9553
9558
  onReady
@@ -12281,6 +12286,49 @@ class PixldocsRenderer {
12281
12286
  setTimeout(check, 0);
12282
12287
  });
12283
12288
  }
12289
+ waitForCanvasScene(container, config, pageIndex, maxWaitMs = 8e3, pollMs = 50) {
12290
+ return new Promise((resolve) => {
12291
+ var _a, _b;
12292
+ const start = Date.now();
12293
+ const pageHasContent = (((_b = (_a = config.pages[pageIndex]) == null ? void 0 : _a.children) == null ? void 0 : _b.length) ?? 0) > 0;
12294
+ const settle = () => requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
12295
+ const check = () => {
12296
+ const fabricCanvas = this.getFabricCanvasFromContainer(container);
12297
+ const lowerCanvas = (fabricCanvas == null ? void 0 : fabricCanvas.lowerCanvasEl) || container.querySelector("canvas.lower-canvas, canvas");
12298
+ const objectCount = typeof (fabricCanvas == null ? void 0 : fabricCanvas.getObjects) === "function" ? fabricCanvas.getObjects().length : 0;
12299
+ const ready = !!lowerCanvas && (!pageHasContent || objectCount > 0);
12300
+ if (ready) {
12301
+ console.log(`[canvas-renderer][scene-wait] ready after ${Date.now() - start}ms (objects=${objectCount})`);
12302
+ settle();
12303
+ return;
12304
+ }
12305
+ if (Date.now() - start >= maxWaitMs) {
12306
+ console.warn(`[canvas-renderer][scene-wait-timeout] elapsed=${Date.now() - start}ms objects=${objectCount} pageHasContent=${pageHasContent}`);
12307
+ settle();
12308
+ return;
12309
+ }
12310
+ setTimeout(check, pollMs);
12311
+ };
12312
+ setTimeout(check, 0);
12313
+ });
12314
+ }
12315
+ async waitForRelevantFonts(config, maxWaitMs = 1800) {
12316
+ if (typeof document === "undefined" || !document.fonts) return;
12317
+ const descriptors = collectFontDescriptorsFromConfig(config);
12318
+ if (descriptors.length === 0) return;
12319
+ const loads = Promise.all(
12320
+ descriptors.map((descriptor) => {
12321
+ const stylePrefix = descriptor.style === "italic" ? "italic " : "";
12322
+ const spec = `${stylePrefix}${descriptor.weight} 16px "${descriptor.family}"`;
12323
+ return document.fonts.load(spec).catch(() => []);
12324
+ })
12325
+ ).then(() => void 0);
12326
+ await Promise.race([
12327
+ loads,
12328
+ new Promise((resolve) => setTimeout(resolve, maxWaitMs))
12329
+ ]);
12330
+ await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve())));
12331
+ }
12284
12332
  getNormalizedGradientStops(gradient) {
12285
12333
  const stops = Array.isArray(gradient == null ? void 0 : gradient.stops) ? gradient.stops.map((stop) => ({
12286
12334
  offset: Math.max(0, Math.min(1, Number((stop == null ? void 0 : stop.offset) ?? 0))),
@@ -12388,16 +12436,17 @@ class PixldocsRenderer {
12388
12436
  pageIndex,
12389
12437
  zoom: pixelRatio,
12390
12438
  absoluteZoom: true,
12439
+ skipFontReadyWait: true,
12391
12440
  onReady
12392
12441
  })
12393
12442
  );
12394
12443
  return;
12395
12444
  }
12396
- const expectedImageCount = this.getExpectedImageCount(config, pageIndex);
12397
- this.waitForCanvasImages(container, expectedImageCount).then(async () => {
12445
+ this.waitForCanvasScene(container, config, pageIndex).then(async () => {
12398
12446
  try {
12399
12447
  const fabricInstance = this.getFabricCanvasFromContainer(container);
12400
- await this.waitForStableTextMetrics(container, config);
12448
+ const expectedImageCount = this.getExpectedImageCount(config, pageIndex);
12449
+ await this.waitForCanvasImages(container, expectedImageCount);
12401
12450
  const fabricCanvas = container.querySelector("canvas.upper-canvas, canvas");
12402
12451
  const sourceCanvas = (fabricInstance == null ? void 0 : fabricInstance.lowerCanvasEl) || container.querySelector("canvas.lower-canvas") || fabricCanvas;
12403
12452
  if (!sourceCanvas) {
@@ -12436,6 +12485,7 @@ class PixldocsRenderer {
12436
12485
  pageIndex,
12437
12486
  zoom: pixelRatio,
12438
12487
  absoluteZoom: true,
12488
+ skipFontReadyWait: true,
12439
12489
  onReady
12440
12490
  })
12441
12491
  );
@@ -12482,13 +12532,13 @@ class PixldocsRenderer {
12482
12532
  pageIndex,
12483
12533
  zoom: 1,
12484
12534
  absoluteZoom: true,
12535
+ skipFontReadyWait: true,
12485
12536
  onReady
12486
12537
  })
12487
12538
  );
12488
12539
  return;
12489
12540
  }
12490
- const expectedImageCount = this.getExpectedImageCount(config, pageIndex);
12491
- this.waitForCanvasImages(container, expectedImageCount).then(async () => {
12541
+ this.waitForCanvasScene(container, config, pageIndex).then(async () => {
12492
12542
  var _a, _b;
12493
12543
  try {
12494
12544
  const fabricInstance = this.getFabricCanvasFromContainer(container);
@@ -12497,7 +12547,8 @@ class PixldocsRenderer {
12497
12547
  reject(new Error("No Fabric canvas instance found for SVG capture"));
12498
12548
  return;
12499
12549
  }
12500
- await this.waitForStableTextMetrics(container, config);
12550
+ const expectedImageCount = this.getExpectedImageCount(config, pageIndex);
12551
+ await this.waitForCanvasImages(container, expectedImageCount);
12501
12552
  const prevVPT = fabricInstance.viewportTransform ? [...fabricInstance.viewportTransform] : void 0;
12502
12553
  const prevSvgVPT = fabricInstance.svgViewportTransformation;
12503
12554
  const prevRetina = fabricInstance.enableRetinaScaling;
@@ -12548,6 +12599,7 @@ class PixldocsRenderer {
12548
12599
  zoom: 1,
12549
12600
  // 1:1 — no UI scaling for SVG capture
12550
12601
  absoluteZoom: true,
12602
+ skipFontReadyWait: true,
12551
12603
  onReady
12552
12604
  })
12553
12605
  );
@@ -12621,7 +12673,8 @@ class PixldocsRenderer {
12621
12673
  }
12622
12674
  async waitForStableTextMetrics(container, config) {
12623
12675
  if (typeof document !== "undefined") {
12624
- await ensureFontsForResolvedConfig(config);
12676
+ void ensureFontsForResolvedConfig(config);
12677
+ await this.waitForRelevantFonts(config);
12625
12678
  }
12626
12679
  const fabricInstance = this.getFabricCanvasFromContainer(container);
12627
12680
  if (!(fabricInstance == null ? void 0 : fabricInstance.getObjects)) return;