@pixldocs/canvas-renderer 0.5.42 → 0.5.44
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 +128 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +128 -26
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4804,9 +4804,17 @@ function calculateScaleSnapGuides(scalingObj, corner, canvas, canvasWidth, canva
|
|
|
4804
4804
|
const PD_BG_KEY = "__pdBg";
|
|
4805
4805
|
const PATCHED_KEY = "__pdBgPatched";
|
|
4806
4806
|
function extractTextBgConfig(element) {
|
|
4807
|
+
const legacy = Math.max(0, Number(element.textBgPadding ?? 0)) || 0;
|
|
4808
|
+
const pick = (v) => {
|
|
4809
|
+
const n = Number(v);
|
|
4810
|
+
return Number.isFinite(n) && n >= 0 ? n : void 0;
|
|
4811
|
+
};
|
|
4807
4812
|
return {
|
|
4808
4813
|
color: element.textBgColor,
|
|
4809
|
-
|
|
4814
|
+
padTop: pick(element.textBgPaddingTop) ?? legacy,
|
|
4815
|
+
padRight: pick(element.textBgPaddingRight) ?? legacy,
|
|
4816
|
+
padBottom: pick(element.textBgPaddingBottom) ?? legacy,
|
|
4817
|
+
padLeft: pick(element.textBgPaddingLeft) ?? legacy,
|
|
4810
4818
|
rxTL: Math.max(0, Number(element.textBgRxTL ?? 0)) || 0,
|
|
4811
4819
|
rxTR: Math.max(0, Number(element.textBgRxTR ?? 0)) || 0,
|
|
4812
4820
|
rxBR: Math.max(0, Number(element.textBgRxBR ?? 0)) || 0,
|
|
@@ -4824,9 +4832,8 @@ function buildTextShadow(element) {
|
|
|
4824
4832
|
const ox = Number(element.textShadowOffsetX ?? 0);
|
|
4825
4833
|
const oy = Number(element.textShadowOffsetY ?? 0);
|
|
4826
4834
|
if (!color || color === "transparent") return null;
|
|
4827
|
-
if (blur === 0 && ox === 0 && oy === 0) return null;
|
|
4828
4835
|
return new fabric__namespace.Shadow({
|
|
4829
|
-
color,
|
|
4836
|
+
color: String(color),
|
|
4830
4837
|
blur: blur || 0,
|
|
4831
4838
|
offsetX: ox || 0,
|
|
4832
4839
|
offsetY: oy || 0,
|
|
@@ -4863,11 +4870,14 @@ function applyTextBackground(obj, cfg) {
|
|
|
4863
4870
|
if (hasTextBackground(bg)) {
|
|
4864
4871
|
const w = this.width ?? 0;
|
|
4865
4872
|
const h = this.height ?? 0;
|
|
4866
|
-
const
|
|
4867
|
-
const
|
|
4868
|
-
const
|
|
4869
|
-
const
|
|
4870
|
-
const
|
|
4873
|
+
const pT = Math.max(0, Number(bg.padTop ?? 0));
|
|
4874
|
+
const pR = Math.max(0, Number(bg.padRight ?? 0));
|
|
4875
|
+
const pB = Math.max(0, Number(bg.padBottom ?? 0));
|
|
4876
|
+
const pL = Math.max(0, Number(bg.padLeft ?? 0));
|
|
4877
|
+
const x = -w / 2 - pL;
|
|
4878
|
+
const y = -h / 2 - pT;
|
|
4879
|
+
const bgW = w + pL + pR;
|
|
4880
|
+
const bgH = h + pT + pB;
|
|
4871
4881
|
ctx.save();
|
|
4872
4882
|
buildRoundedRectPath2D(
|
|
4873
4883
|
ctx,
|
|
@@ -4898,37 +4908,107 @@ function applyTextBackground(obj, cfg) {
|
|
|
4898
4908
|
const originalToSVG = (_a = obj.toSVG) == null ? void 0 : _a.bind(obj);
|
|
4899
4909
|
if (typeof originalToSVG === "function") {
|
|
4900
4910
|
obj.toSVG = function(reviver) {
|
|
4901
|
-
|
|
4911
|
+
let svg = originalToSVG(reviver);
|
|
4902
4912
|
const bg = this[PD_BG_KEY];
|
|
4903
|
-
|
|
4913
|
+
const shadow = this.shadow;
|
|
4914
|
+
const hasBg = hasTextBackground(bg);
|
|
4915
|
+
const hasShadow = !!shadow && !!shadow.color && shadow.color !== "transparent";
|
|
4916
|
+
if (!hasBg && !hasShadow) return svg;
|
|
4904
4917
|
const w = this.width ?? 0;
|
|
4905
4918
|
const h = this.height ?? 0;
|
|
4906
|
-
const
|
|
4907
|
-
const
|
|
4908
|
-
const
|
|
4909
|
-
const
|
|
4910
|
-
const
|
|
4911
|
-
const
|
|
4919
|
+
const pT = Math.max(0, Number((bg == null ? void 0 : bg.padTop) ?? 0));
|
|
4920
|
+
const pR = Math.max(0, Number((bg == null ? void 0 : bg.padRight) ?? 0));
|
|
4921
|
+
const pB = Math.max(0, Number((bg == null ? void 0 : bg.padBottom) ?? 0));
|
|
4922
|
+
const pL = Math.max(0, Number((bg == null ? void 0 : bg.padLeft) ?? 0));
|
|
4923
|
+
const x = -w / 2 - pL;
|
|
4924
|
+
const y = -h / 2 - pT;
|
|
4925
|
+
const bgW = w + pL + pR;
|
|
4926
|
+
const bgH = h + pT + pB;
|
|
4927
|
+
const bgD = buildRoundedRectPathD(
|
|
4912
4928
|
x,
|
|
4913
4929
|
y,
|
|
4914
4930
|
bgW,
|
|
4915
4931
|
bgH,
|
|
4916
|
-
bg.rxTL ?? 0,
|
|
4917
|
-
bg.rxTR ?? 0,
|
|
4918
|
-
bg.rxBR ?? 0,
|
|
4919
|
-
bg.rxBL ?? 0
|
|
4932
|
+
(bg == null ? void 0 : bg.rxTL) ?? 0,
|
|
4933
|
+
(bg == null ? void 0 : bg.rxTR) ?? 0,
|
|
4934
|
+
(bg == null ? void 0 : bg.rxBR) ?? 0,
|
|
4935
|
+
(bg == null ? void 0 : bg.rxBL) ?? 0
|
|
4920
4936
|
);
|
|
4921
|
-
const
|
|
4922
|
-
const bgPath = `<path d="${
|
|
4937
|
+
const bgFill = (bg == null ? void 0 : bg.color) || "";
|
|
4938
|
+
const bgPath = hasBg ? `<path d="${bgD}" fill="${escapeXmlAttr(bgFill)}" />` : "";
|
|
4939
|
+
svg = svg.replace(/style="[^"]*filter:\s*url\([^)]+\)[^"]*"/i, "");
|
|
4940
|
+
svg = svg.replace(/<filter[\s\S]*?<\/filter>/gi, "");
|
|
4941
|
+
let shadowLayer = "";
|
|
4942
|
+
if (hasShadow) {
|
|
4943
|
+
const ox = Number(shadow.offsetX ?? 0) || 0;
|
|
4944
|
+
const oy = Number(shadow.offsetY ?? 0) || 0;
|
|
4945
|
+
const blur = Math.max(0, Number(shadow.blur ?? 0));
|
|
4946
|
+
const shadowColor = String(shadow.color);
|
|
4947
|
+
const shadowBgPath = hasBg ? `<path d="${bgD}" fill="${escapeXmlAttr(shadowColor)}" />` : "";
|
|
4948
|
+
const inner = extractGInnerMarkup(svg);
|
|
4949
|
+
const recoloredText = recolorSvgFills(inner, shadowColor);
|
|
4950
|
+
const layers = [];
|
|
4951
|
+
if (blur > 0) {
|
|
4952
|
+
const ringCount = Math.min(6, Math.max(2, Math.round(blur / 2)));
|
|
4953
|
+
for (let i = 1; i <= ringCount; i++) {
|
|
4954
|
+
const t = i / ringCount;
|
|
4955
|
+
const dist = blur * t * 0.6;
|
|
4956
|
+
const op = (0.18 * (1 - t * 0.7)).toFixed(3);
|
|
4957
|
+
const ringOffsets = [
|
|
4958
|
+
[dist, 0],
|
|
4959
|
+
[-dist, 0],
|
|
4960
|
+
[0, dist],
|
|
4961
|
+
[0, -dist],
|
|
4962
|
+
[dist * 0.7, dist * 0.7],
|
|
4963
|
+
[-dist * 0.7, dist * 0.7],
|
|
4964
|
+
[dist * 0.7, -dist * 0.7],
|
|
4965
|
+
[-dist * 0.7, -dist * 0.7]
|
|
4966
|
+
];
|
|
4967
|
+
for (const [dx, dy] of ringOffsets) {
|
|
4968
|
+
layers.push(
|
|
4969
|
+
`<g transform="translate(${(ox + dx).toFixed(3)} ${(oy + dy).toFixed(3)})" opacity="${op}">${shadowBgPath}${recoloredText}</g>`
|
|
4970
|
+
);
|
|
4971
|
+
}
|
|
4972
|
+
}
|
|
4973
|
+
layers.push(
|
|
4974
|
+
`<g transform="translate(${ox.toFixed(3)} ${oy.toFixed(3)})" opacity="0.25">${shadowBgPath}${recoloredText}</g>`
|
|
4975
|
+
);
|
|
4976
|
+
} else {
|
|
4977
|
+
layers.push(
|
|
4978
|
+
`<g transform="translate(${ox.toFixed(3)} ${oy.toFixed(3)})">${shadowBgPath}${recoloredText}</g>`
|
|
4979
|
+
);
|
|
4980
|
+
}
|
|
4981
|
+
shadowLayer = layers.join("");
|
|
4982
|
+
}
|
|
4923
4983
|
const openTagMatch = svg.match(/^\s*<g\b[^>]*>/);
|
|
4984
|
+
const inserted = shadowLayer + bgPath;
|
|
4924
4985
|
if (openTagMatch) {
|
|
4925
4986
|
const openTag = openTagMatch[0];
|
|
4926
|
-
return svg.replace(openTag, openTag +
|
|
4987
|
+
return svg.replace(openTag, openTag + inserted);
|
|
4927
4988
|
}
|
|
4928
|
-
return `<g>${
|
|
4989
|
+
return `<g>${inserted}${svg}</g>`;
|
|
4929
4990
|
};
|
|
4930
4991
|
}
|
|
4931
4992
|
}
|
|
4993
|
+
function recolorSvgFills(svg, color) {
|
|
4994
|
+
const safe = escapeXmlAttr(color);
|
|
4995
|
+
let out = svg.replace(
|
|
4996
|
+
/(<(?:text|tspan|path|rect)\b[^>]*?\sfill=")([^"]*)("[^>]*>)/gi,
|
|
4997
|
+
(_m, pre, val, post) => {
|
|
4998
|
+
const v = val.trim().toLowerCase();
|
|
4999
|
+
if (v === "none" || v === "transparent") return pre + val + post;
|
|
5000
|
+
return pre + safe + post;
|
|
5001
|
+
}
|
|
5002
|
+
);
|
|
5003
|
+
out = out.replace(
|
|
5004
|
+
/(<(?:text|tspan|path|rect)\b[^>]*?\sstyle=")([^"]*)("[^>]*>)/gi,
|
|
5005
|
+
(_m, pre, styleVal, post) => {
|
|
5006
|
+
const replaced = styleVal.replace(/fill\s*:\s*[^;"]+/gi, `fill: ${color}`);
|
|
5007
|
+
return pre + replaced + post;
|
|
5008
|
+
}
|
|
5009
|
+
);
|
|
5010
|
+
return out;
|
|
5011
|
+
}
|
|
4932
5012
|
function buildRoundedRectPathD(x, y, w, h, rTL, rTR, rBR, rBL) {
|
|
4933
5013
|
const maxR = Math.min(w, h) / 2;
|
|
4934
5014
|
const tl = Math.min(Math.max(0, rTL), maxR);
|
|
@@ -4952,6 +5032,13 @@ function buildRoundedRectPathD(x, y, w, h, rTL, rTR, rBR, rBL) {
|
|
|
4952
5032
|
function escapeXmlAttr(s) {
|
|
4953
5033
|
return String(s).replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
4954
5034
|
}
|
|
5035
|
+
function extractGInnerMarkup(markup) {
|
|
5036
|
+
const openMatch = markup.match(/^\s*<g\b[^>]*>/);
|
|
5037
|
+
if (!openMatch) return markup;
|
|
5038
|
+
const closeIdx = markup.lastIndexOf("</g>");
|
|
5039
|
+
if (closeIdx <= openMatch[0].length) return markup;
|
|
5040
|
+
return markup.slice(openMatch[0].length, closeIdx);
|
|
5041
|
+
}
|
|
4955
5042
|
const TRIANGLE_STROKE_MITER_LIMIT = 1e6;
|
|
4956
5043
|
const toSafeNumber = (value, fallback = 0) => Number.isFinite(value) ? Math.max(0, Number(value)) : fallback;
|
|
4957
5044
|
function normalizeShapeType(shapeType) {
|
|
@@ -7871,6 +7958,10 @@ const PageCanvas = react.forwardRef(
|
|
|
7871
7958
|
JSON.stringify({
|
|
7872
7959
|
c: element.textBgColor ?? null,
|
|
7873
7960
|
p: element.textBgPadding ?? 0,
|
|
7961
|
+
pt: element.textBgPaddingTop ?? null,
|
|
7962
|
+
pr: element.textBgPaddingRight ?? null,
|
|
7963
|
+
pb: element.textBgPaddingBottom ?? null,
|
|
7964
|
+
pl: element.textBgPaddingLeft ?? null,
|
|
7874
7965
|
tl: element.textBgRxTL ?? 0,
|
|
7875
7966
|
tr: element.textBgRxTR ?? 0,
|
|
7876
7967
|
br: element.textBgRxBR ?? 0,
|
|
@@ -8314,7 +8405,7 @@ const PageCanvas = react.forwardRef(
|
|
|
8314
8405
|
});
|
|
8315
8406
|
}, [selectedIds, isActive, ready, elements]);
|
|
8316
8407
|
const updateFabricObject = (obj, element, skipPositionUpdate = false) => {
|
|
8317
|
-
var _a, _b;
|
|
8408
|
+
var _a, _b, _c;
|
|
8318
8409
|
const fc = fabricRef.current;
|
|
8319
8410
|
if (fc && isTransforming(fc)) {
|
|
8320
8411
|
return;
|
|
@@ -8778,9 +8869,20 @@ const PageCanvas = react.forwardRef(
|
|
|
8778
8869
|
applyTextBackground(obj, extractTextBgConfig(element));
|
|
8779
8870
|
const shadow = buildTextShadow(element);
|
|
8780
8871
|
obj.set("shadow", shadow ?? null);
|
|
8872
|
+
try {
|
|
8873
|
+
obj._cacheCanvas = null;
|
|
8874
|
+
obj._cacheContext = null;
|
|
8875
|
+
} catch {
|
|
8876
|
+
}
|
|
8877
|
+
obj.dirty = true;
|
|
8878
|
+
(_c = obj.setCoords) == null ? void 0 : _c.call(obj);
|
|
8781
8879
|
obj.__lastTextBgShadowJson = JSON.stringify({
|
|
8782
8880
|
c: element.textBgColor ?? null,
|
|
8783
8881
|
p: element.textBgPadding ?? 0,
|
|
8882
|
+
pt: element.textBgPaddingTop ?? null,
|
|
8883
|
+
pr: element.textBgPaddingRight ?? null,
|
|
8884
|
+
pb: element.textBgPaddingBottom ?? null,
|
|
8885
|
+
pl: element.textBgPaddingLeft ?? null,
|
|
8784
8886
|
tl: element.textBgRxTL ?? 0,
|
|
8785
8887
|
tr: element.textBgRxTR ?? 0,
|
|
8786
8888
|
br: element.textBgRxBR ?? 0,
|
|
@@ -12258,7 +12360,7 @@ function PixldocsPreview(props) {
|
|
|
12258
12360
|
!canvasSettled && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", minHeight: 200 }, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#888", fontSize: 14 }, children: "Loading preview..." }) })
|
|
12259
12361
|
] });
|
|
12260
12362
|
}
|
|
12261
|
-
const PACKAGE_VERSION = "0.5.
|
|
12363
|
+
const PACKAGE_VERSION = "0.5.44";
|
|
12262
12364
|
let __underlineFixInstalled = false;
|
|
12263
12365
|
function installUnderlineFix(fab) {
|
|
12264
12366
|
var _a;
|