UNPKG

qrcode-reader-vue3

Version:

A set of Vue.js components for detecting and decoding QR codes.

113 lines (92 loc) 3.07 kB
import { DropImageFetchError } from "./errors.js"; import BarcodeDetector from "barcode-detector"; import { eventOn } from "callforth"; const adaptOldFormat = (detectedCodes) => { if (detectedCodes.length > 0) { const [firstCode] = detectedCodes; const [topLeftCorner, topRightCorner, bottomRightCorner, bottomLeftCorner] = firstCode.cornerPoints; return { content: firstCode.rawValue, location: { topLeftCorner, topRightCorner, bottomRightCorner, bottomLeftCorner, // not supported by native API: topLeftFinderPattern: {}, topRightFinderPattern: {}, bottomLeftFinderPattern: {}, }, imageData: null, binaryData: null, }; } else { return { content: null, location: null, imageData: null, binaryData: null, }; } }; /** * Continuously extracts frames from camera stream and tries to read * potentially pictured QR codes. */ export const keepScanning = (videoElement, options) => { const barcodeDetector = new BarcodeDetector({ formats: ["qr_code"] }); const { detectHandler, locateHandler, minDelay } = options; const processFrame = (state) => async (timeNow) => { if (videoElement.readyState > 1) { const { lastScanned, contentBefore, locationBefore } = state; if (timeNow - lastScanned >= minDelay) { const detectedCodes = await barcodeDetector.detect(videoElement); const { content, location, imageData, binaryData } = adaptOldFormat(detectedCodes); if (content !== null && content !== contentBefore) { detectHandler({ content, location, imageData, binaryData }); } if (location !== null || locationBefore !== null) { locateHandler(detectedCodes); } window.requestAnimationFrame( processFrame({ lastScanned: timeNow, contentBefore: content ?? contentBefore, locationBefore: location, binaryData: binaryData, }) ); } else { window.requestAnimationFrame(processFrame(state)); } } }; processFrame({ contentBefore: null, locationBefore: null, lastScanned: performance.now(), binaryData: null, })(); }; const imageElementFromUrl = async (url) => { if (url.startsWith("http") && url.includes(location.host) === false) { throw new DropImageFetchError(); } const image = document.createElement("img"); image.src = url; await eventOn(image, "load"); return image; }; export const processFile = async (file) => { const barcodeDetector = new BarcodeDetector({ formats: ["qr_code"] }); const detectedCodes = await barcodeDetector.detect(file); return adaptOldFormat(detectedCodes); }; export const processUrl = async (url) => { const barcodeDetector = new BarcodeDetector({ formats: ["qr_code"] }); const image = await imageElementFromUrl(url); const detectedCodes = await barcodeDetector.detect(image); return adaptOldFormat(detectedCodes); };