base.js 6.9 KB
Newer Older
MuGuiLin's avatar
MuGuiLin 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
; (function (window, QrCodeRecognition) {
    "use strict";

    if (typeof define === 'function' && define.amd) {
        define(QrCodeRecognition());
    } else if (typeof exports === 'object') {
        module.exports = QrCodeRecognition();
    } else {
        window.QrCodeRecognition = QrCodeRecognition();
    };

}(typeof window !== "undefined" ? window : this, () => {
    "use strict";
    return class QrCodeRecognition {
        constructor(opts = {}) {
            this.timer = null;
            this.result = "";
            this.isAnimation = true;
            this.lineWidth = opts.borderWidth || 3;
            this.strokeStyle = opts.lineColor || 'red';
            this.audio = new Audio(opts.audio || './js/tone.mp3');
            this.video = document.createElement('video');
            this.file = document.querySelector(opts.uploadId);
            this.cvsele = document.querySelector(opts.sweepId);
            this.canvas = this.cvsele.getContext('2d');
            this.seuccess = opts.seuccess || Function;
            this.error = opts.error || Function;
        };

        draw(begin, end) {
            this.canvas.beginPath();
            this.canvas.moveTo(begin.x, begin.y);
            this.canvas.lineTo(end.x, end.y);
            this.canvas.lineWidth = this.lineWidth;
            this.canvas.strokeStyle = this.strokeStyle;
            this.canvas.stroke();
        };

        cance() {
            this.isAnimation = false;
            cancelAnimationFrame(this.timer);
            setTimeout(() => {
                this.cvsele.style.display = "none";
            }, 1000);
        };

        untie() {
            if (this.video.readyState === this.video.HAVE_ENOUGH_DATA) {
                const { videoWidth, videoHeight } = this.video;
                this.cvsele.width = videoWidth;
                this.cvsele.height = videoHeight;
                this.canvas.drawImage(this.video, 0, 0, videoWidth, videoHeight);
                try {
                    const img = this.canvas.getImageData(0, 0, videoWidth, videoHeight);
                    document.querySelector('#imgurl').src = img;
                    const obj = jsQR(img.data, img.width, img.height, { inversionAttempts: 'dontInvert' });
                    if (obj) {
                        const loc = obj.location;
                        this.draw(loc.topLeftCorner, loc.topRightCorner);
                        this.draw(loc.topRightCorner, loc.bottomRightCorner);
                        this.draw(loc.bottomRightCorner, loc.bottomLeftCorner);
                        this.draw(loc.bottomLeftCorner, loc.topLeftCorner);
                        if (this.result != obj.data) {
                            this.audio.play();
                            this.cance();
                            this.seuccess(obj);
                        }
                    } else {
                        this.error("识别失败,请检查二维码是否正确!");
                    }
                } catch (err) {
                    this.error("识别失败,请检查二维码是否正确!", err);
                };
            };
            if (this.isAnimation) {
                this.timer = requestAnimationFrame(() => {
                    this.untie();
                });
            }
        };

        sweep() {
            this.isAnimation = true;
            this.cvsele.style.display = "block";
            navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
            if (navigator.mediaDevices) {
                navigator.mediaDevices.getUserMedia({
                    video: { facingMode: "environment" }
                }).then(stream => {
                    this.video.srcObject = stream;
                    this.video.setAttribute('playsinline', true);
                    this.video.setAttribute('webkit-playsinline', true);
                    this.video.addEventListener('loadedmetadata', () => {
                        this.video.play();
                        this.untie();
                    });
                }).catch(error => {
                    this.cance();
                    alert('对不起:未识别到扫描设备!');
                    // console.error(error.name + ":" + error.message + "," + error.constraint);
                });
            } else if (navigator.getUserMedia) {
                navigator.getUserMedia({
                    video: { facingMode: "environment" }
                }, (stream) => {
                    this.video.srcObject = stream;
                    this.video.setAttribute('playsinline', true);
                    this.video.setAttribute('webkit-playsinline', true);
                    this.video.addEventListener('loadedmetadata', () => {
                        this.video.play();
                        this.untie();
                    });
                }, (error) => {
                    this.cance();
                    alert('对不起:未识别到扫描设备!');
                    // console.error(error.name + ":" + error.message + "," + error.constraint);
                });
            } else {
                if (navigator.userAgent.toLowerCase().match(/chrome/) && location.origin.indexOf('https://') < 0) {
                    console.error('获取浏览器录音功能,因安全性问题,需要在localhost 或 127.0.0.1 或 https 下才能获取权限!');
                } else {
                    this.cance();
                    alert('对不起:未识别到扫描设备!');
                }
            };
        };

        upload() {
            this.cance();
            const file = this.file.files[0];
            const createObjectURL = window.createObjectURL || window.URL.createObjectURL || window.webkitURL.createObjectUR;

            const fReader = new FileReader();
            fReader.readAsDataURL(file); // Base64 8Bit字节码
            // fReader.readAsBinaryString(file);  // Binary 原始二进制
            // fReader.readAsArrayBuffer(file);   // ArrayBuffer 文件流
            fReader.onload = (e) => {
                document.querySelector('#imgurl').src = e.target.result || createObjectURL(file);
                e.target.result && Jimp.read(e.target.result).then(async (res) => {
                    const { data, width, height } = res.bitmap;
                    try {
                        const resolve = await jsQR(data, width, height);
                        this.audio.play();
                        this.seuccess(resolve);
                    } catch (err) {
                        this.error("识别失败,请检查二维码是否正确!", err);
                    } finally {
                        console.info("读取到的文件:", res);
                    }
                }).catch((err) => {
                    this.error("文件读取错误:", err);
                });
            };
        };
    };
}));