screengraft 0.54.1 → 0.54.2
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/package.json +1 -1
- package/ui/index.html +38 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "screengraft",
|
|
3
|
-
"version": "0.54.
|
|
3
|
+
"version": "0.54.2",
|
|
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
|
@@ -2655,6 +2655,10 @@ $('#dofMeasure').onclick = measureDof;
|
|
|
2655
2655
|
const gz = $('#dofGizmo');
|
|
2656
2656
|
const SIGMA_FULL_FRAC = 0.02; // mirrors dof.DOF_MAX_FRAC -- keep in step
|
|
2657
2657
|
let dofEnd = parseFloat(recall('dofEnd','1')); if (!(dofEnd > 0)) dofEnd = 1;
|
|
2658
|
+
// Where along the lines the handles sit (0..1 across the screen's extent).
|
|
2659
|
+
// Page-only: it changes nothing in the render. Turning re-derives it so the
|
|
2660
|
+
// handle stays on the point you turned about instead of sliding along the line.
|
|
2661
|
+
let dofK = 0.5;
|
|
2658
2662
|
// The near limit. null = one-sided (the plane of focus at the screen's edge).
|
|
2659
2663
|
let dofEnd2 = recall('dofEnd2','') === '' ? null : parseFloat(recall('dofEnd2','')); if (dofEnd2 !== null && !(dofEnd2 < 1)) dofEnd2 = null;
|
|
2660
2664
|
function dofEndV(){ return dofOn ? dofEnd : 1; }
|
|
@@ -2695,10 +2699,10 @@ function paintGizmo(){
|
|
|
2695
2699
|
const k = W / Math.max(im.clientWidth, 1); // photo px per screen px
|
|
2696
2700
|
const g = gizmoGeom(); if (!g.H || !g.Hi) return;
|
|
2697
2701
|
const P = (f, q) => applyH(g.H, gzPt(g, f, q));
|
|
2698
|
-
const a0 = P(dofStart, -0.06), a1 = P(dofStart, 1.06), ac = P(dofStart,
|
|
2699
|
-
const b0 = P(dofEnd, -0.06), b1 = P(dofEnd, 1.06), bc = P(dofEnd,
|
|
2702
|
+
const a0 = P(dofStart, -0.06), a1 = P(dofStart, 1.06), ac = P(dofStart, dofK);
|
|
2703
|
+
const b0 = P(dofEnd, -0.06), b1 = P(dofEnd, 1.06), bc = P(dofEnd, dofK);
|
|
2700
2704
|
const two = dofEnd2 !== null;
|
|
2701
|
-
const c0 = two ? P(dofEnd2, -0.06) : null, c1 = two ? P(dofEnd2, 1.06) : null, cc = two ? P(dofEnd2,
|
|
2705
|
+
const c0 = two ? P(dofEnd2, -0.06) : null, c1 = two ? P(dofEnd2, 1.06) : null, cc = two ? P(dofEnd2, dofK) : null;
|
|
2702
2706
|
const th = P(dofEnd, 0.08 + 0.84 * dofStr); // the strength thumb slides along the dashed line
|
|
2703
2707
|
const sigma = dofStr * SIGMA_FULL_FRAC * g.side;
|
|
2704
2708
|
const r = 6 * k, rp = 4 * k, fs11 = 11 * k, off = 14 * k;
|
|
@@ -2733,7 +2737,19 @@ let gzDrag = null;
|
|
|
2733
2737
|
gz.addEventListener('pointerdown', e => {
|
|
2734
2738
|
const h = e.target.dataset && e.target.dataset.h; if (!h) return;
|
|
2735
2739
|
e.preventDefault(); gz.setPointerCapture(e.pointerId);
|
|
2736
|
-
gzDrag = {h};
|
|
2740
|
+
gzDrag = {h};
|
|
2741
|
+
if (h === 'rotA' || h === 'rotB'){
|
|
2742
|
+
// Turning keeps the SHARP line's centre where it is on the screen and the
|
|
2743
|
+
// limits at their distances from it, in screenshot pixels. The stored
|
|
2744
|
+
// numbers are fractions of the screen's extent along the direction, and
|
|
2745
|
+
// that extent changes with the angle -- so turning on the fractions alone
|
|
2746
|
+
// slid every line as it turned (reported 13 Sep 2026).
|
|
2747
|
+
const g = gizmoGeom();
|
|
2748
|
+
gzDrag.pivot = gzPt(g, dofStart, dofK);
|
|
2749
|
+
gzDrag.dFar = (dofEnd - dofStart) * (g.hi - g.lo);
|
|
2750
|
+
gzDrag.dNear = dofEnd2 === null ? null : (dofStart - dofEnd2) * (g.hi - g.lo);
|
|
2751
|
+
}
|
|
2752
|
+
gz.classList.add('drag');
|
|
2737
2753
|
});
|
|
2738
2754
|
gz.addEventListener('pointermove', e => {
|
|
2739
2755
|
if (!gzDrag) return;
|
|
@@ -2752,11 +2768,26 @@ gz.addEventListener('pointermove', e => {
|
|
|
2752
2768
|
} else {
|
|
2753
2769
|
// Turn about the SHARP line's centre -- the plane of focus is what turns;
|
|
2754
2770
|
// the pip under the pointer follows.
|
|
2755
|
-
const c =
|
|
2771
|
+
const c = gzDrag.pivot;
|
|
2756
2772
|
const v = [p[0]-c[0], p[1]-c[1]];
|
|
2757
2773
|
const sign = gzDrag.h === 'rotB' ? 1 : -1; // rotB sits at +u, rotA at -u
|
|
2758
|
-
|
|
2759
|
-
if (e.shiftKey)
|
|
2774
|
+
let ang = ((Math.atan2(v[1]*sign, v[0]*sign) * 180 / Math.PI - 90) % 360 + 360) % 360;
|
|
2775
|
+
if (e.shiftKey) ang = Math.round(ang / 15) * 15;
|
|
2776
|
+
else {
|
|
2777
|
+
// Magnetic to the screen's own axes: within 4° of 0/90/180/270 the lines
|
|
2778
|
+
// run exactly along the screen's edges, which is what "along the phone"
|
|
2779
|
+
// means in the photograph once the perspective is applied.
|
|
2780
|
+
const near = Math.round(ang / 90) * 90;
|
|
2781
|
+
if (Math.abs(((ang - near) + 180) % 360 - 180) < 4) ang = near % 360;
|
|
2782
|
+
}
|
|
2783
|
+
dofAng = ang;
|
|
2784
|
+
// Re-express the lines against the new extent so nothing moves but the angle.
|
|
2785
|
+
const g2 = gizmoGeom();
|
|
2786
|
+
const f0 = (c[0]*g2.d[0] + c[1]*g2.d[1] - g2.lo) / (g2.hi - g2.lo);
|
|
2787
|
+
dofStart = Math.max(0, Math.min(0.95, f0));
|
|
2788
|
+
dofK = Math.max(0.05, Math.min(0.95, (c[0]*g2.u[0] + c[1]*g2.u[1] - g2.ulo) / (g2.uhi - g2.ulo)));
|
|
2789
|
+
dofEnd = Math.max(dofStart + 0.05, Math.min(1.5, dofStart + gzDrag.dFar / (g2.hi - g2.lo)));
|
|
2790
|
+
if (dofEnd2 !== null) dofEnd2 = Math.max(-0.5, Math.min(dofStart - 0.05, dofStart - gzDrag.dNear / (g2.hi - g2.lo)));
|
|
2760
2791
|
}
|
|
2761
2792
|
paintDof(); paintGizmo(); autoPreview();
|
|
2762
2793
|
});
|