[object Object]

← back to Wallco Ai

curator: equal-size left/right panes (shared imgSize) + corner-drag resize grips

ed63d9b2f8bed3fc7bd90df8546969ccea0151d3 · 2026-05-27 16:47:50 -0700 · Steve Abrams

Both flat tile and room render at the same square imgSize; drag the corner grip
on either pane to grow/shrink both together (persisted). Stage scrolls if large.

Files touched

Diff

commit ed63d9b2f8bed3fc7bd90df8546969ccea0151d3
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Wed May 27 16:47:50 2026 -0700

    curator: equal-size left/right panes (shared imgSize) + corner-drag resize grips
    
    Both flat tile and room render at the same square imgSize; drag the corner grip
    on either pane to grow/shrink both together (persisted). Stage scrolls if large.
---
 public/admin/drunk-curator.html | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/public/admin/drunk-curator.html b/public/admin/drunk-curator.html
index ffac996..a90022d 100644
--- a/public/admin/drunk-curator.html
+++ b/public/admin/drunk-curator.html
@@ -12,9 +12,10 @@
   h1{font-size:16px;margin:0;font-weight:650;} h1 small{color:var(--mut);font-weight:400;}
   .stats{margin-left:auto;display:flex;gap:18px;font-size:13px;color:var(--mut);font-variant-numeric:tabular-nums;}
   .stats b{color:var(--ink);} .streak{color:var(--hot);}
-  .stage{display:flex;flex-direction:column;align-items:center;height:calc(100vh - 56px);padding:14px;gap:10px;}
+  .stage{display:flex;flex-direction:column;align-items:center;height:calc(100vh - 56px);padding:14px;gap:10px;overflow:auto;}
   .panes{display:grid;grid-template-columns:1fr 1fr;gap:16px;width:min(96vw,1100px);height:min(60vh,540px);}
   .pane{position:relative;border-radius:14px;overflow:hidden;border:1px solid var(--line);background:#000;}
+  .rsz{position:absolute;right:1px;bottom:1px;width:20px;height:20px;z-index:10;cursor:nwse-resize;background:linear-gradient(135deg,transparent 44%,rgba(255,255,255,.55) 44% 54%,transparent 54% 66%,rgba(255,255,255,.55) 66% 76%,transparent 76%);}
   .pane .tag{position:absolute;top:8px;left:10px;z-index:3;font-size:10px;letter-spacing:.08em;text-transform:uppercase;color:#fff;background:rgba(0,0,0,.45);padding:2px 8px;border-radius:20px;backdrop-filter:blur(4px);}
   /* left: flat tile — fill exactly so auto-ID error boxes map 1:1 to the image */
   .tile{width:100%;height:100%;object-fit:fill;display:block;}
@@ -149,6 +150,14 @@ function toggleFS(){
   if(!document.fullscreenElement){ (el.requestFullscreen||el.webkitRequestFullscreen||function(){}).call(el); }
   else { (document.exitFullscreen||document.webkitExitFullscreen||function(){}).call(document); }
 }
+// Shared display square for BOTH panes (flat tile == room), user-resizable by
+// dragging the corner grips. Persisted.
+let imgSize = Math.max(220, Math.min(900, parseInt(localStorage.getItem('drunk_imgsize')) || Math.round(Math.min(window.innerHeight*0.55, 480))));
+function setImgSize(n){ imgSize = Math.max(220, Math.min(900, Math.round(n))); localStorage.setItem('drunk_imgsize', imgSize); applyScale(); }
+let _rsz=null;
+function startResize(e){ e.preventDefault(); e.stopPropagation(); _rsz={x:e.clientX, y:e.clientY, s:imgSize}; document.body.style.userSelect='none'; }
+addEventListener('mousemove', e=>{ if(!_rsz) return; setImgSize(_rsz.s + ((e.clientX-_rsz.x)+(e.clientY-_rsz.y))/2); });
+addEventListener('mouseup', ()=>{ if(_rsz){ _rsz=null; document.body.style.userSelect=''; } });
 const FURN = ['console', 'sofa', 'bed'];  // furniture silhouettes the "Furniture" button cycles for staging/scale
 let furnIdx = (parseInt(localStorage.getItem('drunk_furn')) || 0) % FURN.length;
 // "Furniture" → render a REAL furnished room scene for THIS design via /api/room
@@ -226,12 +235,8 @@ function applyScale(){
 // derived from the rendered wall's aspect so the ruler matches what's shown.
 function drawRoomRulers(){
   const room=document.getElementById('room'); if(!room) return;
-  const row=room.closest('.roomrow'), pane=room.closest('.pane');
-  const btns=row?row.querySelector('.roombtns'):null;
-  // force the room SQUARE → true 12′×12′; side fits the pane minus the button column
-  const availW=(row?row.clientWidth:room.clientWidth)-(btns?btns.offsetWidth:0)-16;
-  const availH=(pane?pane.clientHeight:room.clientHeight)-26;
-  const side=Math.max(180, Math.min(availW, availH));
+  // room is the SAME square size as the flat tile (shared imgSize, resizable)
+  const side=imgSize;
   room.style.width=side+'px'; room.style.height=side+'px';
   const ppi=side/WALL_INCHES;
   // vertical pinstripe lines at each pattern-repeat boundary + a repeat count
@@ -356,7 +361,7 @@ function render(){
   const d=QUEUE[i], src=`/designs/img/by-id/${d.id}`;
   $('#stage').innerHTML=`
     <div class="panes">
-      <div class="pane"><span class="tag">flat tile · pattern <span id="scaleval">${scaleInches}</span>″ × <span id="scalevalh">${scaleInches}</span>″ (in)</span>
+      <div class="pane"><div class="rsz" onmousedown="startResize(event)" title="drag corner to resize both"></div><span class="tag">flat tile · pattern <span id="scaleval">${scaleInches}</span>″ × <span id="scalevalh">${scaleInches}</span>″ (in)</span>
         <div class="scalewrap">
           <div class="tilebox">
             <div class="ruler vert" id="rulerV"></div>
@@ -365,7 +370,7 @@ function render(){
           <div class="ruler" id="ruler"></div>
         </div>
       </div>
-      <div class="pane"><span class="tag" id="roomtag">room setting · 12′ × 12′ room (ft·in)</span>
+      <div class="pane"><div class="rsz" onmousedown="startResize(event)" title="drag corner to resize both"></div><span class="tag" id="roomtag">room setting · 12′ × 12′ room (ft·in)</span>
         <div class="roomrow">
           <div class="room" id="room">
             <div class="wall" style="background-image:url('${src}')"></div>

← 7bc6023 TODO: mark geometric-block-leaves reroll done (19 SVG tessel  ·  back to Wallco Ai  ·  geom tessellation: add --palette colorways; generate terraco f02d8c5 →