Skip to content

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

License

Notifications You must be signed in to change notification settings

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

 
 
 

Contributors

Languages

  • JavaScript 89.7%
  • HTML 10.3%