fix(capture): ±90° tilt slider midpoint + two-finger rotate
Clamp tape tilt to [-90, 90] so the slider knob starts centered and CCW works. PhotoStage pinch now tracks angle as well as zoom.
This commit is contained in:
@@ -12,7 +12,7 @@ import { encodeInventoryPng, type InventoryInput } from '../png/inventory';
|
||||
import { encodeOverlayPng, type EncodeOverlayInput } from '../png/overlay';
|
||||
import { rotateCalibration } from '../png/rotateCal';
|
||||
import { decodeOrientedBitmap } from '../decodeOrientedBitmap';
|
||||
import { defaultTape, tapeEndpoints, type TapeTransform } from './tapeGeometry';
|
||||
import { clampTiltDeg, defaultTape, tapeEndpoints, type TapeTransform } from './tapeGeometry';
|
||||
import { getCropFill } from '../settings/cropFill';
|
||||
import type { TapeLine } from './capture.types';
|
||||
|
||||
@@ -323,7 +323,7 @@ export function createCaptureSession(opts: SessionOpts = {}): CaptureSession {
|
||||
return { ...d.tape };
|
||||
}
|
||||
// Seed tilt so the mask long side sits near vertical under the fixed line.
|
||||
const seedTilt = 90 - bbox.angleDeg;
|
||||
const seedTilt = clampTiltDeg(90 - bbox.angleDeg);
|
||||
const t = defaultTape(getCropFill(), seedTilt);
|
||||
const ep = w > 0 && h > 0 ? tapeEndpoints(t, w, h) : { spanPx: 0, start: [0, 0] as [number, number], end: [0, 0] as [number, number], ux: 0, uy: 1 };
|
||||
return { ...t, spanPx: ep.spanPx };
|
||||
@@ -338,7 +338,7 @@ export function createCaptureSession(opts: SessionOpts = {}): CaptureSession {
|
||||
: bbox.angleDeg;
|
||||
const nextBbox = orientedRect(bbox, angleDeg);
|
||||
const line: TapeLine = {
|
||||
tiltDeg: tape.tiltDeg,
|
||||
tiltDeg: clampTiltDeg(tape.tiltDeg),
|
||||
zoom: tape.zoom,
|
||||
panX: tape.panX,
|
||||
panY: tape.panY,
|
||||
@@ -534,7 +534,7 @@ export function createCaptureSession(opts: SessionOpts = {}): CaptureSession {
|
||||
};
|
||||
const w = state.source.widthPx;
|
||||
const h = state.source.heightPx;
|
||||
const seedTilt = 90 - bbox.angleDeg;
|
||||
const seedTilt = clampTiltDeg(90 - bbox.angleDeg);
|
||||
const tape0 = defaultTape(getCropFill(), seedTilt);
|
||||
const axis = axisWithTape(bbox, tape0, w, h);
|
||||
set({ k: 'axis', source: state.source, approvedMask: overlay, axis });
|
||||
@@ -544,7 +544,7 @@ export function createCaptureSession(opts: SessionOpts = {}): CaptureSession {
|
||||
// Legacy slider path — maps to photo tilt under the fixed tape line (#99).
|
||||
setAxisAngle(deg: number) {
|
||||
if (state.k !== 'axis') return;
|
||||
const tape = { ...state.axis.tape, tiltDeg: deg };
|
||||
const tape = { ...state.axis.tape, tiltDeg: clampTiltDeg(deg) };
|
||||
const axis = axisWithTape(state.axis.bbox, tape, state.source.widthPx, state.source.heightPx);
|
||||
set({ ...state, axis });
|
||||
void persist();
|
||||
@@ -552,7 +552,8 @@ export function createCaptureSession(opts: SessionOpts = {}): CaptureSession {
|
||||
|
||||
setTape(tape: TapeTransform) {
|
||||
if (state.k !== 'axis') return;
|
||||
const axis = axisWithTape(state.axis.bbox, tape, state.source.widthPx, state.source.heightPx);
|
||||
const clamped = { ...tape, tiltDeg: clampTiltDeg(tape.tiltDeg) };
|
||||
const axis = axisWithTape(state.axis.bbox, clamped, state.source.widthPx, state.source.heightPx);
|
||||
set({ ...state, axis });
|
||||
void persist();
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user