georapbox / barcode-scanner

A Progressive Web Application (PWA) that scans barcodes of various formats, using the Barcode Detection API.
https://georapbox.github.io/barcode-scanner/
MIT License
83 stars 37 forks source link

Using in another application #10

Closed atifghaffar closed 7 months ago

atifghaffar commented 7 months ago

Hello,

Very nice work, congratulations. I would like to use the bar scanner part ( camera-only ) in another standard web app.

Can you help. I have tried https://github.com/mebjas/html5-qrcode It works well for the qrcode scanning but a bit buggy for the barcodes.

Let me know .

Kiind regards

atifghaffar commented 7 months ago

The web site will run on an android device in chrome.

georapbox commented 7 months ago

Hello and thanks for your kind words!

To use the scanner functionality in another app you will need to pick some bits of HTML and Javascript from the existing codebase.

Below, I will provide you with the necessary code snippets to use the barcode scanner in your app along with links to the full code for reference. For the sake of simplicity, I will omit some parts of the code that are not necessary for the scanner to work, like side effects after the barcode is detected or the UI elements, but you can find the full code in the repository.

NOTE: The scanner functionality is built using the Barcode Detection API, which is currently only supported in Chromium-based browsers on Mac and Android devices. If you are going to target Chrome for Android, as you said, you will be just fine. If you intend to target other browsers and platforms, you will also need to use a polyfill for the Barcode Detection API. I use the barcode-detector package in the codebase to polyfill the Barcode Detection API.

For the camera functionality you will need to use the capture-photo web component and use it like this:

HTML

<capture-photo facing-mode="environment" no-image auto-play>
  <!-- This is the layer/button that is displayed when a barcode is detected; hidden by default -->
  <!-- When a barcode is detected, we show this button to allow the user to scan another barcode. -->
  <button type="button" id="scanBtn" class="scan-button" hidden>
    Click to scan another barcode.
  </button>

  <!-- This is the capture button provided by the capture-photo element. -->
  <!-- We hide it because we don't need it in our case as we don't need to capture a photo. -->
  <span slot="capture-button" hidden></span>

  <!-- Override the content of the facing-mode button -->
  <span slot="facing-mode-button-content" title="Switch camera">
    Switch camera
  </span>
</capture-photo>

Full code for the camera markup can be found here.

CSS

For the capture-photo element, you can find the relevant styles here.

Javascript

const capturePhotoEl = document.querySelector('capture-photo');
const scanBtn = document.getElementById('scanBtn');
let rafId;

// This is the barcode detector using the Barcode Detection API.
// https://github.com/georapbox/barcode-scanner/blob/main/src/js/index.js#L365
function detectBarcode(source) {
  return new Promise((resolve, reject) => {
    barcodeDetector.detect(source).then(results => {
      if (Array.isArray(results) && results.length > 0) {
        resolve(results[0]);
      } else {
        reject({
          message: 'Could not detect barcode from provided source.'
        });
      }
    }).catch(err => {
      reject(err);
    });
  });
}

// This is the main function that scans for barcodes.
// https://github.com/georapbox/barcode-scanner/blob/main/src/js/index.js#L381
async function scan() {
  try {
    let barcode = {};
    barcode = await detectBarcode(capturePhotoVideoEl);
    window.cancelAnimationFrame(rafId);

    // Display the scan button
    scanBtn.hidden = false;

    // Perform any other side effects here, after the barcode is detected.
    // For example, you can show the barcode data in the UI.

    return;
  } catch (err) {
    // As the scanner keeps scanning if no barcode is detected, it will throw an error.
    // We don't want to show this error messages to the user because the scanner will keep scanning,
    // therefore we let it fail silently.
  }

  // We use requestAnimationFrame to keep scanning for barcodes in a loop.
  rafId = window.requestAnimationFrame(() => scan());
}

// Begin scanning when the video starts playing.
// https://github.com/georapbox/barcode-scanner/blob/main/src/js/index.js#L61
capturePhotoEl.addEventListener('capture-photo:video-play', evt => {
  scan();

  // Perform any other side effects here, when the video starts playing...
}, {
  once: true
});

// Start scanning again when the scan button is clicked.
// https://github.com/georapbox/barcode-scanner/blob/main/src/js/index.js#L460
scanBtn.addEventListener('click', () => {
  scanBtn.hidden = true;
  scan();

  // Perform any other side effects here, when the scan button is clicked...
});

This is pretty much the core functionality of the barcode scanner. Of course, you will need to adapt it to your app's needs, like handling the barcode data, showing it in the UI, etc, but this should hopefully be a good starting point.

atifghaffar commented 7 months ago

WOW. You actually took the time to answer and document all this. You are a good man. Thankyou.

georapbox commented 7 months ago

Yep, no problem, literally took me 10 minutes. If it helps you with your app I'm more than happy to help if I can. Do you mind if I close the issue?