@7Brito in the end I had to implement multiple plugins to get both qrcode and barcode to work on iOS, Android and PWA for my Ionic + Vue + Capacitor project.
Note, I ran into a bug in vue-quagga so just implemented quaggaJS directly. I also used phonegap-plugin-barcodescanner for both barcode and qrcode for iOS and Android, but specify formats
config to distinguish between each.
PWA
Barcode - quaggaJS
import Quagga from 'quagga';
<div id="interactive" class="viewport scanner">
<video />
<canvas class="drawingBuffer" />
</div>
data() {
return {
width: 0,
height: 0,
readers: [
'ean_reader',
'upc_reader',
'code_128_reader'
]
}
},
computed: {
config() {
return {
inputStream: {
type: 'LiveStream',
constraints: {
width: this.width,
height: this.height,
facingMode: 'environment',
aspectRatio: {
min: 1,
max: 2
},
},
},
locator: {
patchSize: 'medium',
halfSample: true,
},
numOfWorkers: 2,
frequency: 10,
decoder: {
readers: [
'ean_reader',
'upc_reader',
'code_128_reader'
]
},
locate: true
}
}
},
mounted() {
setTimeout(() => {
this.loadCanvas();
this.loadScanner();
}, 1000);
},
destroyed() {
Quagga.stop();
},
methods: {
loadCanvas() {
let ratio = 0.7;
let container = document.querySelector("#interactive");
this.width = container.offsetWidth;
this.height = container.offsetWidth * ratio;
},
loadScanner() {
Quagga.init(this.config, (err) => {
if (err) {
return console.error(err);
}
Quagga.start();
});
Quagga.onDetected(this.onDetected);
Quagga.onProcessed(this.onProcessed);
},
onDetected(result) {
console.log('onDetected', result);
},
onProcessed(result) {
if (result) {
let drawingCtx = Quagga.canvas.ctx.overlay;
let drawingCanvas = Quagga.canvas.dom.overlay;
if (result.boxes) {
drawingCtx.clearRect(
0,
0,
parseInt(drawingCanvas.getAttribute('width')),
parseInt(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 }
);
}
}
}
}
QRCode - vue-qrcode-reader
import { QrcodeStream, QrcodeDropZone, QrcodeCapture } from "vue-qrcode-reader";
<qrcode-drop-zone @decode="onScan" @init="onError">
<qrcode-stream @decode="onScan" @init="onInit"></qrcode-stream>
</qrcode-drop-zone>
<qrcode-capture v-if="noStreamApiSupport" @decode="onScan" />
async onInit(promise) {
await promise;
},
onScan(data) {
console.log('onScan', data);
},
onError(promise) {
promise.catch(console.error);
}
iOS / Android
Barcode - phonegap-plugin-barcodescanner
async scanBarcode(frontCamera=true, flipCamera=true, torchButton=true) {
return new Promise((resolve, reject) => {
cordova.plugins.barcodeScanner.scan(
(result) => {
resolve(result.text);
},
(error) => {
reject(error);
},
{
preferFrontCamera: frontCamera,
showFlipCameraButton: flipCamera,
showTorchButton: torchButton,
torchOn: false,
saveHistory: false,
prompt: "Place barcode inside scan area",
resultDisplayDuration: 500,
formats: "ALL_1D,AZTEC,CODABAR,CODE_39,CODE_93,CODE_128,EAN_8,EAN_13,UPC_A,UPC_E,UPC_EAN_EXTENSION,DATA_MATRIX,ITF,MAXICODE,MSI,RSS_14,PDF_417,PLESSEY", // default: all but PDF_417 and RSS_EXPANDED
disableAnimations: true,
disableSuccessBeep: false
}
);
});
}
QRCode - phonegap-plugin-barcodescanner
async scanQrcode(frontCamera=true, flipCamera=true, torchButton=true) {
return new Promise((resolve, reject) => {
cordova.plugins.barcodeScanner.scan(
(result) => {
resolve(result.text);
},
(error) => {
reject(error);
},
{
preferFrontCamera: frontCamera,
showFlipCameraButton: flipCamera,
showTorchButton: torchButton,
torchOn: false,
saveHistory: false,
prompt: "Place qrcode inside scan area",
resultDisplayDuration: 500,
formats: "QR_CODE",
disableAnimations: true,
disableSuccessBeep: false
}
);
});
}
Hope this helps! Big thanks to @aaronksaunders for his capacitor-vue-ionicv4-app example