Fixed Events; Added example for multiple types of barcodes

feature/109
Christoph Oberhofer 9 years ago
parent be70d72e0b
commit 2f2ed46cf3

3936
dist/quagga.js vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -11,7 +11,7 @@
font-style: normal;
}
[class^="icon-"], [class*=" icon-"] {
[class^="icon-"]:before, [class*=" icon-"]:before {
/* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon' !important;
speak: none;

@ -60,6 +60,7 @@
margin: -1rem;
border-radius: 2rem;
z-index: 100;
box-sizing: content-box;
}
.overlay__content video {
@ -223,13 +224,13 @@ header .headline {
}
/* line 34, ../sass/styles.scss */
header .headline h1 {
color: #FFDD69;
font-size: 3em;
margin-bottom: 0;
}
/* line 39, ../sass/styles.scss */
header .headline h2 {
.headline h2 {
margin-top: 0.2em;
color: #FFDD69;
}
/* line 45, ../sass/styles.scss */
@ -244,8 +245,7 @@ footer {
}
/* line 51, ../sass/styles.scss */
#container {
max-width: 640px;
.container {
margin: 20px auto;
padding: 10px;
}

@ -70,21 +70,23 @@ var App = {
}.bind(this));
},
attachListeners: function() {
var self = this;
document.querySelector('.input-field input + .button.scan')
.addEventListener("click", function onClick(e) {
e.preventDefault();
e.target.removeEventListener("click", onClick);
document.querySelector('.input-field input[type=file]').click();
});
document.querySelector('.input-field input[type=file]')
.addEventListener("change", function onChange(e) {
e.preventDefault();
e.target.removeEventListener("change", onChange);
if (e.target.files && e.target.files.length) {
self.decode(URL.createObjectURL(e.target.files[0]));
}
});
var self = this,
button = document.querySelector('.input-field input + .button.scan'),
fileInput = document.querySelector('.input-field input[type=file]');
button.addEventListener("click", function onClick(e) {
e.preventDefault();
button.removeEventListener("click", onClick);
document.querySelector('.input-field input[type=file]').click();
});
fileInput.addEventListener("change", function onChange(e) {
e.preventDefault();
fileInput.removeEventListener("change", onChange);
if (e.target.files && e.target.files.length) {
self.decode(URL.createObjectURL(e.target.files[0]));
}
});
}
};
App.init();

@ -21,21 +21,23 @@ var App = {
}.bind(this));
},
attachListeners: function() {
var self = this;
document.querySelector('.input-field input + .button.scan')
.addEventListener("click", function onClick(e) {
e.preventDefault();
e.target.removeEventListener("click", onClick);
document.querySelector('.input-field input[type=file]').click();
});
document.querySelector('.input-field input[type=file]')
.addEventListener("change", function onChange(e) {
e.preventDefault();
e.target.removeEventListener("change", onChange);
if (e.target.files && e.target.files.length) {
self.decode(URL.createObjectURL(e.target.files[0]));
}
});
var self = this,
button = document.querySelector('.input-field input + .button.scan'),
fileInput = document.querySelector('.input-field input[type=file]');
button.addEventListener("click", function onClick(e) {
e.preventDefault();
button.removeEventListener("click", onClick);
document.querySelector('.input-field input[type=file]').click();
});
fileInput.addEventListener("change", function onChange(e) {
e.preventDefault();
fileInput.removeEventListener("change", onChange);
if (e.target.files && e.target.files.length) {
self.decode(URL.createObjectURL(e.target.files[0]));
}
});
}
};
App.init();

@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>index</title>
<meta name="description" content="" />
<meta name="author" content="Christoph Oberhofer" />
<meta name="viewport" content="width=device-width; initial-scale=1.0" />
<link rel="stylesheet" type="text/css" href="../css/fonts.css" />
<link rel="stylesheet" type="text/css" href="../css/styles.css" />
<link rel="stylesheet" type="text/css" href="./styles.css" />
<link rel="stylesheet" type="text/css" href="../css/prism.css" />
</head>
<body>
<header>
<div class="headline">
<h1>QuaggaJS</h1>
<h2>An advanced barcode-scanner written in JavaScript</h2>
</div>
</header>
<section id="container" class="container">
<div class="controls">
<h3>Scan various barcodes continously</h3>
<button type="button" class="icon-barcode button scan">Start Scanning</button>
<div class="readers">
<label>
<span>EAN-13</span>
<input type="checkbox" checked name="ean_reader" />
</label>
<label>
<span>EAN-8</span>
<input type="checkbox" name="ean_8_reader" />
</label>
<label>
<span>UPC-E</span>
<input type="checkbox" name="upc_e_reader" />
</label>
<label>
<span>Code 39</span>
<input type="checkbox" checked name="code_39_reader" />
</label>
<label>
<span>Codabar</span>
<input type="checkbox" name="codabar_reader" />
</label>
<label>
<span>Code 128</span>
<input type="checkbox" checked name="code_128_reader" />
</label>
<label>
<span>Interleaved 2 of 5</span>
<input type="checkbox" name="i2of5_reader" />
</label>
</div>
<p>
Be aware that not all combinations play together nicely. Some
codes do not have a checksum (e.g. ITF).
</p>
</div>
<div class="overlay overlay--inline">
<div class="overlay__content">
<div class="overlay__close">X</div>
</div>
</div>
</section>
<ul class="results"></ul>
<script src="../../dist/quagga.js" type="text/javascript"></script>
<script src="index.js" type="text/javascript"></script>
<script src="../vendor/prism.js"></script>
</body>
</html>

@ -0,0 +1,96 @@
var Quagga = window.Quagga;
var App = {
_lastResult: null,
init: function() {
this.attachListeners();
},
activateScanner: function() {
var scanner = this.configureScanner('.overlay__content'),
onDetected = function (result) {
this.addToResults(result);
}.bind(this),
stop = function() {
scanner.stop(); // should also clear all event-listeners?
scanner.removeEventListener('detected', onDetected);
this.hideOverlay();
this.attachListeners();
}.bind(this);
this.showOverlay(stop);
console.log("activateScanner");
scanner.addEventListener('detected', onDetected).start();
},
addToResults: function(result) {
if (this._lastResult === result.codeResult.code) {
return;
}
this._lastResult = result.codeResult.code;
var results = document.querySelector('ul.results'),
li = document.createElement('li'),
format = document.createElement('span'),
code = document.createElement('span');
li.className = "result";
format.className = "format";
code.className = "code";
li.appendChild(format);
li.appendChild(code);
format.appendChild(document.createTextNode(result.codeResult.format));
code.appendChild(document.createTextNode(result.codeResult.code));
results.insertBefore(li, results.firstChild);
},
attachListeners: function() {
var button = document.querySelector('button.scan'),
self = this;
button.addEventListener("click", function clickListener (e) {
e.preventDefault();
button.removeEventListener("click", clickListener);
self.activateScanner();
});
},
showOverlay: function(cancelCb) {
document.querySelector('.container .controls')
.classList.add('hide');
document.querySelector('.overlay--inline')
.classList.add('show');
var closeButton = document.querySelector('.overlay__close');
closeButton.addEventListener('click', function closeHandler() {
closeButton.removeEventListener("click", closeHandler);
cancelCb();
});
},
hideOverlay: function() {
document.querySelector('.container .controls')
.classList.remove('hide');
document.querySelector('.overlay--inline')
.classList.remove('show');
},
querySelectedReaders: function() {
return Array.prototype.slice.call(document.querySelectorAll('.readers input[type=checkbox]'))
.filter(function(element) {
return !!element.checked;
})
.map(function(element) {
return element.getAttribute("name");
});
},
configureScanner: function(selector) {
var scanner = Quagga
.decoder({readers: this.querySelectedReaders()})
.locator({patchSize: 'medium'})
.fromVideo({
target: selector,
constraints: {
width: 600,
height: 600,
facingMode: "environment"
}
});
return scanner;
}
};
App.init();

@ -0,0 +1,140 @@
body {
display: flex;
flex-direction: column;
padding-bottom: 0;
height: 100%;
box-sizing: border-box;
}
body > header {
flex: 0 0 auto;
padding: 0.5rem 1rem;
}
* {
box-sizing: inherit;
}
header > .headline {
display: flex;
flex-direction: row;
align-items: center;
}
.headline h1, .headline h2 {
margin: 0;
}
.headline h2 {
font-size: 1.3rem;
text-align: right;
}
body > .container {
margin: 0;
flex: 1 1 auto;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
position: relative;
}
/* Controls */
/* Scan! Button */
.icon-barcode.scan {
font-size: x-large;
padding: 0.5rem;
text-align: center;
margin: 0 auto;
display: block;
width: 70%;
}
.icon-barcode.scan:before {
margin-right: 0.5rem;
}
/* Reader Checkboxes */
.controls .readers {
font-size: 1.3rem;
width: 70%;
margin: 2rem auto 0;
}
.controls .readers label {
display: flex;
flex-direction: row;
align-items: center;
}
.controls .readers input {
flex: 0 0 auto;
height: 1.5rem;
width: 1.5rem;
}
.controls .readers span {
flex: 1 1 auto;
}
/* Results */
body > .results {
flex: 0 0 auto;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
background-color: #DDD;
margin: 0;
padding: 0;
list-style-type: none;
padding: 0.25rem;
overflow-x: scroll;
-webkit-overflow-scrolling: touch;
border-top: 1px solid #777;
}
.results > li {
flex: 0 1 auto;
margin: 0.25rem;
background: #fff;
border-radius: 2px;
box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
}
.results:empty {
display: none;
}
.result {
display: flex;
flex-direction: column;
padding: 0.5rem;
}
.result > .format {
font-weight: bold;
}
.result > .code {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Scanner */
.container .controls.hide {
display: none;
}
.overlay--inline {
position: absolute;
display: none;
}
.overlay--inline.show {
display: block;
}

@ -47,83 +47,87 @@
<div class="collapsable-source">
<pre>
<code class="language-javascript">
var App = {
_scanner: null,
init: function() {
this.attachListeners();
},
activateScanner: function() {
var scanner = this.configureScanner('.overlay__content'),
onDetected = function (result) {
document.querySelector('input.isbn').value = result.codeResult.code;
stop();
}.bind(this),
stop = function() {
scanner.stop(); // should also clear all event-listeners?
scanner.removeEventListener('detected', onDetected);
this.hideOverlay();
this.attachListeners();
}.bind(this);
var Quagga = window.Quagga;
var App = {
_scanner: null,
init: function() {
this.attachListeners();
},
activateScanner: function() {
var scanner = this.configureScanner('.overlay__content'),
onDetected = function (result) {
document.querySelector('input.isbn').value = result.codeResult.code;
stop();
}.bind(this),
stop = function() {
scanner.stop(); // should also clear all event-listeners?
scanner.removeEventListener('detected', onDetected);
this.hideOverlay();
this.attachListeners();
}.bind(this);
this.showOverlay(stop);
scanner.addEventListener('detected', onDetected).start();
},
attachListeners: function() {
var self = this;
this.showOverlay(stop);
scanner.addEventListener('detected', onDetected).start();
},
attachListeners: function() {
var self = this,
button = document.querySelector('.input-field input + button.scan');
document.querySelector('.input-field input + button.scan')
.addEventListener("click", function onClick(e) {
e.preventDefault();
e.target.removeEventListener("click", onClick);
self.activateScanner();
});
},
showOverlay: function(cancelCb) {
if (!this._overlay) {
var content = document.createElement('div'),
closeButton = document.createElement('div');
button.addEventListener("click", function onClick(e) {
e.preventDefault();
button.removeEventListener("click", onClick);
self.activateScanner();
});
},
showOverlay: function(cancelCb) {
if (!this._overlay) {
var content = document.createElement('div'),
closeButton = document.createElement('div');
closeButton.appendChild(document.createTextNode('X'));
content.className = 'overlay__content';
closeButton.className = 'overlay__close';
this._overlay = document.createElement('div');
this._overlay.className = 'overlay';
this._overlay.appendChild(content);
content.appendChild(closeButton);
closeButton.addEventListener('click', function closeClick(e) {
e.target.removeEventListener('click', closeClick);
cancelCb();
closeButton.appendChild(document.createTextNode('X'));
content.className = 'overlay__content';
closeButton.className = 'overlay__close';
this._overlay = document.createElement('div');
this._overlay.className = 'overlay';
this._overlay.appendChild(content);
content.appendChild(closeButton);
closeButton.addEventListener('click', function closeClick() {
closeButton.removeEventListener('click', closeClick);
cancelCb();
});
document.body.appendChild(this._overlay);
} else {
var closeButton = document.querySelector('.overlay__close');
closeButton.addEventListener('click', function closeClick() {
closeButton.removeEventListener('click', closeClick);
cancelCb();
});
}
this._overlay.style.display = "block";
},
hideOverlay: function() {
if (this._overlay) {
this._overlay.style.display = "none";
}
},
configureScanner: function(selector) {
if (!this._scanner) {
this._scanner = Quagga
.decoder({readers: ['ean_reader']})
.locator({patchSize: 'medium'})
.fromVideo({
target: selector,
constraints: {
width: 800,
height: 600,
facingMode: "environment"
}
});
document.body.appendChild(this._overlay);
} else {
var closeButton = document.querySelector('.overlay__close');
closeButton.addEventListener('click', cancelCb);
}
this._overlay.style.display = "block";
},
hideOverlay: function() {
if (this._overlay) {
this._overlay.style.display = "none";
}
},
configureScanner: function(selector) {
if (!this._scanner) {
this._scanner = Quagga
.decoder({readers: ['ean_reader']})
.locator({patchSize: 'medium'})
.fromVideo({
target: selector,
constraints: {
width: 800,
height: 600,
facingMode: "environment"
}
});
}
return this._scanner;
}
};
App.init();
return this._scanner;
}
};
App.init();
</code>
</pre>
</div>

@ -21,14 +21,14 @@ var App = {
scanner.addEventListener('detected', onDetected).start();
},
attachListeners: function() {
var self = this;
var self = this,
button = document.querySelector('.input-field input + button.scan');
document.querySelector('.input-field input + button.scan')
.addEventListener("click", function onClick(e) {
e.preventDefault();
e.target.removeEventListener("click", onClick);
self.activateScanner();
});
button.addEventListener("click", function onClick(e) {
e.preventDefault();
button.removeEventListener("click", onClick);
self.activateScanner();
});
},
showOverlay: function(cancelCb) {
if (!this._overlay) {
@ -42,14 +42,17 @@ var App = {
this._overlay.className = 'overlay';
this._overlay.appendChild(content);
content.appendChild(closeButton);
closeButton.addEventListener('click', function closeClick(e) {
e.target.removeEventListener('click', closeClick);
closeButton.addEventListener('click', function closeClick() {
closeButton.removeEventListener('click', closeClick);
cancelCb();
});
document.body.appendChild(this._overlay);
} else {
var closeButton = document.querySelector('.overlay__close');
closeButton.addEventListener('click', cancelCb);
closeButton.addEventListener('click', function closeClick() {
closeButton.removeEventListener('click', closeClick);
cancelCb();
});
}
this._overlay.style.display = "block";
},

@ -60,7 +60,7 @@
"phantomjs": "^1.9.18",
"sinon": "^1.16.1",
"sinon-chai": "^2.8.0",
"webpack": "^2.1.0-beta.4",
"webpack": "^2.1.0-beta.7",
"webpack-sources": "^0.1.1"
},
"directories": {
@ -109,6 +109,6 @@
"lodash": "^4.6.1",
"ndarray": "^1.0.18",
"ndarray-linear-interpolate": "^1.0.0",
"webrtc-adapter": "^1.0.6"
"webrtc-adapter": "^1.2.2"
}
}

@ -50,10 +50,17 @@ export default function createEventedElement() {
var event = getEvent(eventName),
subscribers = event.subscribers;
event.subscribers = subscribers.filter(function(subscriber) {
subscribers.filter(function(subscriber) {
return !!subscriber.once;
}).forEach((subscriber) => {
publishSubscription(subscriber, data);
});
event.subscribers = subscribers.filter(function(subscriber) {
return !subscriber.once;
});
event.subscribers.forEach((subscriber) => {
publishSubscription(subscriber, data);
});
},
once: function(event, callback, async) {
subscribe(event, {

@ -36,11 +36,12 @@ function initCamera(video, constraints) {
.then((stream) => {
return new Promise((resolve, reject) => {
streamRef = stream;
video.src = window.URL.createObjectURL(stream);
video.onloadedmetadata = (e) => {
video.setAttribute("autoplay", 'true');
video.srcObject = stream;
video.addEventListener('loadedmetadata', (e) => {
video.play();
resolve();
};
});
});
})
.then(waitForVideo.bind(null, video));

@ -48,7 +48,7 @@ function fromImage(config, imageSrc, inputConfig = {}) {
toPromise() {
return new Promise((resolve, reject) => {
scanner.decodeSingle(config, (result) => {
if (result.codeResult && result.codeResult.code) {
if (result && result.codeResult && result.codeResult.code) {
return resolve(result);
}
return reject(result);
@ -80,7 +80,6 @@ function fromVideo(config, source, inputConfig = {}) {
} else if (typeof source === 'object'
&& (typeof source.constraints !== 'undefined'
|| typeof source.area !== 'undefined')) {
console.log("inputConfig");
inputConfig = source;
} else if (!source) {
// LiveStream

@ -69,7 +69,6 @@ function createScanner() {
}
_inputStream.setAttribute("preload", "auto");
_inputStream.setAttribute("autoplay", true);
_inputStream.setInputStream(_config.inputStream);
_inputStream.addEventListener("canrecord", canRecord.bind(undefined, cb));
}

Loading…
Cancel
Save