embroidery-qc-image 1.0.22 → 1.0.24
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/components/EmbroideryQCImage.d.ts.map +1 -1
- package/dist/index.esm.js +60 -138
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +60 -138
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -33,78 +33,13 @@ function styleInject(css, ref) {
|
|
|
33
33
|
var css_248z = ".render-embroidery {\r\n display: inline-block;\r\n position: relative;\r\n width: 100%;\r\n max-width: 100%;\r\n}\r\n\r\n.render-embroidery-canvas {\r\n display: block;\r\n width: 100%;\r\n height: auto;\r\n image-rendering: high-quality;\r\n background: transparent;\r\n}\r\n";
|
|
34
34
|
styleInject(css_248z);
|
|
35
35
|
|
|
36
|
-
// ============================================================================
|
|
37
|
-
// CONSTANTS
|
|
38
|
-
// ============================================================================
|
|
39
|
-
const COLOR_MAP = {
|
|
40
|
-
"Army (1394)": "#545541",
|
|
41
|
-
Army: "#545541",
|
|
42
|
-
"Black (8)": "#060608",
|
|
43
|
-
Black: "#060608",
|
|
44
|
-
"Bubblegum (1309)": "#E77B9F",
|
|
45
|
-
Bubblegum: "#E77B9F",
|
|
46
|
-
"Carolina Blue (1274)": "#608CC9",
|
|
47
|
-
"Carolina Blue": "#608CC9",
|
|
48
|
-
"Celadon (1098)": "#8EAD8D",
|
|
49
|
-
Celadon: "#8EAD8D",
|
|
50
|
-
"Coffee Bean (1145)": "#502B23",
|
|
51
|
-
"Coffee Bean": "#502B23",
|
|
52
|
-
"Daffodil (1180)": "#FBE30D",
|
|
53
|
-
Daffodil: "#FBE30D",
|
|
54
|
-
"Dark Gray (1131)": "#2E272E",
|
|
55
|
-
"Dark Gray": "#2E272E",
|
|
56
|
-
"Doe Skin Beige (1344)": "#AE9B8B",
|
|
57
|
-
"Doe Skin Beige": "#AE9B8B",
|
|
58
|
-
"Dusty Blue (1373)": "#7B90A9",
|
|
59
|
-
"Dusty Blue": "#7B90A9",
|
|
60
|
-
"Forest Green (1397)": "#073020",
|
|
61
|
-
"Forest Green": "#073020",
|
|
62
|
-
"Gold (1425)": "#D2920A",
|
|
63
|
-
Gold: "#D2920A",
|
|
64
|
-
"Gray (1118)": "#9999A3",
|
|
65
|
-
Gray: "#9999A3",
|
|
66
|
-
"Ivory (1072)": "#E3DAC9",
|
|
67
|
-
Ivory: "#E3DAC9",
|
|
68
|
-
"Lavender (1032)": "#9274B6",
|
|
69
|
-
Lavender: "#9274B6",
|
|
70
|
-
"Light Denim (1133)": "#366696",
|
|
71
|
-
"Light Denim": "#366696",
|
|
72
|
-
"Light Salmon (1018)": "#E0A793",
|
|
73
|
-
"Light Salmon": "#E0A793",
|
|
74
|
-
"Maroon (1374)": "#480C1C",
|
|
75
|
-
Maroon: "#480C1C",
|
|
76
|
-
"Navy Blue (1044)": "#04072A",
|
|
77
|
-
"Navy Blue": "#04072A",
|
|
78
|
-
"Olive Green (1157)": "#625E1F",
|
|
79
|
-
"Olive Green": "#625E1F",
|
|
80
|
-
"Orange (1278)": "#D45D03",
|
|
81
|
-
Orange: "#D45D03",
|
|
82
|
-
"Peach Blush (1053)": "#E2C0B6",
|
|
83
|
-
"Peach Blush": "#E2C0B6",
|
|
84
|
-
"Pink (1148)": "#EFAFBF",
|
|
85
|
-
Pink: "#EFAFBF",
|
|
86
|
-
"Purple (1412)": "#37196F",
|
|
87
|
-
Purple: "#37196F",
|
|
88
|
-
"Red (1037)": "#9D000B",
|
|
89
|
-
Red: "#9D000B",
|
|
90
|
-
"Silver Sage (1396)": "#424F45",
|
|
91
|
-
"Silver Sage": "#424F45",
|
|
92
|
-
"Summer Sky (1432)": "#65A8D2",
|
|
93
|
-
"Summer Sky": "#65A8D2",
|
|
94
|
-
"Terra Cotta (1477)": "#AE3111",
|
|
95
|
-
"Terra Cotta": "#AE3111",
|
|
96
|
-
"Sand (1055)": "#D2C2AB",
|
|
97
|
-
Sand: "#D2C2AB",
|
|
98
|
-
"White (9)": "#D8D7DC",
|
|
99
|
-
White: "#D8D7DC",
|
|
100
|
-
};
|
|
101
36
|
const DEFAULT_ERROR_COLOR = "#CC1F1A";
|
|
102
37
|
const DEFAULT_WARNING_COLOR = "#FF8C00";
|
|
103
38
|
const BASE_URLS = {
|
|
104
39
|
FONT: "https://s3.hn-1.cloud.cmctelecom.vn/god-system-images/embroidery/fonts",
|
|
105
|
-
ICON: "https://s3.hn-1.cloud.cmctelecom.vn/god-system-images/embroidery/icons",
|
|
106
|
-
FLORAL: "https://s3.hn-1.cloud.cmctelecom.vn/god-system-images/embroidery/florals",
|
|
107
|
-
THREAD_COLOR: "https://s3.hn-1.cloud.cmctelecom.vn/god-system-images/embroidery/thread-colors",
|
|
40
|
+
ICON: "https://s3.hn-1.cloud.cmctelecom.vn/god-system-images/embroidery/icons-resized",
|
|
41
|
+
FLORAL: "https://s3.hn-1.cloud.cmctelecom.vn/god-system-images/embroidery/florals-resized",
|
|
42
|
+
THREAD_COLOR: "https://s3.hn-1.cloud.cmctelecom.vn/god-system-images/embroidery/thread-colors-resized",
|
|
108
43
|
};
|
|
109
44
|
const LAYOUT = {
|
|
110
45
|
// Font families
|
|
@@ -140,6 +75,13 @@ const LAYOUT = {
|
|
|
140
75
|
// HELPER FUNCTIONS
|
|
141
76
|
// ============================================================================
|
|
142
77
|
const loadFont = (fontName) => {
|
|
78
|
+
// Check if font is already loaded in document.fonts (browser cache)
|
|
79
|
+
const fontFaceSet = document.fonts;
|
|
80
|
+
for (const font of fontFaceSet) {
|
|
81
|
+
if (font.family === fontName && font.status === 'loaded') {
|
|
82
|
+
return Promise.resolve();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
143
85
|
return new Promise((resolve) => {
|
|
144
86
|
const fontUrl = `${BASE_URLS.FONT}/${encodeURIComponent(fontName)}.woff2`;
|
|
145
87
|
const fontFace = new FontFace(fontName, `url(${fontUrl})`);
|
|
@@ -157,10 +99,10 @@ const loadFont = (fontName) => {
|
|
|
157
99
|
};
|
|
158
100
|
const getImageUrl = (type, value) => {
|
|
159
101
|
if (type === "icon")
|
|
160
|
-
return `${BASE_URLS.ICON}/Icon ${value}.
|
|
102
|
+
return `${BASE_URLS.ICON}/Icon ${value}.webp`;
|
|
161
103
|
if (type === "floral")
|
|
162
|
-
return `${BASE_URLS.FLORAL}/${value}.
|
|
163
|
-
return `${BASE_URLS.THREAD_COLOR}/${value}.
|
|
104
|
+
return `${BASE_URLS.FLORAL}/${value}.webp`;
|
|
105
|
+
return `${BASE_URLS.THREAD_COLOR}/${value}.webp`;
|
|
164
106
|
};
|
|
165
107
|
const getProxyUrl = (url) => `https://proxy-img.c8p.workers.dev?url=${encodeURIComponent(url)}`;
|
|
166
108
|
const ensureImage = (existing) => {
|
|
@@ -379,43 +321,6 @@ const buildWrappedLines = (ctx, text, maxWidth) => {
|
|
|
379
321
|
lines.push(currentLine);
|
|
380
322
|
return lines;
|
|
381
323
|
};
|
|
382
|
-
const wrapTextMultiColor = (ctx, text, colors, x, y, maxWidth, lineHeight) => {
|
|
383
|
-
const words = text.split(" ");
|
|
384
|
-
const lines = [];
|
|
385
|
-
const lineStartIndices = [0];
|
|
386
|
-
let currentLine = words[0];
|
|
387
|
-
let currentCharIndex = words[0].length;
|
|
388
|
-
for (let i = 1; i < words.length; i++) {
|
|
389
|
-
const testLine = currentLine + " " + words[i];
|
|
390
|
-
if (ctx.measureText(testLine).width > maxWidth && currentLine.length > 0) {
|
|
391
|
-
lines.push(currentLine);
|
|
392
|
-
lineStartIndices.push(currentCharIndex + 1);
|
|
393
|
-
currentLine = words[i];
|
|
394
|
-
currentCharIndex += words[i].length + 1;
|
|
395
|
-
}
|
|
396
|
-
else {
|
|
397
|
-
currentLine = testLine;
|
|
398
|
-
currentCharIndex += words[i].length + 1;
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
lines.push(currentLine);
|
|
402
|
-
let currentY = y;
|
|
403
|
-
lines.forEach((line, lineIdx) => {
|
|
404
|
-
let currentX = x;
|
|
405
|
-
const startCharIdx = lineIdx > 0 ? lineStartIndices[lineIdx] : 0;
|
|
406
|
-
for (let i = 0; i < line.length; i++) {
|
|
407
|
-
const char = line[i];
|
|
408
|
-
const globalCharIdx = startCharIdx + i;
|
|
409
|
-
const colorIndex = globalCharIdx % colors.length;
|
|
410
|
-
const color = colors[colorIndex];
|
|
411
|
-
ctx.fillStyle = COLOR_MAP[color] || LAYOUT.LABEL_COLOR;
|
|
412
|
-
ctx.fillText(char, currentX, currentY);
|
|
413
|
-
currentX += ctx.measureText(char).width;
|
|
414
|
-
}
|
|
415
|
-
currentY += lineHeight;
|
|
416
|
-
});
|
|
417
|
-
return lines.length * lineHeight;
|
|
418
|
-
};
|
|
419
324
|
const drawSwatches = (ctx, colors, startX, startY, swatchHeight, scaleFactor, imageRefs) => {
|
|
420
325
|
let swatchX = startX;
|
|
421
326
|
colors.forEach((color) => {
|
|
@@ -887,9 +792,25 @@ const renderUniformLabels = (ctx, uniformProps, x, y, maxWidth, scaleFactor, ima
|
|
|
887
792
|
let rendered = 0;
|
|
888
793
|
if (values.font && shouldRenderField("font")) {
|
|
889
794
|
const allDefault = textPositions.every((p) => p.is_font_default === true);
|
|
890
|
-
|
|
891
|
-
const
|
|
892
|
-
|
|
795
|
+
// Render "Font: " với font mặc định
|
|
796
|
+
const prefix = "Font: ";
|
|
797
|
+
ctx.font = `${fontSize}px ${LAYOUT.FONT_FAMILY}`;
|
|
798
|
+
const prefixWidth = ctx.measureText(prefix).width;
|
|
799
|
+
let currentX = x + prefixWidth;
|
|
800
|
+
ctx.fillText(prefix, x, cursorY);
|
|
801
|
+
// Render tên font với font từ config
|
|
802
|
+
ctx.font = `${fontSize}px ${values.font}`;
|
|
803
|
+
const fontNameWidth = ctx.measureText(values.font).width;
|
|
804
|
+
ctx.fillText(values.font, currentX, cursorY);
|
|
805
|
+
currentX += fontNameWidth;
|
|
806
|
+
// Render "(Mặc định)" hoặc "(Custom)" với font mặc định
|
|
807
|
+
const suffix = allDefault ? " (Mặc định)" : " (Custom)";
|
|
808
|
+
ctx.font = `${fontSize}px ${LAYOUT.FONT_FAMILY}`;
|
|
809
|
+
ctx.measureText(suffix).width;
|
|
810
|
+
ctx.fillText(suffix, currentX, cursorY);
|
|
811
|
+
// Tính toán height và di chuyển cursorY
|
|
812
|
+
const lineHeight = fontSize + lineGap;
|
|
813
|
+
cursorY += lineHeight;
|
|
893
814
|
rendered++;
|
|
894
815
|
}
|
|
895
816
|
if (values.shape && values.shape !== "None" && shouldRenderField("shape")) {
|
|
@@ -938,31 +859,15 @@ const renderTextPosition = (ctx, position, x, y, maxWidth, displayIndex, showLab
|
|
|
938
859
|
const textMaxWidth = maxWidth - labelWidth;
|
|
939
860
|
// Get display text (handle empty/null/undefined)
|
|
940
861
|
const isEmptyText = !position.text || position.text.trim() === "";
|
|
941
|
-
// Draw text content
|
|
862
|
+
// Draw text content - dùng font mặc định và màu đỏ
|
|
863
|
+
ctx.font = `${textFontSize}px ${LAYOUT.FONT_FAMILY}`;
|
|
864
|
+
ctx.fillStyle = DEFAULT_ERROR_COLOR;
|
|
942
865
|
if (isEmptyText) {
|
|
943
|
-
ctx.font = `${textFontSize}px ${LAYOUT.FONT_FAMILY}`;
|
|
944
|
-
ctx.fillStyle = LAYOUT.LABEL_COLOR;
|
|
945
866
|
const textResult = wrapText(ctx, "(không có text)", x + labelWidth, currentY, textMaxWidth, textFontSize);
|
|
946
867
|
currentY += textResult.height;
|
|
947
868
|
drawnHeight += textResult.height;
|
|
948
869
|
}
|
|
949
|
-
else if (position.floral_pattern) {
|
|
950
|
-
// Khi có floral_pattern, dùng màu mặc định như label
|
|
951
|
-
ctx.font = `${textFontSize}px ${position.font}`;
|
|
952
|
-
ctx.fillStyle = LAYOUT.LABEL_COLOR;
|
|
953
|
-
const textResult = wrapText(ctx, position.text, x + labelWidth, currentY, textMaxWidth, textFontSize);
|
|
954
|
-
currentY += textResult.height;
|
|
955
|
-
drawnHeight += textResult.height;
|
|
956
|
-
}
|
|
957
|
-
else if (position.character_colors?.length) {
|
|
958
|
-
ctx.font = `${textFontSize}px ${position.font}`;
|
|
959
|
-
const textHeight = wrapTextMultiColor(ctx, position.text, position.character_colors, x + labelWidth, currentY, textMaxWidth, textFontSize);
|
|
960
|
-
currentY += textHeight;
|
|
961
|
-
drawnHeight += textHeight;
|
|
962
|
-
}
|
|
963
870
|
else {
|
|
964
|
-
ctx.font = `${textFontSize}px ${position.font}`;
|
|
965
|
-
ctx.fillStyle = COLOR_MAP[position.color ?? "None"] || LAYOUT.LABEL_COLOR;
|
|
966
871
|
const textResult = wrapText(ctx, position.text, x + labelWidth, currentY, textMaxWidth, textFontSize);
|
|
967
872
|
currentY += textResult.height;
|
|
968
873
|
drawnHeight += textResult.height;
|
|
@@ -978,12 +883,26 @@ const renderTextPosition = (ctx, position, x, y, maxWidth, displayIndex, showLab
|
|
|
978
883
|
drawnHeight += result.height;
|
|
979
884
|
}
|
|
980
885
|
if (showLabels.font && position.font) {
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
const
|
|
985
|
-
|
|
986
|
-
|
|
886
|
+
// Render "Font: " với font mặc định
|
|
887
|
+
const prefix = "Font: ";
|
|
888
|
+
ctx.font = `${otherFontSize}px ${LAYOUT.FONT_FAMILY}`;
|
|
889
|
+
const prefixWidth = ctx.measureText(prefix).width;
|
|
890
|
+
let currentX = x + prefixWidth;
|
|
891
|
+
ctx.fillText(prefix, x, currentY);
|
|
892
|
+
// Render tên font với font từ config
|
|
893
|
+
ctx.font = `${otherFontSize}px ${position.font}`;
|
|
894
|
+
const fontNameWidth = ctx.measureText(position.font).width;
|
|
895
|
+
ctx.fillText(position.font, currentX, currentY);
|
|
896
|
+
currentX += fontNameWidth;
|
|
897
|
+
// Render "(Mặc định)" hoặc "(Custom)" với font mặc định
|
|
898
|
+
const suffix = position.is_font_default === true ? " (Mặc định)" : " (Custom)";
|
|
899
|
+
ctx.font = `${otherFontSize}px ${LAYOUT.FONT_FAMILY}`;
|
|
900
|
+
ctx.measureText(suffix).width;
|
|
901
|
+
ctx.fillText(suffix, currentX, currentY);
|
|
902
|
+
// Tính toán height và di chuyển cursorY
|
|
903
|
+
const lineHeight = otherFontSize + lineGap;
|
|
904
|
+
currentY += lineHeight;
|
|
905
|
+
drawnHeight += lineHeight;
|
|
987
906
|
}
|
|
988
907
|
if (showLabels.color) {
|
|
989
908
|
const colorValue = position.character_colors?.join(", ") || position.color;
|
|
@@ -1066,8 +985,11 @@ const prepareExportCanvas = async (config, options = {}) => {
|
|
|
1066
985
|
const imageRefs = {
|
|
1067
986
|
current: new Map(),
|
|
1068
987
|
};
|
|
1069
|
-
|
|
1070
|
-
await
|
|
988
|
+
// Load fonts and images in parallel
|
|
989
|
+
await Promise.all([
|
|
990
|
+
preloadFonts(config),
|
|
991
|
+
preloadImages(config, imageRefs)
|
|
992
|
+
]);
|
|
1071
993
|
renderEmbroideryCanvas(canvas, config, { width, height }, imageRefs);
|
|
1072
994
|
if (!canvas.width || !canvas.height) {
|
|
1073
995
|
return null;
|