16 Commits

Author SHA1 Message Date
Samuel Prevost
b87f933b9e feat(solver): iterative homography solver with circle datums
Replace the two-pass closed-form deskew (getPerspectiveTransform +
per-axis scale corrections) with an alternating-minimisation loop around
cv.findHomography (internal Levenberg–Marquardt). Each outer iteration
recomputes per-datum point correspondences from the current H and the
datum's shape constraint, then findHomography refines H. Confidence
drives per-correspondence replication; primary gets a 3× gauge boost.

- Add EllipseDatum type (center + two conjugate semi-axis endpoints +
  known diameter) with 3-handle Konva rendering and coin presets.
- Generalise primary selection to any datum type. Priority rect >
  ellipse > line; within type, confidence then image size. Warm-start
  anchors: rect = 4 axis-aligned corners; ellipse = 4 conjugate-axis
  samples on a world circle; line = 2 endpoints + 2 synthetic
  perpendicular points (isotropic image-scale assumption).
- Direction-agnostic shape residuals: Procrustes-fit ideal (w × h) rect
  to projected corners; midpoint-preserving line rescale; radial-snap
  ellipse samples to a circle at projectPoint(H, center).
- Drop the "at least one rectangle" requirement. Any datum combination
  works; diagnostics widgets auto-pick a scale reference across types.
- Diagnostics: replace X/Y axis-correction cards with RMS residual +
  iteration count; per-datum table shows a residual breakdown column
  (edge %, perp Δ°, iso/skew/dia).
- Detect period-2 oscillation in the outer loop and warn to console.
- Relative convergence threshold so the affine and perspective entries
  of H are weighted comparably.
- Guard diagnostic diameter via geometric-mean-radius for non-circular
  conics; guard collinear-axes ellipses; fix Mat leak in
  solveHomography on the exception path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 17:42:40 +02:00
Samuel Prevost
a71c8c73ef feat(datums): broaden image upload, swap W/H, validate rect corners
Some checks failed
Deploy to GitHub Pages / build (push) Has been cancelled
Deploy to GitHub Pages / deploy (push) Has been cancelled
- Accept any browser-supported image type (png, webp, gif, …) in addition
  to jpg and heic on the upload step.
- Add a swap button between the width and height inputs on rectangle
  datums so users can flip dimensions with one click.
- Block the Next action on the datum step when a rectangle has crossed
  corners (top below bottom or right left of left), and surface which
  datums need fixing in the tooltip.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 20:39:37 +02:00
Samuel Prevost
27b23a61d9 docs: add comparison table to README
Some checks failed
Deploy to GitHub Pages / build (push) Has been cancelled
Deploy to GitHub Pages / deploy (push) Has been cancelled
Highlight what sets Skwik apart from existing perspective-correction
and measurement tools: client-side, multi-datum weighting, mm scale,
measurement tools, and scale bar export all in one.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-16 17:59:01 +02:00
Samuel Prevost
03d0f38476 fix(result): fix scale bar export, scale input UX, and auto-scale
Some checks failed
Deploy to GitHub Pages / build (push) Has been cancelled
Deploy to GitHub Pages / deploy (push) Has been cancelled
- Fix scale bar checkbox: replace shadcn Checkbox (broken event
  propagation) with native input[type=checkbox] + v-model
- Scale input: use local string ref so user can type freely;
  red highlight when invalid, run button disabled until valid
- Auto-compute default scale to match input image dimensions,
  capped at 8192px output; cached scale takes priority

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-14 23:59:36 +02:00
Samuel Prevost
e72c4bc89b fix(canvas): fix mobile touch interactions and desktop panning
Some checks failed
Deploy to GitHub Pages / build (push) Has been cancelled
Deploy to GitHub Pages / deploy (push) Has been cancelled
- Mobile: fix pinch-zoom jitter by disabling Konva stage drag during
  two-finger gestures so only our zoom handler controls position
- Mobile: fix dot dragging — defer pan start so Konva can claim touch
  for shape drag first (isDraggingShape flag)
- Desktop: enable stage drag for click-drag panning, disable during
  point drag; filter dragend by nodeType to prevent offset corruption
- Fallback file hash using name+size+lastModified when crypto.subtle
  is unavailable (HTTP contexts, some mobile browsers)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-14 23:51:29 +02:00
Samuel Prevost
f3d065e610 ci: add GitHub Actions workflow for GitHub Pages deployment
Some checks failed
Deploy to GitHub Pages / build (push) Has been cancelled
Deploy to GitHub Pages / deploy (push) Has been cancelled
- pnpm 10 + Node 22 for fastest CI
- Frozen lockfile, upload-pages-artifact v3, deploy-pages v4
- Vite base path set to /skwik/ when building in GHA
- Concurrency group cancels in-progress deploys

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-14 23:28:36 +02:00
Samuel Prevost
bf20518083 chore: add .claude/ to gitignore
Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-14 23:25:59 +02:00
Samuel Prevost
9e3cf6fd67 chore: add compressed example before/after images
Resized to ~480px max dimension, JPEG q80 (~128KB total).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-14 23:24:14 +02:00
Samuel Prevost
23fecfb738 fix(nav): make step indicators clickable with real button elements
Badge Primitive (<span>) was swallowing clicks. Reachable steps now
render as <button> with hover effects, current/unreached as Badge.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-14 23:24:09 +02:00
Samuel Prevost
98c6fc9a35 feat(ui): squirrel logo, fork ribbon, clickable steps, and polish
- Squirrel engineer logo (SkwikLogo.vue) with hard hat and ruler
- Matching favicon with squirrel head silhouette
- Gitea fork ribbon (top-left, desktop only, Gitea green)
- Centered header with logo, title, and subtitle
- Footer: "Made by Samuel Prevost" with GitHub link
- Clickable step indicators for previously visited steps
- Smaller datum dots (6/4 base radius with visual cap)
- Engineering-tool styling: monospace for measurements, Geist Mono
  font, deeper dark mode colors, instrument-panel header
- EXIF viewer explains why focal length matters
- Upload page describes what Skwik does

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-14 23:19:44 +02:00
Samuel Prevost
11e8013b6a feat(cache): persist datums per file hash and user settings
- Add file-hash.ts: SHA-256 hash of uploaded files via Web Crypto API
- Add datum-cache.ts: localStorage save/load/clear for datums by hash
- Add settings-cache.ts: persist scalePxPerMm and includeScaleBar
- Restore datums from cache on re-upload of same file
- Discreet "Clear cache" button on upload page
- Store fileHash and cacheRestoreMessage in Pinia store
- Auto-save datums on every change via deep watcher
- Track maxStepReached for clickable step navigation

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-14 23:19:34 +02:00
Samuel Prevost
0cb9009eaa feat(result): add measurement tools, grid overlay, and scale bar export
- New CorrectedImageViewer component with dual-canvas (image + overlay)
- Point-to-point measurement tool: click two points, see mm distance
- Toggleable grid overlay with configurable spacing and major lines
- Scale bar export: appends measurement bar to downloaded PNG
- Progress bar with step labels during algorithm execution
- Estimated output size shown before running, blocks if > 512MB
- Actual output dimensions/filesize shown in diagnostics
- Filename changed to originalname-skwik.png
- Collapsible algorithm explanation with numbered steps
- Process New Image button to reset and start over
- Scale bar tooltip explaining the feature
- Add shadcn-vue Checkbox component

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-14 23:19:25 +02:00
Samuel Prevost
1bc1f46bb8 feat(deskew): add debug logging, progress callbacks, and WASM safety
- Add step-by-step console logging throughout the algorithm
- Add onProgress callback for UI progress bar integration
- Fix WASM OOM: clamp output dimensions with proper matrix scaling
  (previously clamped size but not the transform, causing cropping)
- Fix waitForOpenCV race condition: probe cv.Mat() instead of
  checking constructor existence
- Wrap all OpenCV mats in try/finally for guaranteed cleanup
- Raise MAX_OUTPUT_DIM to 12288 for more leniency

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-14 23:19:16 +02:00
Samuel Prevost
3e0284da4c Add README
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 21:19:10 +02:00
Samuel Prevost
4069491c2f Implement real deskew algorithm and UI improvements
- Replace placeholder with OpenCV.js WASM perspective correction:
  pick highest-confidence rectangle, compute homography, fold
  weighted scale corrections from secondary datums, single warpPerspective
- All units now mm throughout (no cm conversion)
- Simplified datum creation: two buttons (+ Rectangle / + Line) with
  preset chips, auto-numbered labels (Line 1, Rectangle 2, etc.)
- Dimensions default to 0, user must input manually; Next button
  disabled until all datums have valid dimensions with tooltip hint
- Fix image preview (keep object URL alive), fix canvas disappearing
  on breakpoint switch (single instance + ResizeObserver re-fit)
- Mobile responsive: bottom sheet for datum panel, full-width canvas
- Spinner on result screen during processing
- Stricter ESLint config, updated Prettier to 4-space/no-semicolons

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 21:15:53 +02:00
Samuel Prevost
2d56c5dada Initial commit: Skwik image deskew tool
Vue 3 + Vite + TypeScript (strict) app with shadcn-vue, Konva.js canvas,
and Pinia. 4-step wizard: upload JPG/HEIC, view EXIF, place datum
measurements (rectangles/lines with presets), run deskew (placeholder).
Dark mode, mobile-responsive with bottom sheet for datum panel.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 20:53:00 +02:00