$(function () { var App = { init: function () { App.attachListeners(); }, attachListeners: function () { var self = this; $('.controls input[type=file]').on('change', event => { if (event.target.files && event.target.files.length) { App.decode(URL.createObjectURL(event.target.files[0])); } }); $('.controls button').on('click', event => { var input = document.querySelector('.controls input[type=file]'); if (input.files && input.files.length) { App.decode(URL.createObjectURL(input.files[0])); } }); $('.controls .reader-config-group').on('change', 'input, select', event => { event.preventDefault(); var $target = $(event.target), value = $target.attr('type') === 'checkbox' ? $target.prop('checked') : $target.val(), name = $target.attr('name'), state = self._convertNameToState(name); console.log(`Value of ${state} changed to ${value}`); self.setState(state, value); }); }, _accessByPath: function (obj, path, val) { var parts = path.split('.'), depth = parts.length, setter = (typeof val !== 'undefined') ? true : false; return parts.reduce((o, key, i) => { if (setter && (i + 1) === depth) { o[key] = val; } return key in o ? o[key] : {}; }, obj); }, _convertNameToState: function (name) { return name.replace('_', '.').split('-').reduce((result, value) => { return result + value.charAt(0).toUpperCase() + value.substring(1); }); }, detachListeners: function () { $('.controls input[type=file]').off('change'); $('.controls .reader-config-group').off('change', 'input, select'); $('.controls button').off('click'); }, decode: function (src) { var self = this, config = $.extend({}, self.state, { src: src }); Quagga.decodeSingle(config, result => { }); }, setState: function (path, value) { var self = this; if (typeof self._accessByPath(self.inputMapper, path) === 'function') { value = self._accessByPath(self.inputMapper, path)(value); } self._accessByPath(self.state, path, value); console.log(JSON.stringify(self.state)); App.detachListeners(); App.init(); }, inputMapper: { inputStream: { size: function (value) { return parseInt(value); } }, numOfWorkers: function (value) { return parseInt(value); }, decoder: { readers: function (value) { if (value === 'ean_extended') { return [{ format: 'ean_reader', config: { supplements: [ 'ean_5_reader', 'ean_2_reader' ] } }]; } return [{ format: value + '_reader', config: {} }]; } } }, state: { inputStream: { size: 800, singleChannel: false }, locator: { patchSize: 'medium', halfSample: true }, decoder: { readers: [{ format: 'code_128_reader', config: {} }] }, locate: true, src: null } }; App.init(); function calculateRectFromArea(canvas, area) { var canvasWidth = canvas.width, canvasHeight = canvas.height, top = parseInt(area.top) / 100, right = parseInt(area.right) / 100, bottom = parseInt(area.bottom) / 100, left = parseInt(area.left) / 100; top *= canvasHeight; right = canvasWidth - canvasWidth * right; bottom = canvasHeight - canvasHeight * bottom; left *= canvasWidth; return { x: left, y: top, width: right - left, height: bottom - top }; } Quagga.onProcessed(function (result) { var drawingCtx = Quagga.canvas.ctx.overlay, drawingCanvas = Quagga.canvas.dom.overlay, area; if (result) { if (result.boxes) { drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute('width')), parseInt(drawingCanvas.getAttribute('height'))); result.boxes.forEach(box => { if (box !== result.box) { Quagga.ImageDebug.drawPath(box, drawingCtx, 'green', 2); } }); } if (result.box) { Quagga.ImageDebug.drawPath(result.box, drawingCtx, '#00F', 2); } if (result.codeResult && result.codeResult.code) { Quagga.ImageDebug.drawPath(result.line, drawingCtx, 'red', 3); } if (App.state.inputStream.area) { area = calculateRectFromArea(drawingCanvas, App.state.inputStream.area); drawingCtx.strokeStyle = '#0F0'; drawingCtx.strokeRect(area.x, area.y, area.width, area.height); } } }); Quagga.onDetected(function (result) { var code = result.codeResult.code, $node, canvas = Quagga.canvas.dom.image; $node = $('