LoginSignup
6
2

More than 3 years have passed since last update.

Rails+React+QuaggaJSを使ってバーコードスキャンしてみた

Posted at

はじめに

チーム開発したい方たちと集まりRuby on RailsとReactを使ってアプリ作成しており、
バーコード読み取り機能の実装を担当することとなったためざっくり動くところまで作ってみました。

環境

  • Ruby: 2.6.5
  • Ruby on Rails: 6.0.3

セットアップ

rails _6.0.3_ new barcode_app -d postgresql

cd barcode_app 

yarn add quagga

rails webpacker:install
rails webpacker:install:react
rails generate react:install
app/javascript/components/scanners/config.json
{
  "inputStream": {
    "type": "LiveStream",
    "constraints": {
      "width": { "min": 450 },
      "height": { "min": 300 },
      "facingMode": "environment",
      "aspectRatio": { "min": 1, "max": 2 }
    }
  },
  "locator": {
    "patchSize": "medium",
    "halfSample": true
  },
  "numOfWorkers": 2,
  "frequency": 10,
  "decoder": {
    "readers": ["ean_reader"]
  },
  "locate": true
}
app/javascript/components/scanners/Index.jsx
import React, { useState } from "react";
import Scanner from "./Scanner";


const Index = () => {
  const [camera, setCamera] = useState(true);
  const [result, setResult] = useState(null);

  const onDetected = result => {
    setResult(result);
    setCamera(!camera)
    window.location.href = '/scanners/' + result
  };

  return (
    <section className="section-wrapper">
      <div className="section-title">
        <h1 className="section-title-text">
          {camera ? <Scanner onDetected={onDetected} /> : <p>読み込み中...</p> }
        </h1>
      </div>
    </section>
  );
}

export default Index
app/javascript/components/scanners/Scanner.jsx
import React, { useEffect } from "react";
import config from "./config.json";
import Quagga from "quagga";

const Scanner = props => {
  const { onDetected } = props;

  useEffect(() => {
    Quagga.init(config, err => {
      if (err) {
        console.log(err, "error msg");
      }
      Quagga.start();
      return () => {
        Quagga.stop()
      }
    });

    Quagga.onProcessed(result => {
      var drawingCtx = Quagga.canvas.ctx.overlay,
        drawingCanvas = Quagga.canvas.dom.overlay;

      if (result) {
        if (result.boxes) {
          drawingCtx.clearRect(
            0,
            0,
            Number(drawingCanvas.getAttribute("width")),
            Number(drawingCanvas.getAttribute("height"))
          );
          result.boxes
            .filter(function(box) {
              return box !== result.box;
            })
            .forEach(function(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 }
          );
        }
      }
    });

    Quagga.onDetected(detected);
  }, []);

  const detected = result => {
    onDetected(result.codeResult.code);
  };

  return (
    <div id="interactive" className="viewport" />
  );
};

export default Scanner;

はまったポイント

スクリーンショット 2021-01-09 22.40.19.png

参考にした記事

対応箇所

config/webpack/environment.js
const { environment } = require('@rails/webpacker')

// 追記
environment.loaders.delete('nodeModules');

module.exports = environment

完成

ezgif.com-gif-maker (4) (1).gif

GitHub
https://github.com/yodev21/scanner_app

参考記事

WebRTCを使ってブラウザでバーコードのスキャンをしてみる

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2