embroidery-qc-image 1.0.31 → 1.0.32

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
@@ -626,36 +626,17 @@ const renderStrokePatchesCanvas = (ctx, canvas, config, imageRefs) => {
626
626
  renderErrorState(ctx, canvas, "Position phải là TEXT");
627
627
  return;
628
628
  }
629
- // Validate required fields
630
- if (!position.font) {
631
- renderErrorState(ctx, canvas, "Thiếu font");
632
- return;
633
- }
634
- // Validate layer_colors
635
- if (!position.layer_colors) {
636
- renderErrorState(ctx, canvas, "Thiếu layer_colors");
637
- return;
638
- }
639
- if (position.layer_colors.length !== 3) {
640
- renderErrorState(ctx, canvas, `layer_colors phải có đúng 3 phần tử, hiện tại có ${position.layer_colors.length}`);
641
- return;
642
- }
643
- // Validate từng màu
644
- const [textColor, borderColor, backgroundColor] = position.layer_colors;
645
- const missingColors = [];
646
- if (!textColor || textColor.trim() === "") {
647
- missingColors.push("Màu text (vị trí 1)");
648
- }
649
- if (!borderColor || borderColor.trim() === "") {
650
- missingColors.push("Màu border (vị trí 2)");
651
- }
652
- if (!backgroundColor || backgroundColor.trim() === "") {
653
- missingColors.push("Màu background (vị trí 3)");
654
- }
655
- if (missingColors.length > 0) {
656
- renderErrorState(ctx, canvas, `Thiếu màu trong layer_colors:\n${missingColors.join("\n")}`);
657
- return;
658
- }
629
+ // Get layer colors with empty check (don't use fallback)
630
+ const textColor = position.layer_colors?.[0];
631
+ const borderColor = position.layer_colors?.[1];
632
+ const backgroundColor = position.layer_colors?.[2];
633
+ const fabricColor = position.layer_colors?.[3]; // Màu vải
634
+ // For rendering, use fallback colors (fabricColor không cần fallback vì chỉ hiển thị)
635
+ const textColorForRender = textColor;
636
+ const borderColorForRender = borderColor;
637
+ const backgroundColorForRender = backgroundColor;
638
+ // Check if font is missing (but continue rendering)
639
+ const isFontMissing = !position.font || position.font.trim() === "";
659
640
  // ============================================================================
660
641
  // TOP SECTION (2/3): Hiển thị mẫu preview
661
642
  // ============================================================================
@@ -671,7 +652,8 @@ const renderStrokePatchesCanvas = (ctx, canvas, config, imageRefs) => {
671
652
  const actualTopSectionHeight = topSectionHeight - titleFontSize - LAYOUT.LINE_GAP - extraSpacing;
672
653
  // Calculate text size to fit top section
673
654
  let previewFontSize = LAYOUT.HEADER_FONT_SIZE * 3; // Start with large size
674
- ctx.font = `${previewFontSize}px ${position.font}`;
655
+ const fontToUse = isFontMissing ? LAYOUT.FONT_FAMILY : position.font;
656
+ ctx.font = `${previewFontSize}px ${fontToUse}`;
675
657
  const text = position.text || "";
676
658
  const maxTextWidth = usableWidth * 0.9; // Use 75% of width for better padding
677
659
  const maxTextHeight = actualTopSectionHeight; // Use 60% of height
@@ -679,23 +661,23 @@ const renderStrokePatchesCanvas = (ctx, canvas, config, imageRefs) => {
679
661
  let textWidth = ctx.measureText(text).width;
680
662
  while (textWidth > maxTextWidth && previewFontSize > 50) {
681
663
  previewFontSize *= 0.95;
682
- ctx.font = `${previewFontSize}px ${position.font}`;
664
+ ctx.font = `${previewFontSize}px ${fontToUse}`;
683
665
  textWidth = ctx.measureText(text).width;
684
666
  }
685
667
  // Ensure text height also fits
686
668
  while (previewFontSize > maxTextHeight && previewFontSize > 50) {
687
669
  previewFontSize *= 0.95;
688
- ctx.font = `${previewFontSize}px ${position.font}`;
670
+ ctx.font = `${previewFontSize}px ${fontToUse}`;
689
671
  }
690
672
  // Update textWidth after final scaling
691
673
  textWidth = ctx.measureText(text).width;
692
674
  // Center the text in top section
693
675
  const textX = padding + usableWidth / 2 - textWidth / 2;
694
676
  const textY = actualTopSectionY + actualTopSectionHeight / 2 - previewFontSize / 2;
695
- // Get color hex values
696
- const textColorHex = COLOR_MAP[textColor] || LAYOUT.LABEL_COLOR;
697
- const borderColorHex = COLOR_MAP[borderColor] || LAYOUT.LABEL_COLOR;
698
- const bgColorHex = COLOR_MAP[backgroundColor] || "#FFFFFF";
677
+ // Get color hex values (use render colors with fallback)
678
+ const textColorHex = COLOR_MAP[textColorForRender] || LAYOUT.LABEL_COLOR;
679
+ const borderColorHex = COLOR_MAP[borderColorForRender] || LAYOUT.LABEL_COLOR;
680
+ const bgColorHex = COLOR_MAP[backgroundColorForRender] || "#FFFFFF";
699
681
  // Calculate stroke widths
700
682
  // Background needs to be MUCH thicker to create spacing from text
701
683
  // Border needs to be even thicker to wrap around background
@@ -755,62 +737,142 @@ const renderStrokePatchesCanvas = (ctx, canvas, config, imageRefs) => {
755
737
  const fontPrefix = "Font: ";
756
738
  ctx.font = `${infoFontSize}px ${LAYOUT.FONT_FAMILY}`;
757
739
  ctx.fillText(fontPrefix, startX, infoY);
758
- // Render font name với chính font đó
759
- const prefixWidth = ctx.measureText(fontPrefix).width;
760
- ctx.font = `${infoFontSize}px ${position.font}`;
761
- ctx.fillText(position.font, startX + prefixWidth, infoY);
740
+ if (isFontMissing) {
741
+ // Hiển thị warning màu đỏ nếu thiếu font
742
+ ctx.fillStyle = "#CC0000"; // Red color
743
+ ctx.fillText("(Đang thiếu font chữ)", startX + ctx.measureText(fontPrefix).width, infoY);
744
+ ctx.fillStyle = LAYOUT.LABEL_COLOR; // Reset color
745
+ }
746
+ else {
747
+ // Render font name với chính font đó
748
+ const prefixWidth = ctx.measureText(fontPrefix).width;
749
+ const fontName = position.font || LAYOUT.FONT_FAMILY;
750
+ ctx.font = `${infoFontSize}px ${fontName}`;
751
+ ctx.fillText(fontName, startX + prefixWidth, infoY);
752
+ }
762
753
  infoY += infoLineHeight;
763
754
  // Reset font về mặc định cho các dòng tiếp theo
764
755
  ctx.font = `${infoFontSize}px ${LAYOUT.FONT_FAMILY}`;
765
- // Màu chữ (Text Color)
756
+ // Màu chữ (Text Color) - layer_colors[0]
766
757
  drawAsterisk(padding, infoY);
767
- const textColorLabel = `Màu chữ: ${textColor}`;
768
- ctx.fillText(textColorLabel, startX, infoY);
769
- // Draw text color swatch
770
- const swatchSize = infoFontSize * 1.3; // Giảm từ 1.5 xuống 1.3
771
- const swatchX = startX +
772
- ctx.measureText(textColorLabel).width +
773
- LAYOUT.ELEMENT_SPACING * 0.3; // Giảm spacing
774
- const swatchY = infoY + infoFontSize / 2 - swatchSize / 2;
775
- const textColorSwatchUrl = getImageUrl("threadColor", textColor);
776
- const textColorSwatchImg = imageRefs.current.get(textColorSwatchUrl);
777
- if (textColorSwatchImg?.complete && textColorSwatchImg.naturalHeight > 0) {
778
- const ratio = textColorSwatchImg.naturalWidth / textColorSwatchImg.naturalHeight;
779
- const swatchW = Math.max(1, Math.floor(swatchSize * ratio));
780
- ctx.drawImage(textColorSwatchImg, swatchX, swatchY, swatchW, swatchSize);
758
+ const textColorPrefix = "Màu chữ: ";
759
+ ctx.fillText(textColorPrefix, startX, infoY);
760
+ if (!textColor || textColor.trim() === "") {
761
+ // Hiển thị warning màu đỏ nếu thiếu màu
762
+ const prefixWidth = ctx.measureText(textColorPrefix).width;
763
+ ctx.fillStyle = "#CC0000";
764
+ ctx.fillText("(Chưa màu)", startX + prefixWidth, infoY);
765
+ ctx.fillStyle = LAYOUT.LABEL_COLOR; // Reset color
766
+ }
767
+ else {
768
+ // Hiển thị tên màu
769
+ const prefixWidth = ctx.measureText(textColorPrefix).width;
770
+ ctx.fillText(textColor, startX + prefixWidth, infoY);
771
+ // Draw text color swatch
772
+ const swatchSize = infoFontSize * 1.3;
773
+ const swatchX = startX +
774
+ ctx.measureText(textColorPrefix + textColor).width +
775
+ LAYOUT.ELEMENT_SPACING * 0.3;
776
+ const swatchY = infoY + infoFontSize / 2 - swatchSize / 2;
777
+ const textColorSwatchUrl = getImageUrl("threadColor", textColor);
778
+ const textColorSwatchImg = imageRefs.current.get(textColorSwatchUrl);
779
+ if (textColorSwatchImg?.complete && textColorSwatchImg.naturalHeight > 0) {
780
+ const ratio = textColorSwatchImg.naturalWidth / textColorSwatchImg.naturalHeight;
781
+ const swatchW = Math.max(1, Math.floor(swatchSize * ratio));
782
+ ctx.drawImage(textColorSwatchImg, swatchX, swatchY, swatchW, swatchSize);
783
+ }
784
+ }
785
+ infoY += infoLineHeight;
786
+ // Màu nền (Background Color) - layer_colors[2]
787
+ drawAsterisk(padding, infoY);
788
+ const bgColorPrefix = "Màu nền: ";
789
+ ctx.fillText(bgColorPrefix, startX, infoY);
790
+ if (!backgroundColor || backgroundColor.trim() === "") {
791
+ // Hiển thị warning màu đỏ nếu thiếu màu
792
+ const prefixWidth = ctx.measureText(bgColorPrefix).width;
793
+ ctx.fillStyle = "#CC0000";
794
+ ctx.fillText("(Chưa có màu)", startX + prefixWidth, infoY);
795
+ ctx.fillStyle = LAYOUT.LABEL_COLOR; // Reset color
796
+ }
797
+ else {
798
+ // Hiển thị tên màu
799
+ const prefixWidth = ctx.measureText(bgColorPrefix).width;
800
+ ctx.fillText(backgroundColor, startX + prefixWidth, infoY);
801
+ // Draw background color swatch
802
+ const swatchSize = infoFontSize * 1.3;
803
+ const bgSwatchX = startX +
804
+ ctx.measureText(bgColorPrefix + backgroundColor).width +
805
+ LAYOUT.ELEMENT_SPACING * 0.3;
806
+ const bgSwatchY = infoY + infoFontSize / 2 - swatchSize / 2;
807
+ const bgColorSwatchUrl = getImageUrl("threadColor", backgroundColor);
808
+ const bgColorSwatchImg = imageRefs.current.get(bgColorSwatchUrl);
809
+ if (bgColorSwatchImg?.complete && bgColorSwatchImg.naturalHeight > 0) {
810
+ const ratio = bgColorSwatchImg.naturalWidth / bgColorSwatchImg.naturalHeight;
811
+ const swatchW = Math.max(1, Math.floor(swatchSize * ratio));
812
+ ctx.drawImage(bgColorSwatchImg, bgSwatchX, bgSwatchY, swatchW, swatchSize);
813
+ }
781
814
  }
782
815
  infoY += infoLineHeight;
783
- // Màu nền (Background Color)
784
- drawAsterisk(padding + bottomPadding, infoY);
785
- const bgColorLabel = `Màu nền: ${backgroundColor}`;
786
- ctx.fillText(bgColorLabel, startX, infoY);
787
- // Draw background color swatch
788
- const bgSwatchX = startX + ctx.measureText(bgColorLabel).width + LAYOUT.ELEMENT_SPACING * 0.3;
789
- const bgSwatchY = infoY + infoFontSize / 2 - swatchSize / 2;
790
- const bgColorSwatchUrl = getImageUrl("threadColor", backgroundColor);
791
- const bgColorSwatchImg = imageRefs.current.get(bgColorSwatchUrl);
792
- if (bgColorSwatchImg?.complete && bgColorSwatchImg.naturalHeight > 0) {
793
- const ratio = bgColorSwatchImg.naturalWidth / bgColorSwatchImg.naturalHeight;
794
- const swatchW = Math.max(1, Math.floor(swatchSize * ratio));
795
- ctx.drawImage(bgColorSwatchImg, bgSwatchX, bgSwatchY, swatchW, swatchSize);
816
+ // Màu viền (Border Color) - layer_colors[1]
817
+ drawAsterisk(padding, infoY);
818
+ const borderColorPrefix = "Màu viền: ";
819
+ ctx.fillText(borderColorPrefix, startX, infoY);
820
+ if (!borderColor || borderColor.trim() === "") {
821
+ // Hiển thị warning màu đỏ nếu thiếu màu
822
+ const prefixWidth = ctx.measureText(borderColorPrefix).width;
823
+ ctx.fillStyle = "#CC0000";
824
+ ctx.fillText("(Chưa màu)", startX + prefixWidth, infoY);
825
+ ctx.fillStyle = LAYOUT.LABEL_COLOR; // Reset color
826
+ }
827
+ else {
828
+ // Hiển thị tên màu
829
+ const prefixWidth = ctx.measureText(borderColorPrefix).width;
830
+ ctx.fillText(borderColor, startX + prefixWidth, infoY);
831
+ // Draw border color swatch
832
+ const swatchSize = infoFontSize * 1.3;
833
+ const borderSwatchX = startX +
834
+ ctx.measureText(borderColorPrefix + borderColor).width +
835
+ LAYOUT.ELEMENT_SPACING * 0.3;
836
+ const borderSwatchY = infoY + infoFontSize / 2 - swatchSize / 2;
837
+ const borderColorSwatchUrl = getImageUrl("threadColor", borderColor);
838
+ const borderColorSwatchImg = imageRefs.current.get(borderColorSwatchUrl);
839
+ if (borderColorSwatchImg?.complete &&
840
+ borderColorSwatchImg.naturalHeight > 0) {
841
+ const ratio = borderColorSwatchImg.naturalWidth / borderColorSwatchImg.naturalHeight;
842
+ const swatchW = Math.max(1, Math.floor(swatchSize * ratio));
843
+ ctx.drawImage(borderColorSwatchImg, borderSwatchX, borderSwatchY, swatchW, swatchSize);
844
+ }
796
845
  }
797
846
  infoY += infoLineHeight;
798
- // Màu viền (Border Color)
799
- drawAsterisk(padding + bottomPadding, infoY);
800
- const borderColorLabel = `Màu viền: ${borderColor}`;
801
- ctx.fillText(borderColorLabel, startX, infoY);
802
- // Draw border color swatch
803
- const borderSwatchX = startX +
804
- ctx.measureText(borderColorLabel).width +
805
- LAYOUT.ELEMENT_SPACING * 0.3;
806
- const borderSwatchY = infoY + infoFontSize / 2 - swatchSize / 2;
807
- const borderColorSwatchUrl = getImageUrl("threadColor", borderColor);
808
- const borderColorSwatchImg = imageRefs.current.get(borderColorSwatchUrl);
809
- if (borderColorSwatchImg?.complete &&
810
- borderColorSwatchImg.naturalHeight > 0) {
811
- const ratio = borderColorSwatchImg.naturalWidth / borderColorSwatchImg.naturalHeight;
812
- const swatchW = Math.max(1, Math.floor(swatchSize * ratio));
813
- ctx.drawImage(borderColorSwatchImg, borderSwatchX, borderSwatchY, swatchW, swatchSize);
847
+ // Màu vải (Fabric Color) - layer_colors[3]
848
+ drawAsterisk(padding, infoY);
849
+ const fabricColorPrefix = "Màu vải: ";
850
+ ctx.fillText(fabricColorPrefix, startX, infoY);
851
+ if (!fabricColor || fabricColor.trim() === "") {
852
+ // Hiển thị warning màu đỏ nếu thiếu màu
853
+ const prefixWidth = ctx.measureText(fabricColorPrefix).width;
854
+ ctx.fillStyle = "#CC0000";
855
+ ctx.fillText("(Chưa màu)", startX + prefixWidth, infoY);
856
+ ctx.fillStyle = LAYOUT.LABEL_COLOR; // Reset color
857
+ }
858
+ else {
859
+ // Hiển thị tên màu
860
+ const prefixWidth = ctx.measureText(fabricColorPrefix).width;
861
+ ctx.fillText(fabricColor, startX + prefixWidth, infoY);
862
+ // Draw fabric color swatch
863
+ const swatchSize = infoFontSize * 1.3;
864
+ const fabricSwatchX = startX +
865
+ ctx.measureText(fabricColorPrefix + fabricColor).width +
866
+ LAYOUT.ELEMENT_SPACING * 0.3;
867
+ const fabricSwatchY = infoY + infoFontSize / 2 - swatchSize / 2;
868
+ const fabricColorSwatchUrl = getImageUrl("threadColor", fabricColor);
869
+ const fabricColorSwatchImg = imageRefs.current.get(fabricColorSwatchUrl);
870
+ if (fabricColorSwatchImg?.complete &&
871
+ fabricColorSwatchImg.naturalHeight > 0) {
872
+ const ratio = fabricColorSwatchImg.naturalWidth / fabricColorSwatchImg.naturalHeight;
873
+ const swatchW = Math.max(1, Math.floor(swatchSize * ratio));
874
+ ctx.drawImage(fabricColorSwatchImg, fabricSwatchX, fabricSwatchY, swatchW, swatchSize);
875
+ }
814
876
  }
815
877
  infoY += infoLineHeight;
816
878
  // Attachment