@pixldocs/canvas-renderer 0.5.27 → 0.5.29
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 +120 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +120 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2571,6 +2571,10 @@ async function _doLoadGoogleFont(fontFamily, weights) {
|
|
|
2571
2571
|
return false;
|
|
2572
2572
|
}
|
|
2573
2573
|
}
|
|
2574
|
+
const getObjectId = (obj) => obj.__docuforgeId;
|
|
2575
|
+
const setObjectData = (obj, id) => {
|
|
2576
|
+
obj.__docuforgeId = id;
|
|
2577
|
+
};
|
|
2574
2578
|
const FONTS_TO_PRELOAD = [
|
|
2575
2579
|
"Open Sans",
|
|
2576
2580
|
"Playfair Display",
|
|
@@ -2710,6 +2714,42 @@ const clearFabricCharCache = () => {
|
|
|
2710
2714
|
};
|
|
2711
2715
|
const clearFontCacheAndRerender = (canvas) => {
|
|
2712
2716
|
clearFabricCharCache();
|
|
2717
|
+
const logUnderlineDebug = (stage, payload) => {
|
|
2718
|
+
try {
|
|
2719
|
+
console.log(`[canvas-renderer][underline-debug] ${stage} ${JSON.stringify(payload)}`);
|
|
2720
|
+
} catch {
|
|
2721
|
+
console.log("[canvas-renderer][underline-debug]", stage, payload);
|
|
2722
|
+
}
|
|
2723
|
+
};
|
|
2724
|
+
const collectUnderlineMetrics = (obj) => {
|
|
2725
|
+
var _a, _b;
|
|
2726
|
+
if (obj instanceof fabric.Textbox) {
|
|
2727
|
+
if (!obj.underline) return [];
|
|
2728
|
+
const lineWidths = obj.__lineWidths;
|
|
2729
|
+
return [{
|
|
2730
|
+
id: getObjectId(obj) ?? null,
|
|
2731
|
+
text: (obj.text || "").slice(0, 120),
|
|
2732
|
+
textLength: ((_a = obj.text) == null ? void 0 : _a.length) ?? 0,
|
|
2733
|
+
fontFamily: obj.fontFamily,
|
|
2734
|
+
fontSize: obj.fontSize,
|
|
2735
|
+
fontWeight: obj.fontWeight,
|
|
2736
|
+
width: obj.width ?? null,
|
|
2737
|
+
height: obj.height ?? null,
|
|
2738
|
+
scaleX: obj.scaleX,
|
|
2739
|
+
scaleY: obj.scaleY,
|
|
2740
|
+
lineCount: ((_b = obj.textLines) == null ? void 0 : _b.length) ?? 0,
|
|
2741
|
+
maxLineWidth: lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : null
|
|
2742
|
+
}];
|
|
2743
|
+
}
|
|
2744
|
+
if (obj instanceof fabric.Group) {
|
|
2745
|
+
return (obj._objects || []).flatMap((child) => collectUnderlineMetrics(child));
|
|
2746
|
+
}
|
|
2747
|
+
return [];
|
|
2748
|
+
};
|
|
2749
|
+
const beforeMetrics = canvas.getObjects().flatMap(collectUnderlineMetrics);
|
|
2750
|
+
if (beforeMetrics.length > 0) {
|
|
2751
|
+
logUnderlineDebug("before-rerender", beforeMetrics);
|
|
2752
|
+
}
|
|
2713
2753
|
const resetTextboxLayoutInternals = (obj) => {
|
|
2714
2754
|
var _a;
|
|
2715
2755
|
(_a = obj._clearCache) == null ? void 0 : _a.call(obj);
|
|
@@ -2724,7 +2764,7 @@ const clearFontCacheAndRerender = (canvas) => {
|
|
|
2724
2764
|
obj.dirty = true;
|
|
2725
2765
|
};
|
|
2726
2766
|
const fixTextbox = (obj) => {
|
|
2727
|
-
var _a, _b;
|
|
2767
|
+
var _a, _b, _c;
|
|
2728
2768
|
if (obj instanceof fabric.Textbox) {
|
|
2729
2769
|
const savedWidth = obj.width;
|
|
2730
2770
|
const savedScaleX = obj.scaleX;
|
|
@@ -2737,15 +2777,35 @@ const clearFontCacheAndRerender = (canvas) => {
|
|
|
2737
2777
|
obj.initDimensions();
|
|
2738
2778
|
obj.set({ width: savedWidth, scaleX: savedScaleX, scaleY: savedScaleY, dirty: true });
|
|
2739
2779
|
}
|
|
2740
|
-
(
|
|
2780
|
+
if (obj.underline) {
|
|
2781
|
+
const lineWidths = obj.__lineWidths;
|
|
2782
|
+
logUnderlineDebug("textbox-rerender", {
|
|
2783
|
+
id: getObjectId(obj) ?? null,
|
|
2784
|
+
text: (obj.text || "").slice(0, 120),
|
|
2785
|
+
fontFamily: obj.fontFamily,
|
|
2786
|
+
fontSize: obj.fontSize,
|
|
2787
|
+
savedWidth,
|
|
2788
|
+
finalWidth: obj.width ?? null,
|
|
2789
|
+
finalHeight: obj.height ?? null,
|
|
2790
|
+
scaleX: obj.scaleX,
|
|
2791
|
+
scaleY: obj.scaleY,
|
|
2792
|
+
lineCount: ((_a = obj.textLines) == null ? void 0 : _a.length) ?? 0,
|
|
2793
|
+
maxLineWidth: lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : null
|
|
2794
|
+
});
|
|
2795
|
+
}
|
|
2796
|
+
(_b = obj._clearCache) == null ? void 0 : _b.call(obj);
|
|
2741
2797
|
obj.setCoords();
|
|
2742
2798
|
} else if (obj instanceof fabric.Group) {
|
|
2743
|
-
(
|
|
2799
|
+
(_c = obj._objects) == null ? void 0 : _c.forEach(fixTextbox);
|
|
2744
2800
|
obj.dirty = true;
|
|
2745
2801
|
obj.setCoords();
|
|
2746
2802
|
}
|
|
2747
2803
|
};
|
|
2748
2804
|
canvas.getObjects().forEach(fixTextbox);
|
|
2805
|
+
const afterMetrics = canvas.getObjects().flatMap(collectUnderlineMetrics);
|
|
2806
|
+
if (afterMetrics.length > 0) {
|
|
2807
|
+
logUnderlineDebug("after-rerender", afterMetrics);
|
|
2808
|
+
}
|
|
2749
2809
|
canvas.requestRenderAll();
|
|
2750
2810
|
};
|
|
2751
2811
|
const ensureFontLoaded = async (fontFamily) => {
|
|
@@ -2783,10 +2843,6 @@ const setupFontLoadingListener = (canvas, afterRerender) => {
|
|
|
2783
2843
|
};
|
|
2784
2844
|
};
|
|
2785
2845
|
preloadAllFonts();
|
|
2786
|
-
const getObjectId = (obj) => obj.__docuforgeId;
|
|
2787
|
-
const setObjectData = (obj, id) => {
|
|
2788
|
-
obj.__docuforgeId = id;
|
|
2789
|
-
};
|
|
2790
2846
|
const svgTextCache = /* @__PURE__ */ new Map();
|
|
2791
2847
|
const htmlImageCache = /* @__PURE__ */ new Map();
|
|
2792
2848
|
const MAX_CACHE_ENTRIES = 200;
|
|
@@ -11844,6 +11900,21 @@ async function ensureFontsForResolvedConfig(config) {
|
|
|
11844
11900
|
});
|
|
11845
11901
|
}
|
|
11846
11902
|
}
|
|
11903
|
+
const PREVIEW_DEBUG_PREFIX = "[canvas-renderer][preview-debug]";
|
|
11904
|
+
function countUnderlinedNodes(config) {
|
|
11905
|
+
var _a;
|
|
11906
|
+
if (!((_a = config == null ? void 0 : config.pages) == null ? void 0 : _a.length)) return 0;
|
|
11907
|
+
let count = 0;
|
|
11908
|
+
const walk = (nodes) => {
|
|
11909
|
+
var _a2;
|
|
11910
|
+
for (const node of nodes || []) {
|
|
11911
|
+
if (node == null ? void 0 : node.underline) count += 1;
|
|
11912
|
+
if ((_a2 = node == null ? void 0 : node.children) == null ? void 0 : _a2.length) walk(node.children);
|
|
11913
|
+
}
|
|
11914
|
+
};
|
|
11915
|
+
for (const page of config.pages) walk(page.children || []);
|
|
11916
|
+
return count;
|
|
11917
|
+
}
|
|
11847
11918
|
function PixldocsPreview(props) {
|
|
11848
11919
|
const {
|
|
11849
11920
|
pageIndex = 0,
|
|
@@ -11871,6 +11942,7 @@ function PixldocsPreview(props) {
|
|
|
11871
11942
|
if (!isResolveMode) {
|
|
11872
11943
|
setResolvedConfig(null);
|
|
11873
11944
|
setCanvasSettled(false);
|
|
11945
|
+
console.log(PREVIEW_DEBUG_PREFIX, "config-mode active");
|
|
11874
11946
|
return;
|
|
11875
11947
|
}
|
|
11876
11948
|
const p = props;
|
|
@@ -11879,6 +11951,12 @@ function PixldocsPreview(props) {
|
|
|
11879
11951
|
setIsLoading(true);
|
|
11880
11952
|
setFontsReady(false);
|
|
11881
11953
|
setCanvasSettled(false);
|
|
11954
|
+
console.log(PREVIEW_DEBUG_PREFIX, "resolve-start", {
|
|
11955
|
+
templateId: p.templateId,
|
|
11956
|
+
formSchemaId: p.formSchemaId,
|
|
11957
|
+
themeId: p.themeId ?? null,
|
|
11958
|
+
pageIndex
|
|
11959
|
+
});
|
|
11882
11960
|
resolveFromForm({
|
|
11883
11961
|
templateId: p.templateId,
|
|
11884
11962
|
formSchemaId: p.formSchemaId,
|
|
@@ -11887,15 +11965,22 @@ function PixldocsPreview(props) {
|
|
|
11887
11965
|
supabaseUrl: p.supabaseUrl,
|
|
11888
11966
|
supabaseAnonKey: p.supabaseAnonKey
|
|
11889
11967
|
}).then((resolved) => {
|
|
11968
|
+
var _a, _b;
|
|
11890
11969
|
if (!cancelled) {
|
|
11970
|
+
console.log(PREVIEW_DEBUG_PREFIX, "resolve-done", {
|
|
11971
|
+
pages: ((_b = (_a = resolved.config) == null ? void 0 : _a.pages) == null ? void 0 : _b.length) ?? 0,
|
|
11972
|
+
underlinedNodes: countUnderlinedNodes(resolved.config)
|
|
11973
|
+
});
|
|
11891
11974
|
setResolvedConfig(resolved.config);
|
|
11892
11975
|
ensureFontsForResolvedConfig(resolved.config).then(() => {
|
|
11893
11976
|
if (!cancelled) {
|
|
11977
|
+
console.log(PREVIEW_DEBUG_PREFIX, "resolve-mode fonts queued");
|
|
11894
11978
|
setFontsReady(true);
|
|
11895
11979
|
setIsLoading(false);
|
|
11896
11980
|
}
|
|
11897
|
-
}).catch(() => {
|
|
11981
|
+
}).catch((err) => {
|
|
11898
11982
|
if (!cancelled) {
|
|
11983
|
+
console.warn(PREVIEW_DEBUG_PREFIX, "resolve-mode fonts queue failed", err);
|
|
11899
11984
|
setFontsReady(true);
|
|
11900
11985
|
setIsLoading(false);
|
|
11901
11986
|
}
|
|
@@ -11904,6 +11989,7 @@ function PixldocsPreview(props) {
|
|
|
11904
11989
|
}).catch((err) => {
|
|
11905
11990
|
if (!cancelled) {
|
|
11906
11991
|
setIsLoading(false);
|
|
11992
|
+
console.warn(PREVIEW_DEBUG_PREFIX, "resolve-error", err);
|
|
11907
11993
|
onError == null ? void 0 : onError(err instanceof Error ? err : new Error(String(err)));
|
|
11908
11994
|
}
|
|
11909
11995
|
});
|
|
@@ -11920,18 +12006,28 @@ function PixldocsPreview(props) {
|
|
|
11920
12006
|
]);
|
|
11921
12007
|
const config = isResolveMode ? resolvedConfig : props.config;
|
|
11922
12008
|
useEffect(() => {
|
|
11923
|
-
var _a, _b;
|
|
12009
|
+
var _a, _b, _c;
|
|
11924
12010
|
if (!config) return;
|
|
11925
12011
|
let cancelled = false;
|
|
11926
12012
|
setCanvasSettled(false);
|
|
11927
12013
|
setStabilizationPass(0);
|
|
12014
|
+
console.log(PREVIEW_DEBUG_PREFIX, "config-changed", {
|
|
12015
|
+
pageIndex,
|
|
12016
|
+
pages: ((_a = config.pages) == null ? void 0 : _a.length) ?? 0,
|
|
12017
|
+
underlinedNodes: countUnderlinedNodes(config),
|
|
12018
|
+
isResolveMode
|
|
12019
|
+
});
|
|
11928
12020
|
const bump = () => {
|
|
11929
12021
|
if (cancelled) return;
|
|
11930
12022
|
clearMeasurementCache();
|
|
11931
12023
|
clearFabricCharCache();
|
|
11932
|
-
setFontsReadyVersion((v) =>
|
|
12024
|
+
setFontsReadyVersion((v) => {
|
|
12025
|
+
const next = v + 1;
|
|
12026
|
+
console.log(PREVIEW_DEBUG_PREFIX, "font-bump", { pageIndex, next, stabilizationPass });
|
|
12027
|
+
return next;
|
|
12028
|
+
});
|
|
11933
12029
|
};
|
|
11934
|
-
(
|
|
12030
|
+
(_c = (_b = document.fonts) == null ? void 0 : _b.ready) == null ? void 0 : _c.then(bump);
|
|
11935
12031
|
const timeoutId = window.setTimeout(bump, 350);
|
|
11936
12032
|
return () => {
|
|
11937
12033
|
cancelled = true;
|
|
@@ -11953,17 +12049,28 @@ function PixldocsPreview(props) {
|
|
|
11953
12049
|
setFontsReady(false);
|
|
11954
12050
|
setCanvasSettled(false);
|
|
11955
12051
|
setStabilizationPass(0);
|
|
11956
|
-
ensureFontsForResolvedConfig(config).then(() =>
|
|
12052
|
+
ensureFontsForResolvedConfig(config).then(() => {
|
|
12053
|
+
console.log(PREVIEW_DEBUG_PREFIX, "config-mode fonts queued", {
|
|
12054
|
+
pageIndex,
|
|
12055
|
+
underlinedNodes: countUnderlinedNodes(config)
|
|
12056
|
+
});
|
|
12057
|
+
setFontsReady(true);
|
|
12058
|
+
}).catch((err) => {
|
|
12059
|
+
console.warn(PREVIEW_DEBUG_PREFIX, "config-mode fonts queue failed", err);
|
|
12060
|
+
setFontsReady(true);
|
|
12061
|
+
});
|
|
11957
12062
|
}, [isResolveMode, config]);
|
|
11958
12063
|
const handleCanvasReady = useCallback(() => {
|
|
11959
12064
|
if (stabilizationPass === 0) {
|
|
12065
|
+
console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready-pass", { pageIndex, stabilizationPass, action: "stabilize-again" });
|
|
11960
12066
|
setCanvasSettled(false);
|
|
11961
12067
|
setStabilizationPass(1);
|
|
11962
12068
|
return;
|
|
11963
12069
|
}
|
|
12070
|
+
console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready-pass", { pageIndex, stabilizationPass, action: "settled" });
|
|
11964
12071
|
setCanvasSettled(true);
|
|
11965
12072
|
onReady == null ? void 0 : onReady();
|
|
11966
|
-
}, [onReady, stabilizationPass]);
|
|
12073
|
+
}, [onReady, pageIndex, stabilizationPass]);
|
|
11967
12074
|
if (isLoading) {
|
|
11968
12075
|
return /* @__PURE__ */ jsx("div", { className, style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) });
|
|
11969
12076
|
}
|