@pixldocs/canvas-renderer 0.5.95 → 0.5.96

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.js CHANGED
@@ -396,33 +396,6 @@ function measureTextHeight(element) {
396
396
  return fallbackEstimateHeight(element);
397
397
  }
398
398
  }
399
- function getMinTextWidth(element) {
400
- if (element.type !== "text" || !element.text) {
401
- return typeof element.width === "number" ? element.width : 200;
402
- }
403
- try {
404
- const textbox = new fabric.Textbox(element.text, {
405
- width: 1e4,
406
- fontSize: element.fontSize || 16,
407
- fontFamily: element.fontFamily || "Open Sans",
408
- fontWeight: element.fontWeight || 400,
409
- fontStyle: element.fontStyle || "normal",
410
- lineHeight: element.lineHeight || 1.2,
411
- charSpacing: element.charSpacing || 0,
412
- splitByGrapheme: element.splitByGrapheme ?? element.wordWrap === "break-word",
413
- left: 0,
414
- top: 0
415
- });
416
- textbox.initDimensions();
417
- const lineWidths = textbox.__lineWidths;
418
- if (lineWidths && lineWidths.length > 0) {
419
- const maxLine = Math.max(...lineWidths);
420
- return Math.ceil(maxLine) + 2;
421
- }
422
- } catch (_) {
423
- }
424
- return typeof element.width === "number" ? element.width : 200;
425
- }
426
399
  function fallbackEstimateHeight(element) {
427
400
  if (element.type !== "text" || !element.text) {
428
401
  return element.height || 20;
@@ -2778,11 +2751,22 @@ const waitUntilFontsAvailable = async (fontFamilies, options) => {
2778
2751
  }
2779
2752
  };
2780
2753
  const clearFabricCharCache = () => {
2754
+ var _a;
2781
2755
  const fabricAny = fabric;
2756
+ if (fabricAny.cache && typeof fabricAny.cache.clearFontCache === "function") {
2757
+ fabricAny.cache.clearFontCache();
2758
+ }
2759
+ if (((_a = fabricAny.cache) == null ? void 0 : _a.charWidthsCache) instanceof Map) {
2760
+ fabricAny.cache.charWidthsCache.clear();
2761
+ }
2782
2762
  if (typeof fabricAny.charWidthsCache === "object" && fabricAny.charWidthsCache !== null) {
2783
- Object.keys(fabricAny.charWidthsCache).forEach((key) => {
2784
- delete fabricAny.charWidthsCache[key];
2785
- });
2763
+ if (fabricAny.charWidthsCache instanceof Map) {
2764
+ fabricAny.charWidthsCache.clear();
2765
+ } else {
2766
+ Object.keys(fabricAny.charWidthsCache).forEach((key) => {
2767
+ delete fabricAny.charWidthsCache[key];
2768
+ });
2769
+ }
2786
2770
  }
2787
2771
  if (typeof fabric.util !== "undefined" && typeof fabric.util.clearFabricFontCache === "function") {
2788
2772
  fabric.util.clearFabricFontCache();
@@ -5557,6 +5541,8 @@ function createText(element) {
5557
5541
  const targetScaleY = element.scaleY ?? 1;
5558
5542
  const textbox = new fabric.Textbox(text, {
5559
5543
  width: targetWidth,
5544
+ minWidth: 1,
5545
+ dynamicMinWidth: 0,
5560
5546
  scaleX: targetScaleX,
5561
5547
  scaleY: targetScaleY,
5562
5548
  fontSize,
@@ -5577,6 +5563,8 @@ function createText(element) {
5577
5563
  textbox.initDimensions();
5578
5564
  textbox.set({
5579
5565
  width: targetWidth,
5566
+ minWidth: 1,
5567
+ dynamicMinWidth: 0,
5580
5568
  scaleX: targetScaleX,
5581
5569
  scaleY: targetScaleY
5582
5570
  });
@@ -5586,6 +5574,7 @@ function createText(element) {
5586
5574
  const scaleYAfterSet = textbox.scaleY ?? 1;
5587
5575
  if (Math.abs(widthAfterSet - targetWidth) > 0.01 || Math.abs(scaleXAfterSet - targetScaleX) > 0.01 || Math.abs(scaleYAfterSet - targetScaleY) > 0.01) {
5588
5576
  textbox.width = targetWidth;
5577
+ textbox.dynamicMinWidth = 0;
5589
5578
  textbox.scaleX = targetScaleX;
5590
5579
  textbox.scaleY = targetScaleY;
5591
5580
  textbox.setCoords();
@@ -6432,6 +6421,48 @@ const PageCanvas = forwardRef(
6432
6421
  if (!canvas2) return false;
6433
6422
  return !!canvas2._currentTransform || !!canvas2.__isUserTransforming;
6434
6423
  }, []);
6424
+ const reflowTextboxesFromCurrentElements = useCallback((canvas2) => {
6425
+ const elementById = new Map(elementsRef.current.map((el) => [el.id, el]));
6426
+ let didReflow = false;
6427
+ const reflowObject = (obj) => {
6428
+ var _a;
6429
+ if (obj instanceof fabric.Group) {
6430
+ (_a = obj._objects) == null ? void 0 : _a.forEach(reflowObject);
6431
+ obj.dirty = true;
6432
+ return;
6433
+ }
6434
+ if (!(obj instanceof fabric.Textbox)) return;
6435
+ const id = getObjectId(obj);
6436
+ const element = id ? elementById.get(id) : void 0;
6437
+ if (!element) return;
6438
+ const targetWidth = Math.max(1, Number(element.width) > 0 ? Number(element.width) : Number(obj.width ?? 200));
6439
+ const overflowPolicy = element.overflowPolicy || "grow-and-push";
6440
+ const splitByGrapheme = overflowPolicy === "auto-shrink" ? false : element.splitByGrapheme ?? element.wordWrap === "break-word";
6441
+ obj.set({
6442
+ width: targetWidth,
6443
+ minWidth: 1,
6444
+ dynamicMinWidth: 0,
6445
+ text: element.text || "Text",
6446
+ fontSize: element.fontSize || 16,
6447
+ fontFamily: element.fontFamily || "Open Sans",
6448
+ fontWeight: element.fontWeight || 400,
6449
+ fontStyle: element.fontStyle || "normal",
6450
+ lineHeight: element.lineHeight || 1.2,
6451
+ charSpacing: element.charSpacing || 0,
6452
+ splitByGrapheme
6453
+ });
6454
+ obj.initDimensions();
6455
+ if (Math.abs((obj.width ?? 0) - targetWidth) > 0.01) {
6456
+ obj.width = targetWidth;
6457
+ }
6458
+ obj.dynamicMinWidth = 0;
6459
+ obj.setCoords();
6460
+ obj.dirty = true;
6461
+ didReflow = true;
6462
+ };
6463
+ canvas2.getObjects().forEach(reflowObject);
6464
+ if (didReflow) canvas2.requestRenderAll();
6465
+ }, []);
6435
6466
  useEffect(() => {
6436
6467
  if (!canvasElRef.current) return;
6437
6468
  const zoom2 = workspaceZoom || 1;
@@ -6512,6 +6543,8 @@ const PageCanvas = forwardRef(
6512
6543
  };
6513
6544
  initFonts();
6514
6545
  const persistTextDimensionsAfterFontLoad = (canvas2) => {
6546
+ reflowTextboxesFromCurrentElements(canvas2);
6547
+ if (isPreviewMode) return;
6515
6548
  const state = useEditorStore.getState();
6516
6549
  const page = state.canvas.pages.find((p) => p.id === pageId);
6517
6550
  if (!page) return;
@@ -9108,10 +9141,11 @@ const PageCanvas = forwardRef(
9108
9141
  text = result;
9109
9142
  }
9110
9143
  }
9111
- const minWidth = getMinTextWidth(element);
9112
- const textboxWidth = overflowPolicy === "auto-shrink" ? fixedWidth : Math.max(storedWidth, minWidth);
9144
+ const textboxWidth = fixedWidth;
9113
9145
  obj.set({
9114
9146
  width: textboxWidth,
9147
+ minWidth: 1,
9148
+ dynamicMinWidth: 0,
9115
9149
  fontSize,
9116
9150
  fontFamily: element.fontFamily || "Open Sans",
9117
9151
  fill: element.fill || "#1a1a1a",
@@ -9131,6 +9165,7 @@ const PageCanvas = forwardRef(
9131
9165
  if (Math.abs((obj.width ?? 0) - textboxWidth) > 0.01) {
9132
9166
  obj.width = textboxWidth;
9133
9167
  }
9168
+ obj.dynamicMinWidth = 0;
9134
9169
  obj.setCoords();
9135
9170
  obj.dirty = true;
9136
9171
  try {
@@ -12919,7 +12954,6 @@ function PixldocsPreview(props) {
12919
12954
  const [isLoading, setIsLoading] = useState(false);
12920
12955
  const [fontsReady, setFontsReady] = useState(false);
12921
12956
  const [canvasSettled, setCanvasSettled] = useState(false);
12922
- const [stabilizationPass, setStabilizationPass] = useState(0);
12923
12957
  const isResolveMode = !("config" in props && props.config);
12924
12958
  useEffect(() => {
12925
12959
  if (!isResolveMode) {
@@ -12990,21 +13024,16 @@ function PixldocsPreview(props) {
12990
13024
  isResolveMode ? props.themeId : void 0
12991
13025
  ]);
12992
13026
  const config = isResolveMode ? resolvedConfig : props.config;
12993
- const previewKey = useMemo(
12994
- () => `${pageIndex}-${stabilizationPass}`,
12995
- [pageIndex, stabilizationPass]
12996
- );
13027
+ const previewKey = useMemo(() => `${pageIndex}`, [pageIndex]);
12997
13028
  useEffect(() => {
12998
13029
  if (isResolveMode) return;
12999
13030
  if (!config) {
13000
13031
  setFontsReady(false);
13001
13032
  setCanvasSettled(false);
13002
- setStabilizationPass(0);
13003
13033
  return;
13004
13034
  }
13005
13035
  setFontsReady(false);
13006
13036
  setCanvasSettled(false);
13007
- setStabilizationPass(0);
13008
13037
  let cancelled = false;
13009
13038
  const hasAutoShrink = configHasAutoShrinkText$1(config);
13010
13039
  const waitMs = hasAutoShrink ? 4e3 : 1800;
@@ -13027,16 +13056,10 @@ function PixldocsPreview(props) {
13027
13056
  };
13028
13057
  }, [isResolveMode, config]);
13029
13058
  const handleCanvasReady = useCallback(() => {
13030
- if (stabilizationPass === 0) {
13031
- console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready-pass", { pageIndex, stabilizationPass, action: "stabilize-again" });
13032
- setCanvasSettled(false);
13033
- setStabilizationPass(1);
13034
- return;
13035
- }
13036
- console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready-pass", { pageIndex, stabilizationPass, action: "settled" });
13059
+ console.log(PREVIEW_DEBUG_PREFIX, "canvas-ready", { pageIndex, action: "settled" });
13037
13060
  setCanvasSettled(true);
13038
13061
  onReady == null ? void 0 : onReady();
13039
- }, [onReady, pageIndex, stabilizationPass]);
13062
+ }, [onReady, pageIndex]);
13040
13063
  if (isLoading) {
13041
13064
  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..." }) });
13042
13065
  }