screengraft 0.63.6 → 0.63.7

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/ui/index.html +10 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "screengraft",
3
- "version": "0.63.6",
3
+ "version": "0.63.7",
4
4
  "description": "Put a UI screenshot or screen recording onto a photographed device screen with the perspective exactly right \u2014 a homography you confirm by hand, not a generative guess.",
5
5
  "keywords": [
6
6
  "mockup",
package/ui/index.html CHANGED
@@ -2565,15 +2565,20 @@ function ringColour(rgb){ let b = rgb.map(v => v/255);
2565
2565
  return 'rgb(' + b.map(v => Math.round(Math.max(0, Math.min(1, v))*255)).join(',') + ')'; }
2566
2566
  // One small copy of each pane's picture to sample from (a readback per draw,
2567
2567
  // not per pixel). Fit pane: the canvas; result pane: the composite <img>.
2568
+ const WELL_RGB = [10,10,11]; // --well, what is under a rail that is not over the picture
2568
2569
  const _sampleCv = document.createElement('canvas'), _sampleCx = _sampleCv.getContext('2d', {willReadFrequently: true});
2569
2570
  function _backdropSampler(source, rect){
2570
2571
  const W = 256, H = Math.max(1, Math.round(256 * rect.height / Math.max(rect.width, 1)));
2571
2572
  _sampleCv.width = W; _sampleCv.height = H;
2572
2573
  try { _sampleCx.drawImage(source, 0, 0, W, H); } catch (e) { return null; }
2573
2574
  const data = _sampleCx.getImageData(0, 0, W, H).data;
2574
- return (x, y) => { const px = Math.max(0, Math.min(W-1, Math.round((x - rect.left) * W / rect.width)));
2575
- const py = Math.max(0, Math.min(H-1, Math.round((y - rect.top) * H / rect.height)));
2576
- const i = (py*W + px) * 4; return data[i+3] ? [data[i], data[i+1], data[i+2]] : null; };
2575
+ // A point outside the picture is over the well, not over the picture's
2576
+ // nearest edge -- clamping put the left rail on the photo's bright edge
2577
+ // column and painted it light (Safari, 14 Sep 2026).
2578
+ return (x, y) => { if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) return WELL_RGB;
2579
+ const px = Math.max(0, Math.min(W-1, Math.floor((x - rect.left) * W / rect.width)));
2580
+ const py = Math.max(0, Math.min(H-1, Math.floor((y - rect.top) * H / rect.height)));
2581
+ const i = (py*W + px) * 4; return data[i+3] ? [data[i], data[i+1], data[i+2]] : WELL_RGB; };
2577
2582
  }
2578
2583
  function _sideColours(sample, r, out){
2579
2584
  const N = 9, sides = {top: [], right: [], bottom: [], left: []};
@@ -2581,7 +2586,7 @@ function _sideColours(sample, r, out){
2581
2586
  sides.top.push(sample(r.left + r.width*t, r.top - 1)); sides.bottom.push(sample(r.left + r.width*t, r.bottom + 1));
2582
2587
  sides.left.push(sample(r.left - 1, r.top + r.height*t)); sides.right.push(sample(r.right + 1, r.top + r.height*t)); }
2583
2588
  for (const [side, pts] of Object.entries(sides)){ const ok = pts.filter(Boolean);
2584
- const avg = ok.length ? [0,1,2].map(i => ok.reduce((a, p) => a + p[i], 0) / ok.length) : [11,11,11];
2589
+ const avg = ok.length ? [0,1,2].map(i => ok.reduce((a, p) => a + p[i], 0) / ok.length) : WELL_RGB;
2585
2590
  out.style['border' + side[0].toUpperCase() + side.slice(1) + 'Color'] = ringColour(avg); }
2586
2591
  }
2587
2592
  let _ringsQueued = false;
@@ -2597,7 +2602,7 @@ function paintRingsFallback(){
2597
2602
  const sample = ok && rect.width > 0 ? _backdropSampler(src, rect) : null;
2598
2603
  pane.querySelectorAll('.bgroup > .ring.lift, .pillwrap > .ring.lift').forEach(ring => {
2599
2604
  const r = ring.parentElement.getBoundingClientRect();
2600
- if (sample) _sideColours(sample, r, ring); else ['Top','Right','Bottom','Left'].forEach(sd => ring.style['border' + sd + 'Color'] = ringColour([11,11,11]));
2605
+ if (sample) _sideColours(sample, r, ring); else ['Top','Right','Bottom','Left'].forEach(sd => ring.style['border' + sd + 'Color'] = ringColour(WELL_RGB));
2601
2606
  });
2602
2607
  }
2603
2608
  });