Barcode scanner in React
Today we will show you how to implement a barcode scanner in React. In this example, we will use the quaggaJS in the ReactJS component.
What is QuaggaJS?
QuaggaJS is a barcode-scanner entirely written in JavaScript supporting real- time localization and decoding of various types of barcodes such as EAN, CODE 128, CODE 39, EAN 8, UPC-A, UPC-C, I2of5, 2of5, CODE 93 and CODABAR.
Checkout more articles on ReactJS
- Implement client side pagination in React AG Grid
- Top 8 popular npm packages for React and Node.js
- Track events in React with Google Analytics
- Implement multi-languages in React
- How to create a toast notification in React
Demo Application
Barcode scanner in React - Clue Mediator
Steps to implement barcode scanner in React
- Create a react application
- Install quaggaJS package
- Add scanner functionality in react component
- Output
1. Create a react application
First of all, create a simple react application using the `create-react-app`. Run the following command to create an app.
npx create-react-app react-barcode-scanner
2. Install quaggaJS package
Run the following command to install quaggaJS to implement a barcode scanner.
npm install quagga
3. Add scanner functionality in react component
We have to initialize the Quagga JS to start the scanner and attach the function to read the code.
const _onDetected = res => {
setBarcode(res.codeResult.code);
};
const startScanner = () => {
Quagga.init(
{
inputStream: {
type: 'LiveStream',
target: document.querySelector('#scanner-container'),
constraints: {
facingMode: 'environment' // or user
}
},
numOfWorkers: navigator.hardwareConcurrency,
locate: true,
frequency: 1,
debug: {
drawBoundingBox: true,
showFrequency: true,
drawScanline: true,
showPattern: true
},
multiple: false,
locator: {
halfSample: false,
patchSize: 'large', // x-small, small, medium, large, x-large
debug: {
showCanvas: false,
showPatches: false,
showFoundPatches: false,
showSkeleton: false,
showLabels: false,
showPatchLabels: false,
showRemainingPatchLabels: false,
boxFromPatches: {
showTransformed: false,
showTransformedBox: false,
showBB: false
}
}
},
decoder: {
readers: [
'code_128_reader',
'ean_reader',
'ean_8_reader',
'code_39_reader',
'code_39_vin_reader',
'codabar_reader',
'upc_reader',
'upc_e_reader',
'i2of5_reader',
'i2of5_reader',
'2of5_reader',
'code_93_reader'
]
}
},
err => {
if (err) {
return console.log(err);
}
Quagga.start();
}
);
Quagga.onDetected(_onDetected);
};
Use the following function to draw an indicator on the canvas after the process is done.
Quagga.onProcessed(result => {
let drawingCtx = Quagga.canvas.ctx.overlay,
drawingCanvas = Quagga.canvas.dom.overlay;
if (result) {
if (result.boxes) {
drawingCtx.clearRect(
0,
0,
parseInt(drawingCanvas.getAttribute('width')),
parseInt(drawingCanvas.getAttribute('height'))
);
result.boxes.filter(box => box !== result.box).forEach(box => {
Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, {
color: 'green',
lineWidth: 2
});
});
}
if (result.box) {
Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: '#00F', lineWidth: 2 });
}
if (result.codeResult && result.codeResult.code) {
Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: 'red', lineWidth: 3 });
}
}
});
To stop the scanner, use the following code.
const stopScanner = () => {
Quagga.offProcessed();
Quagga.offDetected();
Quagga.stop();
};
At last, we have to add the HTML element to load the barcode scanner and add the CSS to align the indicator.
<div id="scanner-container">
</div>
#scanner-container {
position: relative;
}
.drawingBuffer {
position: absolute;
left: 0;
top: 0;
}
4. Output
Letโs combine all the code together and see how it looks.
App.js
import React, { useEffect, useRef, useState } from 'react';
import Quagga from 'quagga';
const App = (props) => {
const firstUpdate = useRef(true);
const [isStart, setIsStart] = useState(false);
const [barcode, setBarcode] = useState('');
useEffect(() => {
return () => {
if (isStart) stopScanner();
};
}, []);
useEffect(() => {
if (firstUpdate.current) {
firstUpdate.current = false;
return;
}
if (isStart) startScanner();
else stopScanner();
}, [isStart]);
const _onDetected = res => {
// stopScanner();
setBarcode(res.codeResult.code);
};
const startScanner = () => {
Quagga.init(
{
inputStream: {
type: 'LiveStream',
target: document.querySelector('#scanner-container'),
constraints: {
facingMode: 'environment' // or user
}
},
numOfWorkers: navigator.hardwareConcurrency,
locate: true,
frequency: 1,
debug: {
drawBoundingBox: true,
showFrequency: true,
drawScanline: true,
showPattern: true
},
multiple: false,
locator: {
halfSample: false,
patchSize: 'large', // x-small, small, medium, large, x-large
debug: {
showCanvas: false,
showPatches: false,
showFoundPatches: false,
showSkeleton: false,
showLabels: false,
showPatchLabels: false,
showRemainingPatchLabels: false,
boxFromPatches: {
showTransformed: false,
showTransformedBox: false,
showBB: false
}
}
},
decoder: {
readers: [
'code_128_reader',
'ean_reader',
'ean_8_reader',
'code_39_reader',
'code_39_vin_reader',
'codabar_reader',
'upc_reader',
'upc_e_reader',
'i2of5_reader',
'i2of5_reader',
'2of5_reader',
'code_93_reader'
]
}
},
err => {
if (err) {
return console.log(err);
}
Quagga.start();
}
);
Quagga.onDetected(_onDetected);
Quagga.onProcessed(result => {
let drawingCtx = Quagga.canvas.ctx.overlay,
drawingCanvas = Quagga.canvas.dom.overlay;
if (result) {
if (result.boxes) {
drawingCtx.clearRect(
0,
0,
parseInt(drawingCanvas.getAttribute('width')),
parseInt(drawingCanvas.getAttribute('height'))
);
result.boxes.filter(box => box !== result.box).forEach(box => {
Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, {
color: 'green',
lineWidth: 2
});
});
}
if (result.box) {
Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: '#00F', lineWidth: 2 });
}
if (result.codeResult && result.codeResult.code) {
Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: 'red', lineWidth: 3 });
}
}
});
};
const stopScanner = () => {
Quagga.offProcessed();
Quagga.offDetected();
Quagga.stop();
};
return <div>
<h3>Barcode scanner in React - <a href="https://www.cluemediator.com/" target="_blank" rel="noopener">Clue Mediator</a></h3>
<button onclick="{()" ==""> setIsStart(prevStart => !prevStart)} style={{ marginBottom: 20 }}>{isStart ? 'Stop' : 'Start'}</button>
{isStart && <react class="fragment">
<div id="scanner-container">
<span>Barcode: {barcode}</span>
}
</div>
}
export default App;
</react></div>
index.css
#scanner-container {
position: relative;
}
.drawingBuffer {
position: absolute;
left: 0;
top: 0;
}
Run the application and check the output in the browser.
I hope you find this article helpful.
Thank you for reading. Happy Coding..!! ๐