Scan viewfinder

Free · MITReact Native · Expo

An overlay for a camera preview: brackets drift while searching, snap onto the subject with a cue, then a scan line sweeps while short findings fly out. It draws the overlay only; camera and detection are yours.

View as Markdown
Try it on your phone
Scan to open this demo in your phone's browser and use it with your fingers.

Installation

$ npx shadcn@latest add https://goodui.dev/native/r/scan-viewfinder.json

Then run npx expo install --fix so react-native-reanimated match your Expo SDK. Files land in components/goodui-native/scan-viewfinder.

Usage

import { CameraView } from "expo-camera";
import { ScanViewfinder, type ScanState } from "@/components/goodui-native/scan-viewfinder/scan-viewfinder";

const TARGET = { x: 0.15, y: 0.25, width: 0.7, height: 0.45 };

<ScanViewfinder state={state} target={TARGET} chips={["Salmon", "Rice"]}>
  <CameraView style={{ flex: 1 }} />
</ScanViewfinder>

When to use

Use it for
  • Apps that photograph something to analyse it: food, plants, documents, coins.
  • Giving feedback while an on-device detector looks for a subject.
Reach for something else
  • QR and barcode scanning: use the camera module's scanner with a plain frame.
  • Plain photo capture: a shutter is enough.

API reference

PropTypeDefault
state*
searching drifts the brackets, locked snaps them to `target`, analysing runs the scan line and chips.
"done" | "searching" | "locked" | "analysing"—
target
The subject, as fractions of the frame.
{ x: number; y: number; width: number; height: number }DEFAULT_TARGET
chips
Short facts that fly out of the subject while analysing: "Salmon", "Rice".
string[][]
children*
The camera preview.
ReactNode—
labelsPartial<ScanViewfinderLabels>—
style
Style for the outer container.
StyleProp<ViewStyle>—
testID
Identifier for end-to-end tests.
string—

Motion and haptics

  • Brackets drift on looping sine timings, then spring onto the target.
  • On lock, the frame flashes and the brackets take the accent color.
  • While analysing, a scan line loops and chips burst out in a staggered ring.
  • Reduced motion: no drift or sweep. Chips fade in at their final place.
  • Haptic: drop on lock, a tick for each chip.
  • Brackets and the scan line run on the UI thread, over the camera preview.

Accessibility

  • The status line is a polite live region, so state changes are announced.
  • Brackets, the scan line and chips are hidden from screen readers. Say the result on the next screen.

Notes for AI

  • It fills its parent with flex: 1, so the parent needs a height.
  • `target` is in fractions of the frame, measured from the top left.
  • State does not advance on its own: move through searching, locked, analysing and done yourself.
  • `chips` are short facts from a real result, cut off at about 130 pt. Do not show invented findings as if they were detected.
  • It stays left to right under RTL because it is measured from the physical camera frame.