JSFiddle - React, Tailwind, and code Playground

by Ray Mak

HTML

<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/@ericblade/quagga2/dist/quagga.js"></script>
<input id="scanner_input" class="form-control" type="text" />
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#barcodeScanner">
	Scan item
</button>
<button type="button" id="clear-page" class="btn btn-warning">
	clear
</button>

<!-- Modal -->
<div class="modal fade" id="barcodeScanner" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
	<div class="modal-dialog">
		<div class="modal-content">
			<div class="modal-header">
				<h5 class="modal-title" id="exampleModalLabel">Scan barcode</h5>
				<button type="button" class="close" data-dismiss="modal" aria-label="Close">
					<span aria-hidden="true">&times;</span>
				</button>
			</div>
			<div class="modal-body">
				<div id="interactive" class="viewport">
					<video autoplay="true" preload="auto" src="" muted="true" playsinline="true"></video>
				</div>
				<div class="error"></div>
			</div>
			<div class="modal-footer">
				<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
			</div>
		</div>
	</div>
</div>
<div>
	<ul id="result_strip"></ul>
</div>

JavaScript

$(function () {
	// Create the QuaggaJS config object for the live stream
	var liveStreamConfig = {
		inputStream: {
			type: "LiveStream",
			constraints: {
				width: { min: 640 },
				height: { min: 480 },
				aspectRatio: { min: 1, max: 100 },
				facingMode: "environment" // or "user" for the front camera
			}
		},
		locator: {
			patchSize: "medium",
			halfSample: true
		},
		numOfWorkers: (navigator.hardwareConcurrency ? navigator.hardwareConcurrency : 4),
		decoder: {
			"readers": ['upc_reader', 'upc_e_reader', 'code_128_reader', 'ean_reader', 'ean_8_reader', 'code_39_reader', 'code_39_vin_reader', 'codabar_reader', 'i2of5_reader', '2of5_reader', 'code_93_reader'],
			multiple: false
		},
		locate: false
	};

	var resultCollector = Quagga.ResultCollector.create({
		capture: true, // keep track of the image producing this result
		capacity: 20,  // maximum number of results to store
		blacklist: [   // list containing codes which should not be recorded
			{ code: "3574660239843", format: "upc_e" }],
		filter: function (codeResult) {
			// only store results which match this constraint
			// returns true/false
			// e.g.: return codeResult.format === "ean_13";
			return true;
		}
	});

	$('#barcodeScanner').on('shown.bs.modal', function (e) {
		Quagga.init(
			liveStreamConfig,
			function (err) {
				if (err) {
					$('#barcodeScanner .modal-body .error').html('<div class="alert alert-danger"><strong><i class="fa fa-exclamation-triangle"></i> ' + err.name + '</strong>: ' + err.message + '</div>');
					Quagga.stop();
					return;
				}
				Quagga.registerResultCollector(resultCollector);
				Quagga.start();
			}
		);
	});

	// Make sure, QuaggaJS draws frames an lines around possible
	// barcodes on the live stream
	Quagga.onProcessed(function (result) {
		var drawingCtx = Quagga.canvas.ctx.overlay,
			drawingCanvas = Quagga.canvas.dom.overlay;

		if (result) {
			if (result.boxes) {
				drawingCtx.clearRect(0, 0,...