@primestyleai/tryon 3.6.4 → 3.6.6

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.
@@ -261,11 +261,11 @@ function PrimeStyleTryonInner({
261
261
  const progressBarRef = useRef(null);
262
262
  const progressTextRef = useRef(null);
263
263
  const progressStatusRef = useRef(null);
264
+ const progressIntervalRef = useRef(null);
264
265
  useEffect(() => {
265
266
  if (view === "processing") {
267
+ if (progressIntervalRef.current) return;
266
268
  progressRef.current = 0;
267
- if (progressBarRef.current) progressBarRef.current.style.width = "0%";
268
- if (progressTextRef.current) progressTextRef.current.textContent = "0%";
269
269
  const statuses = [
270
270
  { at: 0, text: "Preparing your image..." },
271
271
  { at: 15, text: "Analyzing body proportions..." },
@@ -274,7 +274,7 @@ function PrimeStyleTryonInner({
274
274
  { at: 75, text: "Refining details..." },
275
275
  { at: 90, text: "Almost there..." }
276
276
  ];
277
- const interval = setInterval(() => {
277
+ progressIntervalRef.current = setInterval(() => {
278
278
  const p = progressRef.current;
279
279
  if (p >= 100) return;
280
280
  const increment = p < 30 ? 1.2 : p < 60 ? 0.8 : p < 80 ? 0.4 : p < 95 ? 0.15 : 0;
@@ -287,7 +287,15 @@ function PrimeStyleTryonInner({
287
287
  if (status) progressStatusRef.current.textContent = status.text;
288
288
  }
289
289
  }, 200);
290
- return () => clearInterval(interval);
290
+ return () => {
291
+ clearInterval(progressIntervalRef.current);
292
+ progressIntervalRef.current = null;
293
+ };
294
+ } else {
295
+ if (progressIntervalRef.current) {
296
+ clearInterval(progressIntervalRef.current);
297
+ progressIntervalRef.current = null;
298
+ }
291
299
  }
292
300
  }, [view]);
293
301
  useEffect(() => {
@@ -814,6 +822,7 @@ function PrimeStyleTryonInner({
814
822
  function UploadView() {
815
823
  return /* @__PURE__ */ jsx(Fragment, { children: selectedFile && previewUrl ? /* @__PURE__ */ jsxs(Fragment, { children: [
816
824
  /* @__PURE__ */ jsxs("div", { className: cx("ps-tryon-preview", cn.preview), children: [
825
+ /* @__PURE__ */ jsx("div", { className: "ps-tryon-preview-blur", style: { backgroundImage: `url(${previewUrl})` } }),
817
826
  /* @__PURE__ */ jsx("img", { src: previewUrl, alt: "Your photo", className: cn.previewImage }),
818
827
  /* @__PURE__ */ jsx("button", { onClick: handleRemovePreview, className: cx("ps-tryon-preview-remove", cn.removeButton), children: "×" })
819
828
  ] }),
@@ -1070,6 +1079,17 @@ function PrimeStyleTryonInner({
1070
1079
  ] }, `form-${formGender}-${sizingUnit}-${heightUnit}-${sizingCountry}-${formKey}`);
1071
1080
  }
1072
1081
  function ProcessingView() {
1082
+ const barCb = useCallback((el) => {
1083
+ progressBarRef.current = el;
1084
+ if (el) el.style.width = `${Math.round(progressRef.current)}%`;
1085
+ }, []);
1086
+ const pctCb = useCallback((el) => {
1087
+ progressTextRef.current = el;
1088
+ if (el) el.textContent = `${Math.round(progressRef.current)}%`;
1089
+ }, []);
1090
+ const statusCb = useCallback((el) => {
1091
+ progressStatusRef.current = el;
1092
+ }, []);
1073
1093
  return /* @__PURE__ */ jsxs("div", { className: "ps-tryon-processing", children: [
1074
1094
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-processing-image-wrap", children: [
1075
1095
  previewUrl && /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -1080,10 +1100,10 @@ function PrimeStyleTryonInner({
1080
1100
  /* @__PURE__ */ jsx("div", { className: "ps-tryon-scan-overlay" })
1081
1101
  ] }),
1082
1102
  /* @__PURE__ */ jsxs("div", { className: "ps-tryon-progress-section", children: [
1083
- /* @__PURE__ */ jsx("div", { className: "ps-tryon-progress-bar-wrap", children: /* @__PURE__ */ jsx("div", { ref: progressBarRef, className: "ps-tryon-progress-bar-fill" }) }),
1084
- /* @__PURE__ */ jsx("span", { ref: progressTextRef, className: "ps-tryon-progress-pct", children: "0%" })
1103
+ /* @__PURE__ */ jsx("div", { className: "ps-tryon-progress-bar-wrap", children: /* @__PURE__ */ jsx("div", { ref: barCb, className: "ps-tryon-progress-bar-fill" }) }),
1104
+ /* @__PURE__ */ jsx("span", { ref: pctCb, className: "ps-tryon-progress-pct", children: "0%" })
1085
1105
  ] }),
1086
- /* @__PURE__ */ jsx("div", { ref: progressStatusRef, className: cx("ps-tryon-processing-text", cn.processingText), children: "Preparing your image..." }),
1106
+ /* @__PURE__ */ jsx("div", { ref: statusCb, className: cx("ps-tryon-processing-text", cn.processingText), children: "Preparing your image..." }),
1087
1107
  /* @__PURE__ */ jsx("p", { className: cx("ps-tryon-processing-sub", cn.processingSubText), children: "This usually takes 15-25 seconds" })
1088
1108
  ] });
1089
1109
  }
@@ -1456,8 +1476,16 @@ const STYLES = `
1456
1476
  .ps-tryon-upload svg { color: var(--ps-upload-icon-color, #bb945c); margin-bottom: clamp(7px, 0.63vw, 12px); }
1457
1477
  .ps-tryon-upload-text { font-size: clamp(10px, 0.73vw, 14px); color: var(--ps-upload-color, #fff); margin: 0 0 clamp(2px, 0.21vw, 4px); }
1458
1478
  .ps-tryon-upload-hint { font-size: clamp(9px, 0.63vw, 12px); color: #999; margin: 0; }
1459
- .ps-tryon-preview { position: relative; margin-bottom: clamp(2px, 0.21vw, 4px); }
1460
- .ps-tryon-preview img { width: 100%; border-radius: clamp(8px, 0.63vw, 12px); display: block; }
1479
+ .ps-tryon-preview {
1480
+ position: relative; margin-bottom: clamp(2px, 0.21vw, 4px);
1481
+ height: clamp(280px, 20vw, 380px); border-radius: clamp(8px, 0.63vw, 12px);
1482
+ overflow: hidden; background: #0a0a0a;
1483
+ }
1484
+ .ps-tryon-preview-blur {
1485
+ position: absolute; inset: -20px; background-size: cover; background-position: center;
1486
+ filter: blur(25px) brightness(0.4); transform: scale(1.2);
1487
+ }
1488
+ .ps-tryon-preview img { position: relative; z-index: 1; width: 100%; height: 100%; object-fit: contain; display: block; }
1461
1489
  .ps-tryon-preview-remove {
1462
1490
  position: absolute; top: clamp(5px, 0.42vw, 8px); right: clamp(5px, 0.42vw, 8px); width: clamp(20px, 1.46vw, 28px); height: clamp(20px, 1.46vw, 28px);
1463
1491
  border-radius: 50%; background: rgba(0,0,0,0.6); border: none; color: white;
@@ -1860,6 +1888,7 @@ const STYLES = `
1860
1888
  .ps-tryon-modal-wide { max-width: 100%; }
1861
1889
  .ps-tryon-modal > :last-child { flex: 1; }
1862
1890
  .ps-tryon-header { border-radius: 0; }
1891
+ .ps-tryon-preview { height: 320px; }
1863
1892
  }
1864
1893
  @media (max-width: 720px) {
1865
1894
  .ps-tryon-result-split { flex-direction: column; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primestyleai/tryon",
3
- "version": "3.6.4",
3
+ "version": "3.6.6",
4
4
  "description": "PrimeStyle Virtual Try-On SDK — React component & Web Component",
5
5
  "type": "module",
6
6
  "main": "dist/primestyle-tryon.js",