Skip to content

cs-util-com/ARTapeMeasure.js

 
 

Repository files navigation

Pocket Tape AR


1. Product Overview

Pocket Tape AR is a browser-based, two-point distance-measurement tool that runs on any WebXR-capable mobile browser. Users can place endpoints with classic WebXR plane hit-tests or the Triangulation (beta) flow that uses two taps per point from different poses. After solving the 3-D points the app draws a coloured line, displays the distance with an accuracy estimate (±), and adds the entry to a session list. It targets DIY hobbyists and professionals with a high-precision workflow while staying lightweight and build-free.


2. Core Use-flow

  1. Launch
    • AR scene: WebXR session starts in portrait mode (or “AR not supported” overlay).
    • HUD / 2-D UI: Top-center banner empty. FAB opens the measurement list from the bottom-left.
    • Notes: Camera permission requested only if not yet granted.
  2. Toggle modes
    • AR scene: Menu button (☰) anchored top-left.
    • HUD / 2-D UI: Menu sheet lists Triangulation (beta) switch with tooltip text.
    • Notes: Default is classic hit-test mode.
  3. Place 1st point
    • AR scene: White sphere marker appears.
    • HUD / 2-D UI: Banner shows live distance = 0.00 m / 0.00 ft.
    • Notes: Haptic tick.
  4. Aim
    • AR scene: Reticle follows hit-test; live provisional line connects marker → reticle.
    • HUD / 2-D UI: Banner updates every frame (fixed precision).
    • Notes: Banner only—no in-scene label yet. If the reticle stays unavailable for ~1.2 s, a bottom prompt suggests switching to Triangulation.
  5. Place 2nd point
    • AR scene: Second sphere marker, coloured line, and mid-point label billboard (CSS2D text).
    • HUD / 2-D UI: Banner freezes to final value, then clears on next measurement.
    • Notes: Haptic tick.
  6. Session list
    • AR scene: No additional in-scene elements.
    • HUD / 2-D UI: Tap FAB → modal sheet slides up. Each row: coloured dot, value + units, copy ❐, delete ✖, unit-toggle switch (Imperial/Metric) at top.
    • Notes: Modal closes when done; unit preference persists between sessions.

Triangulation Mode (beta)

  1. Enable via ☰ → toggle Triangulation (beta). Crosshair replaces plane reticle and a hint banner appears (“Triangulation on — each point needs two taps.”)
  2. Tap #1 with the crosshair centred. HUD shows “Move sideways ~30–40 cm…” plus a 1/2 badge and baseline progress ring (goal 0.35 m).
  3. Baseline guidance runs until the device moves ≥ 0.30 m (hard minimum) between taps. If the user stalls for 10 s a tip is shown.
  4. Tap #2 re-aims the same physical point. The app triangulates the 3-D point, then displays a quality chip:
    • Green: angle ≥ 8° and ray miss ≤ 1.5 cm (chip auto-hides after ~1.6 s, manual Accept still required).
    • Yellow: angle 4–8° or miss 1.5–3 cm (prompt to widen baseline, Accept allowed).
    • Red: angle < 4° or miss > 3 cm (banner urges Redo, Accept anyway enabled).
  5. Quick actions: bottom-left Undo tap #1, bottom-right Redo #2 & Accept, top-right cancels current endpoint.
  6. Complete measurement: after both endpoints resolve, the coloured line is drawn, the midpoint label shows distance (± miss) when available, and the entry is added to Measurements with the same error bar.

All stored data (ray origins/directions, quality score, error estimate) is kept per endpoint to support redo/undo without impacting existing measurements.

3. Functional Requirements

Area Requirement
Measurement • Only straight-line, two-point measurements.
• Unlimited concurrent lines.
• Internal unit = metres (Float64).
Triangulation • Optional mode toggled via ☰ menu.
• Each endpoint captured by two taps from distinct poses.
• Enforce ≥ 0.30 m baseline before accepting second tap.
• Store both rays/poses to support redo/undo per endpoint.
Precision & Format • Metric: metres to 2 decimals (≥ 1 m) or centimetres (cm) under 1 m.
• Imperial: feet + decimal inches (e.g., 4 ft 7.25 in).
Error Reporting • Display adds ± only when error > 0 (triangulation); classic hit-test entries omit error text.
• Error derived from ray–ray miss distance for triangulation.
• Clipboard copy includes the same formatted string.
Units • Conversion occurs at display layer only.
• Default system guessed from navigator.language, preference persisted in localStorage.
• User can toggle in list modal.
Clipboard • Copies the full formatted string (e.g., 2.54 m (±0.8 cm)).
Session List • Always starts empty on reload.
• Rows show coloured dot + formatted string with copy/delete actions.
• Delete uses the browser confirm() prompt before removal from list and scene.
Clear-all • No bulk clear; users reload page or delete items individually.
Editing • Measurements are read-only once placed.
Colouring • Each new measurement advances hue by 137° for contrast; midpoint label & list dot share colour.
Feedback • Haptic tick on each placement; crosshair appears only in triangulation; no audio.
• After ~1.2 s without a hit-test reticle, show a bottom prompt offering to switch to Triangulation.
Tracking Loss • Hit-test mode shows yellow banner: “Move phone to regain tracking.”
• UI remains interactive; placement disabled until tracking resumes.
Unsupported Browser • Full-screen overlay with message + device suggestions; offers optional “View 3D Scene (No AR)” fallback when WebGL is available.

4. Non-Functional Requirements

  • Performance: Target ≥ 30 fps on mid-range devices with 20+ lines. Use simple Three.js materials (unlit line + spheres).
  • Orientation: Attempt to lock portrait via screen.orientation.lock('portrait'); ignore failures.
  • Accessibility: Maintain WCAG-AA contrast for banners and modals; no additional colour-blind accommodations in v1.
  • Privacy: Avoid analytics, cookies, or external tracking; only CDN modules are requested.
  • Security: Host over HTTPS; no service worker or offline cache in the current build.
  • Supported Platforms: Require navigator.xr.isSessionSupported('immersive-ar') to return true (Chrome ≥ 94 Android, iOS Safari ≥ 15, Samsung Internet, Vision Pro Safari). Otherwise show the unsupported overlay with fallback option.

5. Technical Architecture

5.1 Front-end Stack

  • 3-D / AR: src/app.js imports Three.js 0.165 (from unpkg) plus ARButton, CSS2DRenderer, and WebXR APIs.
  • UI: Vanilla JS + Tailwind CDN; DOM IDs defined in index.html and wired in app.js.
  • Modules: No bundler; native ES modules with an importmap in index.html. A lightweight support widget is injected via @csutil/support-bubble.
  • Caching: No manifest or service worker; the app runs entirely from the static HTML + modules.

6. Algorithms & Key Methods

  • Hit-testing: Request viewer reference + hit-test source; show classic reticle only when a hit result is available.
  • Distance calculation: Compute distance = p1.distanceTo(p2) in metres. Metric display uses metres with two decimals when ≥ 1 m, otherwise centimetres rounded to integers. Imperial display converts to inches (metres × 39.3701), splits into feet (Math.floor(totalInches / 12)) and decimal inches ((totalInches % 12).toFixed(2)).
  • Colour generator: Fix HSL saturation at 80% and lightness at 55%, advancing hue with nextHue = (prevHue + 137) % 360 to guarantee contrast.
  • Triangulation: Compute camera forward ray on tap, enforce ≥ 0.30 m device baseline before solving closest-point-of-approach between rays. Result classification: Green (θ ≥ 8° & miss ≤ 1.5 cm), Yellow (θ ≥ 4° or miss ≤ 3 cm), Red otherwise. Error bar combines endpoint misses via RSS.

7. Error-Handling Strategy

  • Camera permission denied / session init fails: Show unsupported overlay and keep Start button hidden.
  • WebXR support missing: Offer unsupported overlay with optional “View 3D Scene” fallback.
  • Unhandled JS error: Log details to the console only; no telemetry.
  • CDN hiccups: Rely on network fetch; no offline caching in current build.

8. Testing Plan

  • Unit tests: Jest suite covering measurement formatting helpers and triangulation feedback UI helpers (src/formatters.test.js, src/triangulation-ui.test.js).
  • Manual exploratory: Checklist covering placement flows, baseline guidance ring, quality chip states, redo/undo, list copy/delete, unit toggle persistence, hit-test tracking banner, and fallback mode.
  • CI: Execute GitHub Actions workflow npm ci then npm test; treat failures as merge blockers.

9. Build & Deployment

  • Build: No build step; serve index.html + src/app.js directly (see npm run serve:static).
  • Deployment: Publish static assets (index.html + src) to hosting of choice (e.g., GitHub Pages root).
  • Versioning: Tag releases as vMAJOR.MINOR.PATCH per repo conventions.
  • License: Repository currently includes LICENSE (GPL v3).

10. Assets to Deliver

  1. index.html with import map, Tailwind CDN hook, and DOM scaffolding.
  2. src/app.js, src/triangulation.js, src/triangulation-ui.js, src/formatters.js plus colocated Jest specs.
  3. README with quick-start, supported devices, and GPL notice.
  4. Optional marketing assets (icons) tracked separately.

11. Future-Ready Extensions (out of scope v1)

  • Multi-language UI via i18next.
  • Per-measurement edit mode.
  • High-contrast / colour-blind safe palette toggle.
  • Advanced calibration workflow.
  • Automated end-to-end Playwright suite + device farm.

About

A web-based AR tape measure using WebXR to detect flat surfaces and display precise distance readings in real time

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 89.7%
  • HTML 10.3%