@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.cjs
CHANGED
|
@@ -2590,6 +2590,10 @@ async function _doLoadGoogleFont(fontFamily, weights) {
|
|
|
2590
2590
|
return false;
|
|
2591
2591
|
}
|
|
2592
2592
|
}
|
|
2593
|
+
const getObjectId = (obj) => obj.__docuforgeId;
|
|
2594
|
+
const setObjectData = (obj, id) => {
|
|
2595
|
+
obj.__docuforgeId = id;
|
|
2596
|
+
};
|
|
2593
2597
|
const FONTS_TO_PRELOAD = [
|
|
2594
2598
|
"Open Sans",
|
|
2595
2599
|
"Playfair Display",
|
|
@@ -2729,6 +2733,42 @@ const clearFabricCharCache = () => {
|
|
|
2729
2733
|
};
|
|
2730
2734
|
const clearFontCacheAndRerender = (canvas) => {
|
|
2731
2735
|
clearFabricCharCache();
|
|
2736
|
+
const logUnderlineDebug = (stage, payload) => {
|
|
2737
|
+
try {
|
|
2738
|
+
console.log(`[canvas-renderer][underline-debug] ${stage} ${JSON.stringify(payload)}`);
|
|
2739
|
+
} catch {
|
|
2740
|
+
console.log("[canvas-renderer][underline-debug]", stage, payload);
|
|
2741
|
+
}
|
|
2742
|
+
};
|
|
2743
|
+
const collectUnderlineMetrics = (obj) => {
|
|
2744
|
+
var _a, _b;
|
|
2745
|
+
if (obj instanceof fabric__namespace.Textbox) {
|
|
2746
|
+
if (!obj.underline) return [];
|
|
2747
|
+
const lineWidths = obj.__lineWidths;
|
|
2748
|
+
return [{
|
|
2749
|
+
id: getObjectId(obj) ?? null,
|
|
2750
|
+
text: (obj.text || "").slice(0, 120),
|
|
2751
|
+
textLength: ((_a = obj.text) == null ? void 0 : _a.length) ?? 0,
|
|
2752
|
+
fontFamily: obj.fontFamily,
|
|
2753
|
+
fontSize: obj.fontSize,
|
|
2754
|
+
fontWeight: obj.fontWeight,
|
|
2755
|
+
width: obj.width ?? null,
|
|
2756
|
+
height: obj.height ?? null,
|
|
2757
|
+
scaleX: obj.scaleX,
|
|
2758
|
+
scaleY: obj.scaleY,
|
|
2759
|
+
lineCount: ((_b = obj.textLines) == null ? void 0 : _b.length) ?? 0,
|
|
2760
|
+
maxLineWidth: lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : null
|
|
2761
|
+
}];
|
|
2762
|
+
}
|
|
2763
|
+
if (obj instanceof fabric__namespace.Group) {
|
|
2764
|
+
return (obj._objects || []).flatMap((child) => collectUnderlineMetrics(child));
|
|
2765
|
+
}
|
|
2766
|
+
return [];
|
|
2767
|
+
};
|
|
2768
|
+
const beforeMetrics = canvas.getObjects().flatMap(collectUnderlineMetrics);
|
|
2769
|
+
if (beforeMetrics.length > 0) {
|
|
2770
|
+
logUnderlineDebug("before-rerender", beforeMetrics);
|
|
2771
|
+
}
|
|
2732
2772
|
const resetTextboxLayoutInternals = (obj) => {
|
|
2733
2773
|
var _a;
|
|
2734
2774
|
(_a = obj._clearCache) == null ? void 0 : _a.call(obj);
|
|
@@ -2743,7 +2783,7 @@ const clearFontCacheAndRerender = (canvas) => {
|
|
|
2743
2783
|
obj.dirty = true;
|
|
2744
2784
|
};
|
|
2745
2785
|
const fixTextbox = (obj) => {
|
|
2746
|
-
var _a, _b;
|
|
2786
|
+
var _a, _b, _c;
|
|
2747
2787
|
if (obj instanceof fabric__namespace.Textbox) {
|
|
2748
2788
|
const savedWidth = obj.width;
|
|
2749
2789
|
const savedScaleX = obj.scaleX;
|
|
@@ -2756,15 +2796,35 @@ const clearFontCacheAndRerender = (canvas) => {
|
|
|
2756
2796
|
obj.initDimensions();
|
|
2757
2797
|
obj.set({ width: savedWidth, scaleX: savedScaleX, scaleY: savedScaleY, dirty: true });
|
|
2758
2798
|
}
|
|
2759
|
-
(
|
|
2799
|
+
if (obj.underline) {
|
|
2800
|
+
const lineWidths = obj.__lineWidths;
|
|
2801
|
+
logUnderlineDebug("textbox-rerender", {
|
|
2802
|
+
id: getObjectId(obj) ?? null,
|
|
2803
|
+
text: (obj.text || "").slice(0, 120),
|
|
2804
|
+
fontFamily: obj.fontFamily,
|
|
2805
|
+
fontSize: obj.fontSize,
|
|
2806
|
+
savedWidth,
|
|
2807
|
+
finalWidth: obj.width ?? null,
|
|
2808
|
+
finalHeight: obj.height ?? null,
|
|
2809
|
+
scaleX: obj.scaleX,
|
|
2810
|
+
scaleY: obj.scaleY,
|
|
2811
|
+
lineCount: ((_a = obj.textLines) == null ? void 0 : _a.length) ?? 0,
|
|
2812
|
+
maxLineWidth: lineWidths && lineWidths.length > 0 ? Math.max(...lineWidths) : null
|
|
2813
|
+
});
|
|
2814
|
+
}
|
|
2815
|
+
(_b = obj._clearCache) == null ? void 0 : _b.call(obj);
|
|
2760
2816
|
obj.setCoords();
|
|
2761
2817
|
} else if (obj instanceof fabric__namespace.Group) {
|
|
2762
|
-
(
|
|
2818
|
+
(_c = obj._objects) == null ? void 0 : _c.forEach(fixTextbox);
|
|
2763
2819
|
obj.dirty = true;
|
|
2764
2820
|
obj.setCoords();
|
|
2765
2821
|
}
|
|
2766
2822
|
};
|
|
2767
2823
|
canvas.getObjects().forEach(fixTextbox);
|
|
2824
|
+
const afterMetrics = canvas.getObjects().flatMap(collectUnderlineMetrics);
|
|
2825
|
+
if (afterMetrics.length > 0) {
|
|
2826
|
+
logUnderlineDebug("after-rerender", afterMetrics);
|
|
2827
|
+
}
|
|
2768
2828
|
canvas.requestRenderAll();
|
|
2769
2829
|
};
|
|
2770
2830
|
const ensureFontLoaded = async (fontFamily) => {
|
|
@@ -2802,10 +2862,6 @@ const setupFontLoadingListener = (canvas, afterRerender) => {
|
|
|
2802
2862
|
};
|
|
2803
2863
|
};
|
|
2804
2864
|
preloadAllFonts();
|
|
2805
|
-
const getObjectId = (obj) => obj.__docuforgeId;
|
|
2806
|
-
const setObjectData = (obj, id) => {
|
|
2807
|
-
obj.__docuforgeId = id;
|
|
2808
|
-
};
|
|
2809
2865
|
const svgTextCache = /* @__PURE__ */ new Map();
|
|
2810
2866
|
const htmlImageCache = /* @__PURE__ */ new Map();
|
|
2811
2867
|
const MAX_CACHE_ENTRIES = 200;
|
|
@@ -11863,6 +11919,21 @@ async function ensureFontsForResolvedConfig(config) {
|
|
|
11863
11919
|
});
|
|
11864
11920
|
}
|
|
11865
11921
|
}
|
|
11922
|
+
const PREVIEW_DEBUG_PREFIX = "[canvas-renderer][preview-debug]";
|
|
11923
|
+
function countUnderlinedNodes(config) {
|
|
11924
|
+
var _a;
|
|
11925
|
+
if (!((_a = config == null ? void 0 : config.pages) == null ? void 0 : _a.length)) return 0;
|
|
11926
|
+
let count = 0;
|
|
11927
|
+
const walk = (nodes) => {
|
|
11928
|
+
var _a2;
|
|
11929
|
+
for (const node of nodes || []) {
|
|
11930
|
+
if (node == null ? void 0 : node.underline) count += 1;
|
|
11931
|
+
if ((_a2 = node == null ? void 0 : node.children) == null ? void 0 : _a2.length) walk(node.children);
|
|
11932
|
+
}
|
|
11933
|
+
};
|
|
11934
|
+
for (const page of config.pages) walk(page.children || []);
|
|
11935
|
+
return count;
|
|
11936
|
+
}
|
|
11866
11937
|
function PixldocsPreview(props) {
|
|
11867
11938
|
const {
|
|
11868
11939
|
pageIndex = 0,
|
|
@@ -11890,6 +11961,7 @@ function PixldocsPreview(props) {
|
|
|
11890
11961
|
if (!isResolveMode) {
|
|
11891
11962
|
setResolvedConfig(null);
|
|
11892
11963
|
setCanvasSettled(false);
|
|
11964
|
+
console.log(PREVIEW_DEBUG_PREFIX, "config-mode active");
|
|
11893
11965
|
return;
|
|
11894
11966
|
}
|
|
11895
11967
|
const p = props;
|
|
@@ -11898,6 +11970,12 @@ function PixldocsPreview(props) {
|
|
|
11898
11970
|
setIsLoading(true);
|
|
11899
11971
|
setFontsReady(false);
|
|
11900
11972
|
setCanvasSettled(false);
|
|
11973
|
+
console.log(PREVIEW_DEBUG_PREFIX, "resolve-start", {
|
|
11974
|
+
templateId: p.templateId,
|
|
11975
|
+
formSchemaId: p.formSchemaId,
|
|
11976
|
+
themeId: p.themeId ?? null,
|
|
11977
|
+
pageIndex
|
|
11978
|
+
});
|
|
11901
11979
|
resolveFromForm({
|
|
11902
11980
|
templateId: p.templateId,
|
|
11903
11981
|
formSchemaId: p.formSchemaId,
|
|
@@ -11906,15 +11984,22 @@ function PixldocsPreview(props) {
|
|
|
11906
11984
|
supabaseUrl: p.supabaseUrl,
|
|
11907
11985
|
supabaseAnonKey: p.supabaseAnonKey
|
|
11908
11986
|
}).then((resolved) => {
|
|
11987
|
+
var _a, _b;
|
|
11909
11988
|
if (!cancelled) {
|
|
11989
|
+
console.log(PREVIEW_DEBUG_PREFIX, "resolve-done", {
|
|
11990
|
+
pages: ((_b = (_a = resolved.config) == null ? void 0 : _a.pages) == null ? void 0 : _b.length) ?? 0,
|
|
11991
|
+
underlinedNodes: countUnderlinedNodes(resolved.config)
|
|
11992
|
+
});
|
|
11910
11993
|
setResolvedConfig(resolved.config);
|
|
11911
11994
|
ensureFontsForResolvedConfig(resolved.config).then(() => {
|
|
11912
11995
|
if (!cancelled) {
|
|
11996
|
+
console.log(PREVIEW_DEBUG_PREFIX, "resolve-mode fonts queued");
|
|
11913
11997
|
setFontsReady(true);
|
|
11914
11998
|
setIsLoading(false);
|
|
11915
11999
|
}
|
|
11916
|
-
}).catch(() => {
|
|
12000
|
+
}).catch((err) => {
|
|
11917
12001
|
if (!cancelled) {
|
|
12002
|
+
console.warn(PREVIEW_DEBUG_PREFIX, "resolve-mode fonts queue failed", err);
|
|
11918
12003
|
setFontsReady(true);
|
|
11919
12004
|
setIsLoading(false);
|
|
11920
12005
|
}
|
|
@@ -11923,6 +12008,7 @@ function PixldocsPreview(props) {
|
|
|
11923
12008
|
}).catch((err) => {
|
|
11924
12009
|
if (!cancelled) {
|
|
11925
12010
|
setIsLoading(false);
|
|
12011
|
+
console.warn(PREVIEW_DEBUG_PREFIX, "resolve-error", err);
|
|
11926
12012
|
onError == null ? void 0 : onError(err instanceof Error ? err : new Error(String(err)));
|
|
11927
12013
|
}
|
|
11928
12014
|
});
|
|
@@ -11939,18 +12025,28 @@ function PixldocsPreview(props) {
|
|
|
11939
12025
|
]);
|
|
11940
12026
|
const config = isResolveMode ? resolvedConfig : props.config;
|
|
11941
12027
|
react.useEffect(() => {
|
|
11942
|
-
var _a, _b;
|
|
12028
|
+
var _a, _b, _c;
|
|
11943
12029
|
if (!config) return;
|
|
11944
12030
|
let cancelled = false;
|
|
11945
12031
|
setCanvasSettled(false);
|
|
11946
12032
|
setStabilizationPass(0);
|
|
12033
|
+
console.log(PREVIEW_DEBUG_PREFIX, "config-changed", {
|
|
12034
|
+
pageIndex,
|
|
12035
|
+
pages: ((_a = config.pages) == null ? void 0 : _a.length) ?? 0,
|
|
12036
|
+
underlinedNodes: countUnderlinedNodes(config),
|
|
12037
|
+
isResolveMode
|
|
12038
|
+
});
|
|
11947
12039
|
const bump = () => {
|
|
11948
12040
|
if (cancelled) return;
|
|
11949
12041
|
clearMeasurementCache();
|
|
11950
12042
|
clearFabricCharCache();
|
|
11951
|
-
setFontsReadyVersion((v) =>
|
|
12043
|
+
setFontsReadyVersion((v) => {
|
|
12044
|
+
const next = v + 1;
|
|
12045
|
+
console.log(PREVIEW_DEBUG_PREFIX, "font-bump", { pageIndex, next, stabilizationPass });
|
|
12046
|
+
return next;
|
|
12047
|
+
});
|
|
11952
12048
|
};
|
|
11953
|
-
(
|
|
12049
|
+
(_c = (_b = document.fonts) == null ? void 0 : _b.ready) == null ? void 0 : _c.then(bump);
|
|
11954
12050
|
const timeoutId = window.setTimeout(bump, 350);
|
|
11955
12051
|
return () => {
|
|
11956
12052
|
cancelled = true;
|
|
@@ -11972,17 +12068,28 @@ function PixldocsPreview(props) {
|
|
|
11972
12068
|
setFontsReady(false);
|
|
11973
12069
|
setCanvasSettled(false);
|
|
11974
12070
|
setStabilizationPass(0);
|
|
11975
|
-
ensureFontsForResolvedConfig(config).then(() =>
|
|
12071
|
+
ensureFontsForResolvedConfig(config).then(() => {
|
|
12072
|
+
console.log(PREVIEW_DEBUG_PREFIX, "config-mode fonts queued", {
|
|
12073
|
+
pageIndex,
|
|
12074
|
+
underlinedNodes: countUnderlinedNodes(config)
|
|
12075
|
+
});
|
|
12076
|
+
setFontsReady(true);
|
|
12077
|
+
}).catch((err) => {
|
|
12078
|
+
console.warn(PREVIEW_DEBUG_PREFIX, "config-mode fonts queue failed", err);
|
|
12079
|
+
setFontsReady(true);
|
|
12080
|
+
});
|
|
11976
12081
|
}, [isResolveMode, config]);
|
|
11977
12082
|
const handleCanvasReady = react.useCallback(() => {
|
|
11978
12083
|
if (stabilizationPass === 0) {
|
|
12084
|
+
console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready-pass", { pageIndex, stabilizationPass, action: "stabilize-again" });
|
|
11979
12085
|
setCanvasSettled(false);
|
|
11980
12086
|
setStabilizationPass(1);
|
|
11981
12087
|
return;
|
|
11982
12088
|
}
|
|
12089
|
+
console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready-pass", { pageIndex, stabilizationPass, action: "settled" });
|
|
11983
12090
|
setCanvasSettled(true);
|
|
11984
12091
|
onReady == null ? void 0 : onReady();
|
|
11985
|
-
}, [onReady, stabilizationPass]);
|
|
12092
|
+
}, [onReady, pageIndex, stabilizationPass]);
|
|
11986
12093
|
if (isLoading) {
|
|
11987
12094
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className, style: { ...style, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) });
|
|
11988
12095
|
}
|