All Projects → nartc → React Native Barcode Mask

nartc / React Native Barcode Mask

Licence: mit
BarcodeMask Component for RNCamera

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to React Native Barcode Mask

React Native Audio Toolkit
Cross-platform audio library for React Native
Stars: ✭ 861 (+856.67%)
Mutual labels:  reactnative
React Native Markdown Package
React native markdown package is a Library for implementing markdown syntax in React Native
Stars: ✭ 50 (-44.44%)
Mutual labels:  reactnative
Ejdb
🏂 EJDB 2.0 — Embeddable JSON Database engine C library. Simple XPath like query language (JQL). Websockets / Android / iOS / React Native / Flutter / Java / Dart / Node.js bindings. Docker image.
Stars: ✭ 1,187 (+1218.89%)
Mutual labels:  reactnative
Expo Chroma Key Camera
Live green-screen effect with Expo and THREE.js
Stars: ✭ 28 (-68.89%)
Mutual labels:  reactnative
Basic Redux React Native Boilerplate
Basic implementation of Redux + React Native
Stars: ✭ 44 (-51.11%)
Mutual labels:  reactnative
Grocerystore With Server
Grocery Store with server integration
Stars: ✭ 51 (-43.33%)
Mutual labels:  reactnative
Usestatewithlayoutanimation
Abstraction for `React Native`'s `LayoutAnimation` and `useState`
Stars: ✭ 19 (-78.89%)
Mutual labels:  reactnative
Reanimated Collapsible Navbar
Declarative implementation of a collapsible navigation bar with snapping in React Native, with all animations running on the UI thread 🚀
Stars: ✭ 86 (-4.44%)
Mutual labels:  reactnative
Ecoleta
Projecto construído durante o Next Level Week 1 - Ecoleta by @Rocketseat
Stars: ✭ 46 (-48.89%)
Mutual labels:  reactnative
Tus Js Client
A pure JavaScript client for the tus resumable upload protocol
Stars: ✭ 1,151 (+1178.89%)
Mutual labels:  reactnative
Gssoc2021 Hotelontouch
👨‍🔧👨‍🔧Manage your all hotel services at one place - This is the project repository for HotelOnTouch Project and this project is actively looking for new contributors👨‍🔧👩‍🏫
Stars: ✭ 30 (-66.67%)
Mutual labels:  reactnative
React Native Heic Converter
Convert your HEIC files with React Native
Stars: ✭ 43 (-52.22%)
Mutual labels:  reactnative
React Native Timer Countdown
⏱ A minimal and customizable countdown timer for React Native (iOS and Android)
Stars: ✭ 53 (-41.11%)
Mutual labels:  reactnative
Bluewallet
Bitcoin thin client for iOS & Android. Built with React Native
Stars: ✭ 878 (+875.56%)
Mutual labels:  reactnative
Reactxp Starter
Basic Blank ReactXP Project for Development
Stars: ✭ 75 (-16.67%)
Mutual labels:  reactnative
Boostnote Mobile
Boostnote for iOS and Android 🚀
Stars: ✭ 844 (+837.78%)
Mutual labels:  reactnative
React Native Web Platform
React Native on web
Stars: ✭ 50 (-44.44%)
Mutual labels:  reactnative
React Native Deep Linking
Deep Linking set up in a React Native App
Stars: ✭ 89 (-1.11%)
Mutual labels:  reactnative
React Native Fingerprint Identify
Awesome Fingerprint Identify for react-native (android only)
Stars: ✭ 81 (-10%)
Mutual labels:  reactnative
React Native Spaceviewer
See and search upcoming and previous rocket space launches! Built with React Native, using Detox E2E tests, Fastlane and Github Actions for app store deployment.
Stars: ✭ 61 (-32.22%)
Mutual labels:  reactnative

@nartc/react-native-barcode-mask

travis bundlephobia downloads npm license Known Vulnerabilities

QR PDF417

Acknowledgement

I want to acknowledge the current react-native-barcode-mask library. Most of @nartc/react-native-barcode-mask is "cloned" from the original but rewritten with React Hooks and Reanimated

Installation

npm install @nartc/react-native-barcode-mask
yarn add @nartc/react-native-barcode-mask

Usage

  1. Import BarcodeMask from @nartc/react-native-barcode-mask
  2. Use <BarcodeMask /> as a child of <RNCamera> from react-native-camera
<RNCamera {...props}>
  <BarcodeMask {...barcodeMaskProps} />
</RNCamera>

Features

  1. Provide customizable masks to be used as RNCamera's SubViews
  2. Provide custom Hook for Detect Barcode within Finder Area feature.

BarcodeMaskProps

name type description default
width DimensionUnit Width of the Barcode Finder Area 280
height DimensionUnit Height of the Barcode Finder Area 230
edgeWidth DimensionUnit Width of corner edges 20
edgeHeight DimensionUnit Height of corner edges 20
edgeColor string Color of corner edges #fff
edgeRadius number Border Radius of corner edges 0
edgeBorderWidth DimensionUnit Thickness of corner edges 4
backgroundColor string Background color of Outer Finder Area #eee
maskOpacity number Opacity of Outer Finder Area 1
showAnimatedLine boolean Whether to show Animated Line true
startValue number Start value of Animated Line (only applicable if showAnimatedLine is set to true) 0
destinationValue number Destination value of Animated Line (depends onanimatedLineOrientation) Length of respective orientation - animatedLineThickness
animatedComponent (width: number, height: number) => ReactElement Allow consumers to provide a Render Prop to render custom animated component. Render Prop will be executed with the computed width and height null
animatedLineThickness DimensionUnit Thickness of Animated Line 2
animatedLineOrientation 'vertical' or 'horizontal' Orientation that the Animated Line will be drawn 'horizontal'
animatedLineColor string Color of Animated Line #fff
animationDuration number Duration of Animated Line animation (in ms) 20000
runTimingFn RunTimingFn Function to trigger the animation internal runTiming function
onLayoutChange OnLayoutChangeHandler Handler to handle LayoutChange. Useful if you want to only detect barcode inside the Finder Area. noop

RunTimingFn

This is a function with the following form:

export type RunTimingFn = (
  clock: Animated.Clock,
  value: number,
  destination: number,
  duration: number
) => Animated.Node<number>;

This function basically will start the Animated.Clock and loop the value from value <-> destination in a loop. By default, an internal runTiming fn will be used (which would work for most cases). You can find the internal function defined here

OnLayoutChangeHandler

This library also provides functionality to only scan the barcode that is in within bounds of the Finder Area (Inner Mask). To use this feature, you need to import and use useBarcodeRead custom hook:

const {
  barcodeRead,
  onBarcodeRead,
  onBarcodeFinderLayoutChange,
} = useBarcodeRead(
  isFocused,
  barcodeData => {},
  processedBarcodeData => {}
);

useBarcodeRead takes in the following arguments:

  1. isFocused: If you're using react-navigation then you should be familiar (or should get familiarized) with the concept of focus. When you navigate to a screen on the same Stack (or different Tab), the previous (current) screen is not unmounted, but only unfocused. RNCamera requires you to reinitialize when a screen is re-focus. react-navigation provides multiple ways to get access to isFocused property. If you don't use react-navigation, you can just pass in true
  2. (barcodeData: string) => string: This is a callback to process barcode raw data. This gets exposed so you can apply your own logic to process the raw data.
  3. (processedData: string) => void: This is a callback that takes in the processedData. This is where you want to do with the processed barcode data: call API, or navigating to a different screen etc...
  4. barcodeReadDelay: number: useBarcodeRead now takes in an optional delay which will handle the frequency of scanning barcode internally, instead of using barcodeRead to manipulate barcodeTypes. Default to 500ms

useBarcodeRead returns the following:

  1. barcodeRead: boolean: This is a boolean flag whether the barcode has been read for the first time. This is to prevent RNCamera captures a barcode too many times too quick. You can use this barcodeRead flag to modify the barcodeTypes props on RNCamera to an empty array to prevent capturing barcode. Like so:
<RNCamera
  barcodeTypes={barcodeRead ? [] : [RNCamera.Constants.BarCodeType.qr]}
/>

NOTE: I noticed that this trick "kind of stopped" working since couple of the latest issue ago. Haven't looked into the commit log of react-native-camera but barcodeRead is returned for the sake of barcodeRead, frequency of scanning barcode is handled internally now.

  1. onBarcodeRead: This is a handler that the hook returns so you can pass to onBarCodeRead prop on RNCamera
  2. onBarcodeFinderLayoutChange: This is a handler that the hook returns so you can pass to onLayoutChange prop on BarcodeMask

useBarcodeRead is exported based on Platform: ios or android because of how the bounds of the scanned barcode are returned differently on each Platform. On iOS, this feature works very well and stable.

However, on Android, this feature isn't as stable because of the randomness of the bounds returned. The bounds returned are differently based on the barcodeType as well. For my specific case, I use QR and PDF417 so I was able to identify the bounds for these two types, even so it's not very reliable for PDF417. Contributions/Suggestions are definitely welcomed to improve support for Android.

useCustomBarcodeRead

A new Hook is introduced: useCustomBarcodeRead

The purpose of this hook is to provide customization to how the Mask will handle barcode read within the Mask's bounds. On iOS, you probably don't need to worry about this because the mask works pretty stable. However on Android, because of the randomness of the bounds and device's coordinate system, this hook will allow the consumers to customize the BarcodeMask internal functionality instead of introducing a fix for a variety of Android devices which would take, probably forever, to complete.

Just like the normal useBarcodeRead(), useCustomBarcodeRead takes in: isFocused, dataProcessor function and processedData callback function. In addition, it also takes in two new parameters:

  1. customBarcodeRead: This is an object with two properties: beforeScan and afterScan. The idea is to provide customization to how BarcodeMask affects the RNCamera. With useBarcodeRead, the returned flag barcodeRead is used to turn on/off scanning ability by setting the barcodeTypes to an [] when barcodeRead is true. Internally, it's just a useState and setBarcodeRead(true/false) is called at a certain point. With this new hook, you can setup a state at your component's level and pass two callbacks beforeScan and afterScan, BarcodeMask will call those at the same point it calls the internal useState. beforeScan and afterScan, if provided, will override the internal useState.
const [customBarcodeRead, setCustomBarcodeRead] = useState(false);
const {} = useCustomBarcodeRead(
  isFocused,
  dataProcessor,
  processedData => {
    /*do stuff*/
  },
  {
    beforeScan: () => {
      setCustomBarcodeRead(true);
    },
    afterScan: () => {
      setCustomBarcodeRead(false);
    },
  }
);

NOTE: When beforeScan and afterScan are provided, internal barcodeRead state will be returned as null.

  1. customBarcodeReadCallback: This is a callback with the following signature. It's a function that returns the RNCamera's BarcodeRead callback.
export interface CustomBarcodeReadCallback {
  (
    finderBoundingRect: { x: number; y: number; width: number; height: number },
    isFinderBoundingInitialized: boolean,
    processingBarcodeFn: (data: string) => void
  ): (event: {
    data: string;
    bounds:
      | { width: number; height: number; origin: Array<Point<string>> }
      | { origin: Point<string>; size: Size<string> };
    type: keyof BarCodeType;
  }) => void;
}

Basically, BarcodeMask will now delegate the helpful data: finderBoundingRect, isFinderBoundingInitialized and the processedData function that you pass in useCustomBarcodeRead in the beginning for the consumers to handle the dimensions related issue.

  1. finderBoundingRect: the dimensions of the BarcodeMask calculated from top-left edgeCorner.
  2. isFinderBoundingInitialized: a flag to notify when the BarcodeMask is finished initialized.
  3. processBarcodeFn: this is the combined function with the logic of: dataProcessor, processedData and customBarcodeRead (if provided). This function takes in event.data (raw barcode data) and run through dataProcessor and ultimately ends up calling processedData() function.

BarcodeMaskWithOuterLayout

A new HOC is added and is exported as withOuterLayout(BarcodeMask) and named BarcodeMaskWithOuterLayout. If you want to explore withOuterLayout, feel free to.

The purpose of this component is to be able to use percentage value for width and height. For example, I want to setup a mask with a set width but I want the height of the mask to take up the height of the RNCamera component, then BarcodeMaskWithOuterLayout will help me achieve that.

<BarcodeMaskWithOuterLayout width={200} height={'100%'} />

Contributions

As mentioned, contributions are always welcomed.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].