@pixldocs/canvas-renderer 0.5.15 → 0.5.17
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.cjs +70 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +70 -40
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2703,12 +2703,10 @@ const waitForFontsReady = async () => {
|
|
|
2703
2703
|
if (!document.fonts) return;
|
|
2704
2704
|
await withFontTimeout(document.fonts.ready, 2500);
|
|
2705
2705
|
};
|
|
2706
|
-
const DEFAULT_FONT_CHECK_TIMEOUT_MS = 3500;
|
|
2707
|
-
const FONT_CHECK_POLL_MS = 60;
|
|
2708
2706
|
const waitUntilFontsAvailable = async (fontFamilies, options) => {
|
|
2709
2707
|
if (!document.fonts || fontFamilies.length === 0) return;
|
|
2710
|
-
const timeoutMs =
|
|
2711
|
-
const pollMs =
|
|
2708
|
+
const timeoutMs = options == null ? void 0 : options.timeoutMs;
|
|
2709
|
+
const pollMs = options == null ? void 0 : options.pollIntervalMs;
|
|
2712
2710
|
const deadline = Date.now() + timeoutMs;
|
|
2713
2711
|
const check = () => fontFamilies.every(
|
|
2714
2712
|
(f) => document.fonts.check(`16px "${f}"`) && document.fonts.check(`bold 16px "${f}"`)
|
|
@@ -11707,18 +11705,16 @@ function normalizeFontFamily(fontStack) {
|
|
|
11707
11705
|
}
|
|
11708
11706
|
const loadedFonts = /* @__PURE__ */ new Set();
|
|
11709
11707
|
const loadingPromises = /* @__PURE__ */ new Map();
|
|
11710
|
-
|
|
11708
|
+
function withTimeout(promise, timeoutMs = 4e3) {
|
|
11711
11709
|
let timeoutId;
|
|
11712
|
-
|
|
11713
|
-
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
]);
|
|
11719
|
-
} finally {
|
|
11710
|
+
return Promise.race([
|
|
11711
|
+
promise,
|
|
11712
|
+
new Promise((resolve) => {
|
|
11713
|
+
timeoutId = setTimeout(resolve, timeoutMs);
|
|
11714
|
+
})
|
|
11715
|
+
]).finally(() => {
|
|
11720
11716
|
if (timeoutId) clearTimeout(timeoutId);
|
|
11721
|
-
}
|
|
11717
|
+
});
|
|
11722
11718
|
}
|
|
11723
11719
|
async function loadGoogleFontCSS(rawFontFamily) {
|
|
11724
11720
|
if (!rawFontFamily || typeof document === "undefined") return;
|
|
@@ -11740,10 +11736,6 @@ async function loadGoogleFontCSS(rawFontFamily) {
|
|
|
11740
11736
|
link.onerror = () => reject(new Error(`Failed to load font: ${fontFamily}`));
|
|
11741
11737
|
document.head.appendChild(link);
|
|
11742
11738
|
});
|
|
11743
|
-
if (document.fonts) {
|
|
11744
|
-
await withTimeout(document.fonts.load(`16px "${fontFamily}"`), 2500);
|
|
11745
|
-
await withTimeout(document.fonts.ready, 2500);
|
|
11746
|
-
}
|
|
11747
11739
|
loadedFonts.add(fontFamily);
|
|
11748
11740
|
} catch (e) {
|
|
11749
11741
|
console.warn(`[@pixldocs/canvas-renderer] Font load failed: ${fontFamily}`, e);
|
|
@@ -11855,17 +11847,15 @@ async function ensureFontsForResolvedConfig(config) {
|
|
|
11855
11847
|
if (typeof document === "undefined") return;
|
|
11856
11848
|
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
11857
11849
|
const families = new Set(descriptors.map((d) => d.family));
|
|
11858
|
-
|
|
11850
|
+
void withTimeout(Promise.all([...families].map((f) => loadGoogleFontCSS(f))), 2500);
|
|
11859
11851
|
if (document.fonts) {
|
|
11860
|
-
|
|
11852
|
+
descriptors.forEach((d) => {
|
|
11861
11853
|
const stylePrefix = d.style === "italic" ? "italic " : "";
|
|
11862
11854
|
const weightStr = String(d.weight);
|
|
11863
11855
|
const spec = `${stylePrefix}${weightStr} 16px "${d.family}"`;
|
|
11864
|
-
|
|
11856
|
+
document.fonts.load(spec).catch(() => {
|
|
11865
11857
|
});
|
|
11866
11858
|
});
|
|
11867
|
-
await withTimeout(Promise.all(loadPromises), 8e3);
|
|
11868
|
-
await withTimeout(document.fonts.ready, 2500);
|
|
11869
11859
|
}
|
|
11870
11860
|
}
|
|
11871
11861
|
function PixldocsPreview(props) {
|
|
@@ -12310,6 +12300,49 @@ class PixldocsRenderer {
|
|
|
12310
12300
|
setTimeout(check, 0);
|
|
12311
12301
|
});
|
|
12312
12302
|
}
|
|
12303
|
+
waitForCanvasScene(container, config, pageIndex, maxWaitMs = 8e3, pollMs = 50) {
|
|
12304
|
+
return new Promise((resolve) => {
|
|
12305
|
+
var _a, _b;
|
|
12306
|
+
const start = Date.now();
|
|
12307
|
+
const pageHasContent = (((_b = (_a = config.pages[pageIndex]) == null ? void 0 : _a.children) == null ? void 0 : _b.length) ?? 0) > 0;
|
|
12308
|
+
const settle = () => requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
|
|
12309
|
+
const check = () => {
|
|
12310
|
+
const fabricCanvas = this.getFabricCanvasFromContainer(container);
|
|
12311
|
+
const lowerCanvas = (fabricCanvas == null ? void 0 : fabricCanvas.lowerCanvasEl) || container.querySelector("canvas.lower-canvas, canvas");
|
|
12312
|
+
const objectCount = typeof (fabricCanvas == null ? void 0 : fabricCanvas.getObjects) === "function" ? fabricCanvas.getObjects().length : 0;
|
|
12313
|
+
const ready = !!lowerCanvas && (!pageHasContent || objectCount > 0);
|
|
12314
|
+
if (ready) {
|
|
12315
|
+
console.log(`[canvas-renderer][scene-wait] ready after ${Date.now() - start}ms (objects=${objectCount})`);
|
|
12316
|
+
settle();
|
|
12317
|
+
return;
|
|
12318
|
+
}
|
|
12319
|
+
if (Date.now() - start >= maxWaitMs) {
|
|
12320
|
+
console.warn(`[canvas-renderer][scene-wait-timeout] elapsed=${Date.now() - start}ms objects=${objectCount} pageHasContent=${pageHasContent}`);
|
|
12321
|
+
settle();
|
|
12322
|
+
return;
|
|
12323
|
+
}
|
|
12324
|
+
setTimeout(check, pollMs);
|
|
12325
|
+
};
|
|
12326
|
+
setTimeout(check, 0);
|
|
12327
|
+
});
|
|
12328
|
+
}
|
|
12329
|
+
async waitForRelevantFonts(config, maxWaitMs = 1800) {
|
|
12330
|
+
if (typeof document === "undefined" || !document.fonts) return;
|
|
12331
|
+
const descriptors = collectFontDescriptorsFromConfig(config);
|
|
12332
|
+
if (descriptors.length === 0) return;
|
|
12333
|
+
const loads = Promise.all(
|
|
12334
|
+
descriptors.map((descriptor) => {
|
|
12335
|
+
const stylePrefix = descriptor.style === "italic" ? "italic " : "";
|
|
12336
|
+
const spec = `${stylePrefix}${descriptor.weight} 16px "${descriptor.family}"`;
|
|
12337
|
+
return document.fonts.load(spec).catch(() => []);
|
|
12338
|
+
})
|
|
12339
|
+
).then(() => void 0);
|
|
12340
|
+
await Promise.race([
|
|
12341
|
+
loads,
|
|
12342
|
+
new Promise((resolve) => setTimeout(resolve, maxWaitMs))
|
|
12343
|
+
]);
|
|
12344
|
+
await new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve())));
|
|
12345
|
+
}
|
|
12313
12346
|
getNormalizedGradientStops(gradient) {
|
|
12314
12347
|
const stops = Array.isArray(gradient == null ? void 0 : gradient.stops) ? gradient.stops.map((stop) => ({
|
|
12315
12348
|
offset: Math.max(0, Math.min(1, Number((stop == null ? void 0 : stop.offset) ?? 0))),
|
|
@@ -12422,10 +12455,11 @@ class PixldocsRenderer {
|
|
|
12422
12455
|
);
|
|
12423
12456
|
return;
|
|
12424
12457
|
}
|
|
12425
|
-
|
|
12426
|
-
this.waitForCanvasImages(container, expectedImageCount).then(async () => {
|
|
12458
|
+
this.waitForCanvasScene(container, config, pageIndex).then(async () => {
|
|
12427
12459
|
try {
|
|
12428
12460
|
const fabricInstance = this.getFabricCanvasFromContainer(container);
|
|
12461
|
+
const expectedImageCount = this.getExpectedImageCount(config, pageIndex);
|
|
12462
|
+
await this.waitForCanvasImages(container, expectedImageCount);
|
|
12429
12463
|
await this.waitForStableTextMetrics(container, config);
|
|
12430
12464
|
const fabricCanvas = container.querySelector("canvas.upper-canvas, canvas");
|
|
12431
12465
|
const sourceCanvas = (fabricInstance == null ? void 0 : fabricInstance.lowerCanvasEl) || container.querySelector("canvas.lower-canvas") || fabricCanvas;
|
|
@@ -12516,8 +12550,7 @@ class PixldocsRenderer {
|
|
|
12516
12550
|
);
|
|
12517
12551
|
return;
|
|
12518
12552
|
}
|
|
12519
|
-
|
|
12520
|
-
this.waitForCanvasImages(container, expectedImageCount).then(async () => {
|
|
12553
|
+
this.waitForCanvasScene(container, config, pageIndex).then(async () => {
|
|
12521
12554
|
var _a, _b;
|
|
12522
12555
|
try {
|
|
12523
12556
|
const fabricInstance = this.getFabricCanvasFromContainer(container);
|
|
@@ -12526,6 +12559,8 @@ class PixldocsRenderer {
|
|
|
12526
12559
|
reject(new Error("No Fabric canvas instance found for SVG capture"));
|
|
12527
12560
|
return;
|
|
12528
12561
|
}
|
|
12562
|
+
const expectedImageCount = this.getExpectedImageCount(config, pageIndex);
|
|
12563
|
+
await this.waitForCanvasImages(container, expectedImageCount);
|
|
12529
12564
|
await this.waitForStableTextMetrics(container, config);
|
|
12530
12565
|
const prevVPT = fabricInstance.viewportTransform ? [...fabricInstance.viewportTransform] : void 0;
|
|
12531
12566
|
const prevSvgVPT = fabricInstance.svgViewportTransformation;
|
|
@@ -12649,14 +12684,9 @@ class PixldocsRenderer {
|
|
|
12649
12684
|
return null;
|
|
12650
12685
|
}
|
|
12651
12686
|
async waitForStableTextMetrics(container, config) {
|
|
12652
|
-
var _a;
|
|
12653
12687
|
if (typeof document !== "undefined") {
|
|
12654
|
-
|
|
12655
|
-
await (
|
|
12656
|
-
const fontFamilies = [...collectFontsFromConfig(config)].filter(Boolean);
|
|
12657
|
-
if (fontFamilies.length > 0) {
|
|
12658
|
-
await waitUntilFontsAvailable(fontFamilies, { timeoutMs: 4e3, pollIntervalMs: 50 });
|
|
12659
|
-
}
|
|
12688
|
+
void ensureFontsForResolvedConfig(config);
|
|
12689
|
+
await this.waitForRelevantFonts(config);
|
|
12660
12690
|
}
|
|
12661
12691
|
const fabricInstance = this.getFabricCanvasFromContainer(container);
|
|
12662
12692
|
if (!(fabricInstance == null ? void 0 : fabricInstance.getObjects)) return;
|
|
@@ -12666,9 +12696,9 @@ class PixldocsRenderer {
|
|
|
12666
12696
|
clearMeasurementCache();
|
|
12667
12697
|
};
|
|
12668
12698
|
const reflowTextboxes = () => {
|
|
12669
|
-
var
|
|
12699
|
+
var _a, _b, _c;
|
|
12670
12700
|
const walk = (obj) => {
|
|
12671
|
-
var
|
|
12701
|
+
var _a2, _b2, _c2, _d;
|
|
12672
12702
|
if (!obj) return;
|
|
12673
12703
|
const children = Array.isArray(obj._objects) ? obj._objects : Array.isArray(obj.objects) ? obj.objects : [];
|
|
12674
12704
|
if (children.length) children.forEach(walk);
|
|
@@ -12680,8 +12710,8 @@ class PixldocsRenderer {
|
|
|
12680
12710
|
scaleY: obj.scaleY
|
|
12681
12711
|
};
|
|
12682
12712
|
const resetTextboxLayoutInternals = () => {
|
|
12683
|
-
var
|
|
12684
|
-
(
|
|
12713
|
+
var _a3;
|
|
12714
|
+
(_a3 = obj._clearCache) == null ? void 0 : _a3.call(obj);
|
|
12685
12715
|
obj.__charBounds = [];
|
|
12686
12716
|
obj.__lineWidths = [];
|
|
12687
12717
|
obj.__lineHeights = [];
|
|
@@ -12695,7 +12725,7 @@ class PixldocsRenderer {
|
|
|
12695
12725
|
resetTextboxLayoutInternals();
|
|
12696
12726
|
obj.initDimensions();
|
|
12697
12727
|
if (saved.width != null) {
|
|
12698
|
-
(
|
|
12728
|
+
(_a2 = obj.set) == null ? void 0 : _a2.call(obj, {
|
|
12699
12729
|
width: saved.width,
|
|
12700
12730
|
scaleX: saved.scaleX,
|
|
12701
12731
|
scaleY: saved.scaleY
|
|
@@ -12714,7 +12744,7 @@ class PixldocsRenderer {
|
|
|
12714
12744
|
}
|
|
12715
12745
|
};
|
|
12716
12746
|
fabricInstance.getObjects().forEach(walk);
|
|
12717
|
-
(
|
|
12747
|
+
(_a = fabricInstance.calcOffset) == null ? void 0 : _a.call(fabricInstance);
|
|
12718
12748
|
(_b = fabricInstance.renderAll) == null ? void 0 : _b.call(fabricInstance);
|
|
12719
12749
|
(_c = fabricInstance.requestRenderAll) == null ? void 0 : _c.call(fabricInstance);
|
|
12720
12750
|
};
|