[object Object]

← back to Wallco Ai

color-dots: Save targets the last-recolored image, not the toolbar's bound img

35354263a3a53225b99f3ca51bcbc2c8f76c1172 · 2026-06-02 08:36:47 -0700 · Steve Abrams

Fix 'colorway not saving' / false 'Recolor a dot first' on PDPs with multiple
/designs/img/ instances (detail-img + edit-preview-img + cf-img). The save
toolbar binds once (window._cdBarDone) to the first qualifying image, but the
user may recolor a different image's dot strip — currentInkMap(boundImg) then
shows no change and the save bails. Now track lastTouched in recolor() and have
save read its inkMap + bake its PNG. Confirmed via design 56254 (Steve).

Files touched

Diff

commit 35354263a3a53225b99f3ca51bcbc2c8f76c1172
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Jun 2 08:36:47 2026 -0700

    color-dots: Save targets the last-recolored image, not the toolbar's bound img
    
    Fix 'colorway not saving' / false 'Recolor a dot first' on PDPs with multiple
    /designs/img/ instances (detail-img + edit-preview-img + cf-img). The save
    toolbar binds once (window._cdBarDone) to the first qualifying image, but the
    user may recolor a different image's dot strip — currentInkMap(boundImg) then
    shows no change and the save bails. Now track lastTouched in recolor() and have
    save read its inkMap + bake its PNG. Confirmed via design 56254 (Steve).
---
 public/js/color-dots.js | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/public/js/color-dots.js b/public/js/color-dots.js
index 3739c5b..3a545c1 100644
--- a/public/js/color-dots.js
+++ b/public/js/color-dots.js
@@ -7,6 +7,11 @@
   'use strict';
   var DOT_COUNT = 6, MIN_W = 150, MAXW = 720;   // cap working res for fast recolor
   var state = new WeakMap();                      // img -> { base, idx, inks, cur, w, h }
+  var lastTouched = null;                         // most-recently recolored img — Save targets THIS,
+                                                  // not the toolbar's statically-bound img (the PDP has
+                                                  // several /designs/img/ instances, each with its own
+                                                  // strip; the user may recolor a different one than the
+                                                  // toolbar bound to → "Recolor a dot first" false-negative).
 
   function isPattern(img) {
     var s = img.currentSrc || img.src || '';
@@ -64,6 +69,7 @@
 
   function recolor(img) {
     var st = state.get(img); if (!st) return;
+    lastTouched = img;
     var out = new ImageData(new Uint8ClampedArray(st.base.data), st.w, st.h);
     var bd = st.base.data, od = out.data, idx = st.idx, inks = st.inks, cur = st.cur;
     for (var p = 0, q = 0; p < bd.length; p += 4, q++) {
@@ -343,8 +349,8 @@
     // image may have been downscaled to MAXW for live preview. Re-render here
     // at the same dimensions used for preview — that's what the user actually
     // recolored and saw. Returns null if state is missing.
-    function bakeCurrentPng() {
-      var st = state.get(img); if (!st) return null;
+    function bakeCurrentPng(bImg) {
+      var st = state.get(bImg); if (!st) return null;
       var c = document.createElement('canvas'); c.width = st.w; c.height = st.h;
       var out = new ImageData(new Uint8ClampedArray(st.base.data), st.w, st.h);
       var bd = st.base.data, od = out.data, idx = st.idx, inks = st.inks, cur = st.cur;
@@ -358,12 +364,16 @@
       try { return c.toDataURL('image/png'); } catch (e) { return null; }
     }
     save.addEventListener('click', function () {
-      var st = state.get(img); if (!st) return;
-      var changed = currentInkMap(img).filter(function (m) { return m.from !== m.to; });
+      // Target the image the user actually recolored (lastTouched), falling back
+      // to the toolbar's bound img. Fixes the false "Recolor a dot first" when the
+      // recolored strip belongs to a different /designs/img/ instance than `img`.
+      var tImg = (lastTouched && state.get(lastTouched)) ? lastTouched : img;
+      var st = state.get(tImg); if (!st) return;
+      var changed = currentInkMap(tImg).filter(function (m) { return m.from !== m.to; });
       if (!changed.length) { toast(host, 'Recolor a dot first'); return; }
       save.disabled = true; save.textContent = 'Saving…';
-      var dataUrl = bakeCurrentPng();   // omit on failure; server will skip promote
-      var body = { design_id: did, ink_map: currentInkMap(img) };
+      var dataUrl = bakeCurrentPng(tImg);   // omit on failure; server will skip promote
+      var body = { design_id: did, ink_map: currentInkMap(tImg) };
       if (dataUrl) body.data_url = dataUrl;
       fetch('/api/colorways/save', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'same-origin',
         body: JSON.stringify(body) })

← 0bbf5ba PDP: '✓ smart-fix → #child' pill linking a design to its pub  ·  back to Wallco Ai  ·  PDP: mtime cache-bust /js/color-dots.js so JS fixes land on ad8604f →