Published
Edited
May 13, 2020
Fork of QR Scan
Importers
Insert cell
Insert cell
qr
Insert cell
Insert cell
function* qrScanner() {
const d = 380;

var scanner = html`
<div style="width: ${d}px; text-align: center; margin-bottom: 5px;">
<button id="start">Scan</button>
</div>
<div style="display: flex">
<div>
<video id="video" muted playsinline width="${d}" height="${d}" style="border: 1px solid #aaa"></video>
</div>
<div>
<textarea id="textarea" style="width: ${d}px; height: ${d -
30}px; margin-left: 20px; padding: 9px"></textarea>
</div>
</div>
<div style="display: none">
<label for="sources">Change video source:</label>
<select id="sources"></select>
</div>`;

scanner.value = null;

yield scanner;

var selectedDeviceId;

const startButton = document.getElementById('start');
const sources = document.getElementById('sources');
var video = document.getElementById('video');
const textarea = document.getElementById('textarea');
const pristineVideo = video.cloneNode();

textarea.oninput = () => {
scanner.value = textarea.value;
scanner.dispatchEvent(new CustomEvent("input", { bubbles: true }));
};

const codeReader = new ZXing.BrowserMultiFormatReader();
console.log('ZXing code reader initialized');

async function start() {
console.log(
`Started continous decode from camera with id ${selectedDeviceId}`
);
startButton.parentNode.style.display = 'none';

try {
let result = await codeReader.decodeOnceFromVideoDevice(
selectedDeviceId,
video
);
console.log(result);
scanner.value = result.text;
textarea.value = result.text;
scanner.dispatchEvent(new CustomEvent("input", { bubbles: true }));

// reset to initial
startButton.parentNode.style.display = 'block';
codeReader.stopStreams();
const container = video.parentNode;
container.removeChild(video);

video = pristineVideo.cloneNode();
container.appendChild(video);
} catch (err) {
console.error(err);
scanner.value = null;
scanner.dispatchEvent(new CustomEvent("input", { bubbles: true }));
}
}

console.log('searching cameras');
codeReader
.getVideoInputDevices()
.then(videoInputDevices => {
if (videoInputDevices.length === 0) {
throw new Error('no cameras!');
}

selectedDeviceId = videoInputDevices[0].deviceId;

if (videoInputDevices.length > 1) {
videoInputDevices.forEach(element => {
var sourceOption = document.createElement('option');
sourceOption.text = element.label;
sourceOption.value = element.deviceId;
sources.appendChild(sourceOption);
});
sources.onchange = () => {
selectedDeviceId = sources.value;
};
sources.parentNode.style.display = 'block';
}

startButton.addEventListener('click', start);
})
.catch(err => {
var errorMessage = document.createElement('p');
errorMessage.innerHTML = 'QR Scanner: ' + err.message;
video.style.display = 'none';
startButton.parentNode.style.display = 'none';
video.parentNode.appendChild(errorMessage);
});

return scanner;
}
Insert cell
ZXing = require("https://unpkg.com/@zxing/library@latest")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more