317 lines
12 KiB
JavaScript
317 lines
12 KiB
JavaScript
import './lib/zxing/zxing.min.js';
|
|
let codeReader = null;
|
|
let id = null;
|
|
let supportsVibrate = false;
|
|
let opt = null;
|
|
let inst = null;
|
|
let selectedDeviceId = null;
|
|
let deviceID = null;
|
|
let element = null;
|
|
let debug = false;
|
|
export function vibrate() {
|
|
if (supportsVibrate) navigator.vibrate(1000);
|
|
}
|
|
export function init(instance, ele, elementid, options, deviceid) {
|
|
console.log('init' + elementid);
|
|
inst = instance;
|
|
opt = options;
|
|
id = elementid;
|
|
deviceID = deviceid;
|
|
element = ele;
|
|
debug = options.debug;
|
|
supportsVibrate = "vibrate" in navigator;
|
|
let startButton = element.querySelector("[data-action=startButton]");
|
|
let resetButton = element.querySelector("[data-action=resetButton]");
|
|
let closeButton = element.querySelector("[data-action=closeButton]");
|
|
|
|
if (startButton) startButton.addEventListener('click', () => {
|
|
start(elementid);
|
|
})
|
|
|
|
if (resetButton) resetButton.addEventListener('click', () => {
|
|
stop(elementid);
|
|
if (debug) console.log('Reset.')
|
|
})
|
|
|
|
if (closeButton) closeButton.addEventListener('click', () => {
|
|
stop(elementid);
|
|
if (debug) console.log('closeButton.')
|
|
instance.invokeMethodAsync("CloseScan");
|
|
})
|
|
|
|
load(elementid);
|
|
}
|
|
|
|
export function reload(elementid) {
|
|
load(elementid);
|
|
}
|
|
|
|
function genHints(opt) {
|
|
const hints = new Map();
|
|
if (opt.TRY_HARDER) {
|
|
hints.set(ZXing.DecodeHintType.TRY_HARDER, opt.TRY_HARDER);
|
|
}
|
|
if (opt.ASSUME_CODE_39_CHECK_DIGIT) {
|
|
hints.set(ZXing.DecodeHintType.ASSUME_CODE_39_CHECK_DIGIT, opt.ASSUME_CODE_39_CHECK_DIGIT);
|
|
}
|
|
if (opt.ASSUME_GS1) {
|
|
hints.set(ZXing.DecodeHintType.ASSUME_GS1, opt.ASSUME_GS1);
|
|
}
|
|
if (opt.CHARACTER_SET) {
|
|
hints.set(ZXing.DecodeHintType.CHARACTER_SET, opt.CHARACTER_SET);
|
|
}
|
|
if (opt.OTHER) {
|
|
hints.set(ZXing.DecodeHintType.OTHER, opt.OTHER);
|
|
}
|
|
if (opt.PURE_BARCODE) {
|
|
hints.set(ZXing.DecodeHintType.PURE_BARCODE, opt.PURE_BARCODE);
|
|
}
|
|
if (opt.RETURN_CODABAR_START_END) {
|
|
hints.set(ZXing.DecodeHintType.RETURN_CODABAR_START_END, opt.RETURN_CODABAR_START_END);
|
|
}
|
|
if (opt.TRY_HARDER) {
|
|
hints.set(ZXing.DecodeHintType.TRY_HARDER, opt.TRY_HARDER);
|
|
}
|
|
return hints;
|
|
}
|
|
|
|
export function load(elementid) {
|
|
if (id == elementid) {
|
|
|
|
const sourceSelect = element.querySelector("[data-action=sourceSelect]");
|
|
const sourceSelectPanel = element.querySelector("[data-action=sourceSelectPanel]");
|
|
const hints = genHints(opt);
|
|
|
|
if (opt.pdf417) {
|
|
codeReader = new ZXing.BrowserPDF417Reader(hints);
|
|
if (debug) console.log('ZXing code PDF417 reader initialized')
|
|
} else if (opt.decodeAllFormats) {
|
|
const formats = opt.formats;
|
|
hints.set(ZXing.DecodeHintType.POSSIBLE_FORMATS, formats);
|
|
codeReader = new ZXing.BrowserMultiFormatReader(hints)
|
|
if (debug) console.log('ZXing code reader initialized with all formats')
|
|
} else {
|
|
codeReader = new ZXing.BrowserMultiFormatReader(hints)
|
|
if (debug) console.log('ZXing code reader initialized')
|
|
}
|
|
codeReader.timeBetweenDecodingAttempts = opt.timeBetweenDecodingAttempts;
|
|
|
|
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
|
|
navigator.mediaDevices
|
|
.getUserMedia({ audio: false, video: true })
|
|
.then(() => {
|
|
|
|
codeReader.listVideoInputDevices()
|
|
.then((videoInputDevices) => {
|
|
if (deviceID != null) {
|
|
selectedDeviceId = deviceID
|
|
} else if (videoInputDevices.length > 1) {
|
|
selectedDeviceId = videoInputDevices[1].deviceId
|
|
} else {
|
|
selectedDeviceId = videoInputDevices[0].deviceId
|
|
}
|
|
if (debug) console.log('videoInputDevices:' + videoInputDevices.length);
|
|
if (videoInputDevices.length > 1) {
|
|
sourceSelect.innerHTML = '';
|
|
videoInputDevices.forEach((device) => {
|
|
const sourceOption = document.createElement('option');
|
|
if (device.label === '') {
|
|
sourceOption.text = 'Camera' + (sourceSelect.length + 1);
|
|
} else {
|
|
sourceOption.text = device.label
|
|
}
|
|
sourceOption.value = device.deviceId
|
|
if (selectedDeviceId != null && device.deviceId == selectedDeviceId) {
|
|
sourceOption.selected = true
|
|
}
|
|
sourceSelect.appendChild(sourceOption)
|
|
})
|
|
|
|
sourceSelect.onchange = () => {
|
|
selectedDeviceId = sourceSelect.value;
|
|
inst.invokeMethodAsync('SelectDeviceID', selectedDeviceId, sourceSelect.options[sourceSelect.selectedIndex].text);
|
|
codeReader.reset();
|
|
start(elementid);
|
|
}
|
|
|
|
sourceSelectPanel.style.display = 'block'
|
|
}
|
|
|
|
start(elementid);
|
|
|
|
})
|
|
.catch((err) => {
|
|
console.log(err)
|
|
inst.invokeMethodAsync("GetError", err + '');
|
|
})
|
|
|
|
})
|
|
.catch((err) => {
|
|
console.error(`An error occurred: ${err}`);
|
|
inst.invokeMethodAsync('GetError', `An error occurred: ${err}`);
|
|
});
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
export function start(elementid) {
|
|
if (undefined !== codeReader && null !== codeReader && id == elementid) {
|
|
if (opt.decodeonce) {
|
|
codeReader.decodeOnceFromVideoDevice(selectedDeviceId, 'video').then((result) => {
|
|
if (debug) console.log(result)
|
|
vibrate();
|
|
if (debug) console.log('autostop');
|
|
codeReader.reset();
|
|
return inst.invokeMethodAsync("GetResult", result.text);
|
|
}).catch((err) => {
|
|
if (err && !(err instanceof ZXing.NotFoundException)) {
|
|
console.log(err)
|
|
inst.invokeMethodAsync("GetError", err + '');
|
|
}
|
|
})
|
|
} else {
|
|
codeReader.decodeFromVideoDevice(selectedDeviceId, 'video', (result, err) => {
|
|
if (result) {
|
|
if (debug) console.log(result)
|
|
vibrate();
|
|
if (debug) console.log('None-stop');
|
|
inst.invokeMethodAsync("GetResult", result.text);
|
|
}
|
|
if (err && !(err instanceof ZXing.NotFoundException)) {
|
|
console.log(err)
|
|
inst.invokeMethodAsync("GetError", err + '');
|
|
}
|
|
})
|
|
}
|
|
|
|
var x = `decodeContinuously`;
|
|
if (opt.decodeonce) x = `decodeOnce`;
|
|
if (debug) console.log(`Started ` + x + ` decode from camera with id ${selectedDeviceId}`)
|
|
if (debug) console.log(id, 'start');
|
|
}
|
|
}
|
|
|
|
export function stop(elementid) {
|
|
if (undefined !== codeReader && null !== codeReader && id == elementid) {
|
|
codeReader.reset();
|
|
if (debug) console.log(id, 'stop');
|
|
}
|
|
}
|
|
|
|
export function QRCodeSvg(instance, input, element, tobase64, size = 300) {
|
|
const codeWriter = new ZXing.BrowserQRCodeSvgWriter()
|
|
|
|
if (debug) console.log('ZXing code writer initialized')
|
|
|
|
if (tobase64) {
|
|
const elementTemp = document.createElement('elementTemp');
|
|
codeWriter.writeToDom(elementTemp, input, size, size)
|
|
let svgElement = elementTemp.firstChild
|
|
const svgData = (new XMLSerializer()).serializeToString(svgElement)
|
|
//const blob = new Blob([svgData])
|
|
instance.invokeMethodAsync("GetQRCode", svgData);
|
|
} else {
|
|
codeWriter.writeToDom(element.querySelector("[data-action=result]"), input, size, size)
|
|
}
|
|
}
|
|
|
|
export function DecodeFormImage(instance, element, options, data) {
|
|
var codeReaderImage = null;
|
|
const hints = genHints(options);
|
|
if (options.pdf417) {
|
|
codeReaderImage = new ZXing.BrowserPDF417Reader(hints);
|
|
if (debug) console.log('ZXing code PDF417 reader initialized')
|
|
} else if (options.decodeAllFormats) {
|
|
const formats = options.formats;
|
|
hints.set(ZXing.DecodeHintType.POSSIBLE_FORMATS, formats);
|
|
codeReaderImage = new ZXing.BrowserMultiFormatReader(hints)
|
|
if (debug) console.log('ZXing code reader initialized with all formats')
|
|
} else {
|
|
codeReaderImage = new ZXing.BrowserMultiFormatReader(hints)
|
|
if (debug) console.log('ZXing code reader initialized')
|
|
}
|
|
if (debug) console.log('ZXing code reader initialized')
|
|
|
|
if (data != null) {
|
|
codeReaderImage.decodeFromImageUrl(data).then(result => {
|
|
if (result) {
|
|
vibrate();
|
|
if (debug) console.log(result.text);
|
|
instance.invokeMethodAsync('GetResult', result.text)
|
|
}
|
|
}).catch((err) => {
|
|
if (err) {
|
|
console.log(err)
|
|
instance.invokeMethodAsync('GetError', err.message)
|
|
}
|
|
})
|
|
|
|
}
|
|
else {
|
|
const resetFile = () => {
|
|
let file = element.querySelector('[type="file"]')
|
|
if (file) {
|
|
file.removeEventListener('change', scanImageHandler)
|
|
file.remove()
|
|
}
|
|
file = document.createElement('input')
|
|
file.setAttribute('type', 'file')
|
|
file.setAttribute('hidden', 'true')
|
|
file.setAttribute('accept', 'image/*')
|
|
//file.setAttribute('capture', 'true')
|
|
element.append(file)
|
|
file.addEventListener('change', scanImageHandler)
|
|
codeReaderImage.file = file
|
|
return file
|
|
}
|
|
|
|
const scanImageHandler = () => {
|
|
const files = codeReaderImage.file.files
|
|
if (files.length === 0) {
|
|
return
|
|
}
|
|
|
|
|
|
const reader = new FileReader()
|
|
reader.onloadend = e => {
|
|
|
|
codeReaderImage.decodeFromImageUrl(e.target.result).then(result => {
|
|
if (result) {
|
|
vibrate();
|
|
if (debug) console.log(result.text);
|
|
instance.invokeMethodAsync('GetResult', result.text)
|
|
} else {
|
|
instance.invokeMethodAsync('GetError', "no valid barcode detected")
|
|
}
|
|
}).catch((err) => {
|
|
if (err) {
|
|
console.log(err)
|
|
instance.invokeMethodAsync('GetError', err.message)
|
|
}
|
|
})
|
|
}
|
|
reader.readAsDataURL(files[0])
|
|
}
|
|
|
|
let file = resetFile()
|
|
file.click()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
export function destroy(elementid) {
|
|
if (undefined !== codeReader && null !== codeReader && id == elementid) {
|
|
codeReader.reset();
|
|
codeReader = null;
|
|
//id = null;
|
|
id = null;
|
|
opt = null;
|
|
inst = null;
|
|
selectedDeviceId = null;
|
|
deviceID = null;
|
|
element = null;
|
|
if (debug) console.log(id, 'destroy');
|
|
}
|
|
} |