embroidery-qc-image 1.0.20 → 1.0.22
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 +76 -27
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +76 -27
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -730,10 +730,30 @@ const renderSide = (ctx, side, startY, width, scaleFactor, imageRefs) => {
|
|
|
730
730
|
ctx.restore();
|
|
731
731
|
// Compute uniform properties
|
|
732
732
|
const textPositions = side.positions.filter((p) => p.type === "TEXT");
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
733
|
+
const iconColorPositions = side.positions.filter((p) => p.type === "ICON" && (!p.layer_colors?.length || p.layer_colors.length === 1));
|
|
734
|
+
const iconColorValues = iconColorPositions
|
|
735
|
+
.map((p) => {
|
|
736
|
+
if (p.layer_colors?.length === 1)
|
|
737
|
+
return p.layer_colors[0];
|
|
738
|
+
return p.color ?? null;
|
|
739
|
+
})
|
|
740
|
+
.filter((color) => Boolean(color));
|
|
741
|
+
const uniformProps = computeUniformProperties(textPositions, {
|
|
742
|
+
additionalColorValues: iconColorValues,
|
|
743
|
+
});
|
|
744
|
+
const hasMultipleTextPositions = textPositions.length > 1;
|
|
745
|
+
const hasSharedIconColor = iconColorValues.length > 0;
|
|
746
|
+
const shouldRenderSharedColorLabel = !hasMultipleTextPositions &&
|
|
747
|
+
hasSharedIconColor &&
|
|
748
|
+
uniformProps.isUniform.color &&
|
|
749
|
+
Boolean(uniformProps.values.color);
|
|
750
|
+
const shouldShowUniformLabels = hasMultipleTextPositions || shouldRenderSharedColorLabel;
|
|
751
|
+
const uniformLabelFields = hasMultipleTextPositions
|
|
752
|
+
? undefined
|
|
753
|
+
: { color: true };
|
|
754
|
+
// Render uniform labels (when applicable)
|
|
755
|
+
if (shouldShowUniformLabels) {
|
|
756
|
+
currentY += renderUniformLabels(ctx, uniformProps, padding, currentY, sideWidth, scaleFactor, imageRefs, textPositions, uniformLabelFields);
|
|
737
757
|
}
|
|
738
758
|
// Group text positions by common properties
|
|
739
759
|
const textGroups = groupTextPositions(textPositions);
|
|
@@ -747,7 +767,12 @@ const renderSide = (ctx, side, startY, width, scaleFactor, imageRefs) => {
|
|
|
747
767
|
}
|
|
748
768
|
// If only 1 TEXT position, show all labels (no uniform labels rendered)
|
|
749
769
|
const showLabels = textPositions.length === 1
|
|
750
|
-
? {
|
|
770
|
+
? {
|
|
771
|
+
font: true,
|
|
772
|
+
shape: true,
|
|
773
|
+
floral: true,
|
|
774
|
+
color: !shouldRenderSharedColorLabel,
|
|
775
|
+
}
|
|
751
776
|
: {
|
|
752
777
|
font: !uniformProps.isUniform.font,
|
|
753
778
|
shape: !uniformProps.isUniform.shape,
|
|
@@ -765,7 +790,17 @@ const renderSide = (ctx, side, startY, width, scaleFactor, imageRefs) => {
|
|
|
765
790
|
currentY += LAYOUT.LINE_GAP * scaleFactor;
|
|
766
791
|
side.positions.forEach((position) => {
|
|
767
792
|
if (position.type === "ICON") {
|
|
768
|
-
|
|
793
|
+
const layerCount = position.layer_colors?.length ?? 0;
|
|
794
|
+
const iconUsesSingleColor = layerCount === 0 || layerCount === 1;
|
|
795
|
+
const iconColorValue = layerCount === 1
|
|
796
|
+
? position.layer_colors?.[0] ?? null
|
|
797
|
+
: position.color ?? null;
|
|
798
|
+
const hideColor = shouldShowUniformLabels &&
|
|
799
|
+
uniformProps.isUniform.color &&
|
|
800
|
+
iconColorValue !== null &&
|
|
801
|
+
uniformProps.values.color === iconColorValue &&
|
|
802
|
+
iconUsesSingleColor;
|
|
803
|
+
currentY += renderIconPosition(ctx, position, padding, currentY, sideWidth, scaleFactor, imageRefs, { hideColor });
|
|
769
804
|
currentY += (LAYOUT.LINE_GAP / 3) * scaleFactor;
|
|
770
805
|
}
|
|
771
806
|
});
|
|
@@ -802,56 +837,67 @@ const groupTextPositions = (textPositions) => {
|
|
|
802
837
|
}
|
|
803
838
|
return groups;
|
|
804
839
|
};
|
|
805
|
-
const computeUniformProperties = (textPositions) => {
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
};
|
|
811
|
-
}
|
|
840
|
+
const computeUniformProperties = (textPositions, options) => {
|
|
841
|
+
const defaults = {
|
|
842
|
+
values: { font: null, shape: null, floral: null, color: null },
|
|
843
|
+
isUniform: { font: false, shape: false, floral: false, color: false },
|
|
844
|
+
};
|
|
812
845
|
const fonts = new Set(textPositions.map((p) => p.font));
|
|
813
846
|
const shapes = new Set(textPositions.map((p) => p.text_shape));
|
|
814
847
|
const florals = new Set(textPositions.map((p) => p.floral_pattern ?? "None"));
|
|
815
|
-
const
|
|
816
|
-
|
|
817
|
-
|
|
848
|
+
const colorSources = [
|
|
849
|
+
...textPositions.map((p) => p.character_colors?.length
|
|
850
|
+
? p.character_colors.join(",")
|
|
851
|
+
: p.color ?? "None"),
|
|
852
|
+
...(options?.additionalColorValues?.map((color) => color ?? "None") ?? []),
|
|
853
|
+
];
|
|
854
|
+
if (textPositions.length === 0 &&
|
|
855
|
+
(!options?.additionalColorValues || options.additionalColorValues.length === 0)) {
|
|
856
|
+
return defaults;
|
|
857
|
+
}
|
|
858
|
+
const colors = new Set(colorSources);
|
|
818
859
|
return {
|
|
819
860
|
values: {
|
|
820
861
|
font: fonts.size === 1 ? [...fonts][0] : null,
|
|
821
862
|
shape: shapes.size === 1 ? [...shapes][0] : null,
|
|
822
863
|
floral: florals.size === 1 ? [...florals][0] : null,
|
|
823
|
-
color: colors.size === 1 ? [...colors][0] : null,
|
|
864
|
+
color: colorSources.length > 0 && colors.size === 1 ? [...colors][0] : null,
|
|
824
865
|
},
|
|
825
866
|
isUniform: {
|
|
826
867
|
font: fonts.size === 1,
|
|
827
868
|
shape: shapes.size === 1,
|
|
828
869
|
floral: florals.size === 1,
|
|
829
|
-
color: colors.size === 1,
|
|
870
|
+
color: colorSources.length > 0 && colors.size === 1,
|
|
830
871
|
},
|
|
831
872
|
};
|
|
832
873
|
};
|
|
833
|
-
const renderUniformLabels = (ctx, uniformProps, x, y, maxWidth, scaleFactor, imageRefs, textPositions) => {
|
|
874
|
+
const renderUniformLabels = (ctx, uniformProps, x, y, maxWidth, scaleFactor, imageRefs, textPositions, fields) => {
|
|
834
875
|
const { values } = uniformProps;
|
|
835
876
|
const fontSize = LAYOUT.OTHER_FONT_SIZE * scaleFactor;
|
|
836
877
|
const lineGap = LAYOUT.LINE_GAP * scaleFactor;
|
|
878
|
+
const shouldRenderField = (field) => {
|
|
879
|
+
if (!fields)
|
|
880
|
+
return true;
|
|
881
|
+
return fields[field] === true;
|
|
882
|
+
};
|
|
837
883
|
ctx.save();
|
|
838
884
|
ctx.font = `${fontSize}px ${LAYOUT.FONT_FAMILY}`;
|
|
839
885
|
ctx.fillStyle = LAYOUT.LABEL_COLOR;
|
|
840
886
|
let cursorY = y;
|
|
841
887
|
let rendered = 0;
|
|
842
|
-
if (values.font) {
|
|
888
|
+
if (values.font && shouldRenderField("font")) {
|
|
843
889
|
const allDefault = textPositions.every((p) => p.is_font_default === true);
|
|
844
|
-
const fontLabel = allDefault ? `Font: ${values.font} (Mặc định)` : `Font: ${values.font}`;
|
|
890
|
+
const fontLabel = allDefault ? `Font: ${values.font} (Mặc định)` : `Font: ${values.font} (Custom)`;
|
|
845
891
|
const result = wrapText(ctx, fontLabel, x, cursorY, maxWidth, fontSize + lineGap);
|
|
846
892
|
cursorY += result.height;
|
|
847
893
|
rendered++;
|
|
848
894
|
}
|
|
849
|
-
if (values.shape && values.shape !== "None") {
|
|
895
|
+
if (values.shape && values.shape !== "None" && shouldRenderField("shape")) {
|
|
850
896
|
const result = wrapText(ctx, `Kiểu chữ: ${values.shape}`, x, cursorY, maxWidth, fontSize + lineGap);
|
|
851
897
|
cursorY += result.height;
|
|
852
898
|
rendered++;
|
|
853
899
|
}
|
|
854
|
-
if (values.color && values.color !== "None") {
|
|
900
|
+
if (values.color && values.color !== "None" && shouldRenderField("color")) {
|
|
855
901
|
const textMaxWidth = Math.max(LAYOUT.MIN_TEXT_WIDTH * scaleFactor, maxWidth - LAYOUT.SWATCH_RESERVED_SPACE * scaleFactor);
|
|
856
902
|
const result = wrapText(ctx, `Màu chỉ: ${values.color}`, x, cursorY, textMaxWidth, fontSize + lineGap);
|
|
857
903
|
const swatchH = Math.floor(fontSize * LAYOUT.SWATCH_HEIGHT_RATIO);
|
|
@@ -866,7 +912,7 @@ const renderUniformLabels = (ctx, uniformProps, x, y, maxWidth, scaleFactor, ima
|
|
|
866
912
|
cursorY += result.height;
|
|
867
913
|
rendered++;
|
|
868
914
|
}
|
|
869
|
-
if (values.floral && values.floral !== "None") {
|
|
915
|
+
if (values.floral && values.floral !== "None" && shouldRenderField("floral")) {
|
|
870
916
|
const result = wrapText(ctx, `Mẫu hoa: ${values.floral}`, x, cursorY, maxWidth, fontSize + lineGap);
|
|
871
917
|
cursorY += result.height;
|
|
872
918
|
rendered++;
|
|
@@ -934,7 +980,7 @@ const renderTextPosition = (ctx, position, x, y, maxWidth, displayIndex, showLab
|
|
|
934
980
|
if (showLabels.font && position.font) {
|
|
935
981
|
const fontLabel = position.is_font_default === true
|
|
936
982
|
? `Font: ${position.font} (Mặc định)`
|
|
937
|
-
: `Font: ${position.font}`;
|
|
983
|
+
: `Font: ${position.font} (Custom)`;
|
|
938
984
|
const result = wrapText(ctx, fontLabel, x, currentY, maxWidth, otherFontSize + lineGap);
|
|
939
985
|
currentY += result.height;
|
|
940
986
|
drawnHeight += result.height;
|
|
@@ -964,7 +1010,7 @@ const renderTextPosition = (ctx, position, x, y, maxWidth, displayIndex, showLab
|
|
|
964
1010
|
ctx.restore();
|
|
965
1011
|
return drawnHeight;
|
|
966
1012
|
};
|
|
967
|
-
const renderIconPosition = (ctx, position, x, y, maxWidth, scaleFactor, imageRefs) => {
|
|
1013
|
+
const renderIconPosition = (ctx, position, x, y, maxWidth, scaleFactor, imageRefs, options) => {
|
|
968
1014
|
const iconFontSize = LAYOUT.OTHER_FONT_SIZE * scaleFactor;
|
|
969
1015
|
const lineGap = LAYOUT.LINE_GAP * scaleFactor;
|
|
970
1016
|
ctx.save();
|
|
@@ -997,7 +1043,10 @@ const renderIconPosition = (ctx, position, x, y, maxWidth, scaleFactor, imageRef
|
|
|
997
1043
|
: position.color
|
|
998
1044
|
? [position.color]
|
|
999
1045
|
: null;
|
|
1000
|
-
|
|
1046
|
+
const layerCount = position.layer_colors?.length ?? 0;
|
|
1047
|
+
const hasMultiLayerColors = layerCount > 1;
|
|
1048
|
+
const shouldSkipColorSection = options?.hideColor && !hasMultiLayerColors;
|
|
1049
|
+
if (iconColors?.length && !shouldSkipColorSection) {
|
|
1001
1050
|
const textMaxWidth = Math.max(LAYOUT.MIN_TEXT_WIDTH * scaleFactor, maxWidth - LAYOUT.SWATCH_RESERVED_SPACE * scaleFactor);
|
|
1002
1051
|
const colorResult = wrapText(ctx, `Màu chỉ: ${iconColors.join(", ")}`, x, cursorY, textMaxWidth, iconFontSize + lineGap);
|
|
1003
1052
|
const swatchH = Math.floor(iconFontSize * LAYOUT.SWATCH_HEIGHT_RATIO);
|