diff --git a/packages/qr-code-scanner/src/qr-code-scanner.js b/packages/qr-code-scanner/src/qr-code-scanner.js index 5b7e42f2c58a3a3106bf0fafc99f409b94a9337b..21f8ce487beca55d1bb9a5f2e177a21c8f631393 100644 --- a/packages/qr-code-scanner/src/qr-code-scanner.js +++ b/packages/qr-code-scanner/src/qr-code-scanner.js @@ -248,13 +248,13 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { let video = await createVideoElement(this._activeCamera); this._askPermission = false; - let lastVideoScanTime = -1; let lastCode = null; let lastSentData = null; let detector = new QRScanner(); + let detectorRunning = false; - const tick = async () => { + const tick = () => { this._requestID = null; if (video.readyState === video.HAVE_ENOUGH_DATA) { this._loading = false; @@ -277,18 +277,31 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { maskStartX = canvasElement.width/2 - maskWidth/2; maskStartY = canvasElement.height/2 - maskHeight/2; - let code = null; - // We only check for QR codes 5 times a second to improve performance - let shouldAnalyze = Math.abs(lastVideoScanTime - video.currentTime) >= 1/3; - if (shouldAnalyze) { - lastVideoScanTime = video.currentTime; - code = await detector.scan(canvasElement, maskStartX, maskStartY, maskWidth, maskHeight); - lastCode = code; - } else { - code = lastCode; + let lastVideo = video; + if (!detectorRunning) { + detectorRunning = true; + detector.scan(canvasElement, maskStartX, maskStartY, maskWidth, maskHeight).then((code) => { + detectorRunning = false; + // if we got restarted then the video element is new, so stop then. + if (lastVideo !== this._videoElement) + return; + lastCode = code; + + if (code) { + if (lastSentData !== code.data) { + this._outputData = code.data; + this.dispatchEvent(new CustomEvent("code-detected", + {bubbles: true, composed: true, detail: {'code': code.data}})); + } + lastSentData = code.data; + } else { + this._outputData = null; + lastSentData = null; + } + }); } - let matched = code ? code.data.match(this.matchRegex) !== null : false; + let matched = lastCode ? lastCode.data.match(this.matchRegex) !== null : false; //draw mask canvas.beginPath(); @@ -301,7 +314,7 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { canvas.fill(); canvas.beginPath(); - if (code) { + if (lastCode) { let okColor = getComputedStyle(this).getPropertyValue('--dbp-success-bg-color'); let notOkColor = getComputedStyle(this).getPropertyValue('--dbp-danger-bg-color'); canvas.fillStyle = matched ? okColor : notOkColor; @@ -329,18 +342,6 @@ export class QrCodeScanner extends ScopedElementsMixin(DBPLitElement) { this.dispatchEvent(new CustomEvent("scan-started", {bubbles: true, composed: true})); firstDrawDone = true; } - - if (code) { - if (lastSentData !== code.data) { - this._outputData = code.data; - this.dispatchEvent(new CustomEvent("code-detected", - {bubbles: true, composed: true, detail: {'code': code.data}})); - } - lastSentData = code.data; - } else { - this._outputData = null; - lastSentData = null; - } } console.assert(this._requestID === null); this._requestID = requestAnimationFrame(tick);