feat(m4): fixed tape line for length calibration (#99)

The photo pans, zooms, and tilts under a line that stays in the middle
of the frame. Scale is the source-pixel distance between the ticks
divided by the declared length, not the mask span.
This commit is contained in:
Ty
2026-09-24 17:56:21 -07:00
parent d49ff2fab5
commit 6000ac2b0f
23 changed files with 643 additions and 1019 deletions
+2 -11
View File
@@ -3,7 +3,6 @@
import type { Capture } from './capture.types';
import { inToEighths, eighthsToIn } from './capture.types';
import { fmtEighths } from './session';
import { calibrationScale } from '../png/crop';
import PhotoStage from './PhotoStage.svelte';
import {
buildPhotosReadyLineup,
@@ -55,12 +54,6 @@
return Number.isFinite(inches) && inches > 0 ? inches : null;
};
$: tapeScale = calibrationScale(
state.axis.tapeLine.start,
state.axis.tapeLine.end,
positiveInches(String(lengthIn)) ?? 0,
);
const commitLength = () => {
const inches = positiveInches(String(lengthIn));
const eighths = inches === null ? 0 : inToEighths(inches);
@@ -74,7 +67,7 @@
thicknessIn = eighths === 0 ? '' : String(eighthsToIn(eighths));
};
$: canCalc = positiveInches(String(lengthIn)) !== null && positiveInches(String(thicknessIn)) !== null && tapeScale > 0;
$: canCalc = positiveInches(String(lengthIn)) !== null && positiveInches(String(thicknessIn)) !== null;
const doCalc = async () => {
calcBusy = true;
@@ -100,7 +93,7 @@
<div class="fields">
<div class="field">
<span class="label">Tape length L (distance between ticks)</span>
<span class="label">Length L (tape reading)</span>
<input
type="number"
aria-label="Length L"
@@ -128,7 +121,6 @@
/>
</div>
</div>
<p class="scale">Tape ticks: {Math.hypot(state.axis.tapeLine.end[0] - state.axis.tapeLine.start[0], state.axis.tapeLine.end[1] - state.axis.tapeLine.start[1]).toFixed(1)} source-photo px · Scale {tapeScale.toFixed(2)} px/in</p>
<div class="row">
<button type="button" class="ghost" on:click={back}>Back</button>
@@ -202,7 +194,6 @@
.fields { display: flex; gap: 16px; margin-top: 16px; }
.field { flex: 1; }
.label { display: block; font-size: 0.9rem; color: #aaa; margin-bottom: 8px; }
.scale { margin: 8px 0 0; color: #aaa; font-size: 0.85rem; font-variant-numeric: tabular-nums; }
.field input {
box-sizing: border-box; width: 100%; min-height: 52px; padding: 12px; font-size: 1rem;
border-radius: 10px; border: 1px solid #444; background: #1d1d1d; color: #eee;