为了适应公司代码全程使用jquery构造 如需其他js或者vue 可根据此代码去改(因为好多地方会用到这个东西所以我封装成了一个js文件)
https://dragonir.github.io/h5-scan-qrcode/#/
这个是效果 可以提前看一下~
我做的比这个效果多一个拿取本地图库的二维码扫码
scancode ---- html文件 如何引入js
scancode.js---- 封装的js文件
jsQR.js ---- 是这个插件所用的一个js可以在vue文件里面直接拿出来 可以去官网看看(不想动手的 麻烦踢踢后台的我 给你们私发!)
jquery.js ----这就不用说了吧
scancode.html
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script src="jquery-3.1.1.min.js"></script> <script type="text/javascript" src="scancode.js?v=1"></script> <script type="text/javascript" src="jsQR.js"></script> </head> <body> <div class=""> <button id="search_scans">点击扫码</button> <input type="text" id="assetTableSearch"> //扫码内容复现到此input上 </div> </body> <script> $(function (){ scancode({btn:$('#search_scans'),input:$('#assetTableSearch')}) }) </script> </html>
复制
scancode.js
/* 示例: scancode({ btn:$('#search_scans'), //打开扫码的按钮 input:$('#assetTableSearch'), //扫码内容写入的input 可选 callback:function(code){ //扫码成功回调 可选 console.log(code) } }) */ (function(global){ global.scancode = function(opt){ return new ScanCode(opt); } function ScanCode(opt){ this.init(opt); } ScanCode.prototype = { constructor: ScanCode, //扫码识别将内容展示到输入框内 opt是对象 btn:按钮名称 input:输入框 callback:返回数据 init: function(opt){ this.opt = opt this.addDom() //添加dom元素 this.addCss() //添加class元素 this.addEvent() //添加事件 this.closeScan() //初始化关闭事件 this.addLocalGallery() //调取本地图库 }, addLocalGallery:function (){ $('#scan_bendi_pic').on('click',function (){ $('#scan_bendi').click() }) }, addDom:function (){ if($('#scan_code_scaner').length === 0){ var html = '<div id="scan_code_scaner">' +'<i id="scan_code_close_icon"></i>' +'<div id="scan_code_banner"><p >若当前浏览器无法扫码,请切换其他浏览器尝试</p></div>' +'<div class="scan_code_cover">\n' + ' <p class="scan_code_line"></p>\n' + ' <span class="scan_code_square_top_left"></span>\n' + ' <span class="scan_code_square_top_right"></span>\n' + ' <span class="scan_code_square_bottom_right"></span>\n' + ' <span class="scan_code_square_bottom_left"></span>\n' + ' <p class="scan_code_tips">将二维码放入框内,即可自动扫描</p>\n' + ' </div>' +' <video\n' + ' id="scan_code_video"\n' + ' width="100%"\n' + ' height="100%"\n' + ' controls\n' + ' ></video>' +'<canvas id="scan_code_canvas"/>' +'<div id="scan_bendi_pic"></div>' //如果不想扫码 可点击图库 扫图库里面的二维码 +'<input type="file" id="scan_bendi" ></input>' +'</div>' $('body').append(html); } }, addCss:function (){ if($('.scan-code-css').length===0){ var css = '<style class="scan-code-css">' +'#scan_code_scaner{display: none;background: #000000;position: fixed;top: 0;left: 0; width: 100%;height: 100%;}' +'#scan_code_scaner #scan_code_banner{ width: 340px;position: absolute;top: 10%; left: 50%;margin-left: -170px;background: #FA74A2;border-radius: 8px;box-sizing: border-box;padding: 12px;opacity: 0.9;box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.2);}' +'#scan_code_scaner #scan_code_banner p{ padding: 0;\n' + ' margin: 0;\n' + ' color: #FFFFFF;\n' + ' font-size: 12px;\n' + ' text-align: justify;\n' + ' text-align-last: left;}' +'#scan_code_close_icon{display: inline-block;\n' + ' height: 24px;\n' + ' width: 24px;\n' + ' background: url("data:image/svg+xml;charset=utf-8,") no-repeat center;\n' + ' background-size: auto 100%;\n' + ' position: absolute;\n' + ' right: 10px;\n' + ' top: 15px;}' +'#scan_code_scaner .scan_code_cover{height: 220px;\n' + ' width: 220px;\n' + ' position: absolute;\n' + ' top:50%;\n' + ' left:50%;\n' + ' -webkit-transform: translate(-50%,-50%);\n' + ' -moz-transform: translate(-50%,-50%);\n' + ' -ms-transform: translate(-50%,-50%);\n' + ' -o-transform: translate(-50%,-50%);\n' + ' transform: translate(-50%,-50%);\n' + ' border: .5px solid #999999;\n' + ' z-index: 1111;}' +'#scan_code_scaner .scan_code_cover .scan_code_line{ width: 200px;\n' + ' height: 1px;\n' + ' margin-left: 10px;\n' + ' background: #5F68E8;\n' + ' background: linear-gradient(to right, transparent, #5F68E8, #0165FF, #5F68E8, transparent);\n' + ' position: absolute;\n' + ' -webkit-animation: scan 1.75s infinite linear;\n' + ' -moz-animation: scan 1.75s infinite linear;\n' + ' -ms-animation: scan 1.75s infinite linear;\n' + ' -o-animation: scan 1.75s infinite linear;\n' + ' animation: scan 1.75s infinite linear;\n' + ' -webkit-animation-fill-mode: both;\n' + ' -moz-animation-fill-mode: both;\n' + ' -ms-animation-fill-mode: both;\n' + ' -o-animation-fill-mode: both;\n' + ' animation-fill-mode: both;\n' + ' border-radius: 1px;}' +'#scan_code_scaner .scan_code_cover .scan_code_square_top_left{display: inline-block;\n' + ' height: 20px;\n' + ' width: 20px;\n' + ' position: absolute;\n' + ' top: 0;\n' + ' left: 0;\n' + ' border-left: 1px solid #5F68E8;\n' + ' border-top: 1px solid #5F68E8;}' +'#scan_code_scaner .scan_code_cover .scan_code_square_top_right{display: inline-block;\n' + ' height: 20px;\n' + ' width: 20px;\n' + ' position: absolute;\n' + ' top: 0;\n' + ' right: 0;\n' + ' border-right: 1px solid #5F68E8;\n' + ' border-top: 1px solid #5F68E8;}' +'#scan_code_scaner .scan_code_cover .scan_code_square_bottom_right{display: inline-block;\n' + ' height: 20px;\n' + ' width: 20px;\n' + ' position: absolute;\n' + ' bottom: 0;\n' + ' right: 0;\n' + ' border-right: 1px solid #5F68E8;\n' + ' border-bottom: 1px solid #5F68E8;}' +'#scan_code_scaner .scan_code_cover .scan_code_square_bottom_left{display: inline-block;\n' + ' height: 20px;\n' + ' width: 20px;\n' + ' position: absolute;\n' + ' bottom: 0;\n' + ' left: 0;\n' + ' border-left: 1px solid #5F68E8;\n' + ' border-bottom: 1px solid #5F68E8;}' +'#scan_code_scaner .scan_code_cover .scan_code_tips{' + 'position: absolute;\n' + ' bottom: -48px;\n' + ' width: 100%;\n' + ' font-size: 14px;\n' + ' color: #FFFFFF;\n' + ' opacity: 0.8;}' +'#scan_code_video{display: none;}' +'@-webkit-keyframes scan{0% {top: 0}\n' + ' 25% {top: 50px}\n' + ' 50% {top: 100px}\n' + ' 75% {top: 150px}\n' + ' 100% {top: 200px}}' +'@-moz-keyframes scan{ 0% {top: 0}\n' + ' 25% {top: 50px}\n' + ' 50% {top: 100px}\n' + ' 75% {top: 150px}\n' + ' 100% {top: 200px}}' +'@-o-keyframes scan{0% {top: 0}\n' + ' 25% {top: 50px}\n' + ' 50% {top: 100px}\n' + ' 75% {top: 150px}\n' + ' 100% {top: 200px}}' +'@keyframes scan{0% {top: 0}\n' + ' 25% {top: 50px}\n' + ' 50% {top: 100px}\n' + ' 75% {top: 150px}\n' + ' 100% {top: 200px}}' +'#scan_bendi_pic{' + ' background: url("data:image/svg+xml;charset=utf-8,");\n' + ' background-size: auto 100%;\n' + 'position: absolute;\n' + 'width: 20px;\n' + 'height: 20px;'+ 'bottom: 15px;\n' + 'left: 15px;}'+ '#scan_bendi{' + 'position: absolute;\n' + ' left: -2000px;\n' + ' bottom: 0px;}' +'</style>'; $('body').append(css); } }, addEvent:function (){ var obj = {}; this.obj = obj var _this = this; this.opt.btn.on('click',function (){ $('#scan_code_scaner').show() // 判断了浏览器是否支持挂载在MediaDevices.getUserMedia()的方法 if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { obj.lineColor='#03C03C'; obj.code = ''; obj.lineWidth = 2; obj.previousCode = null; obj.drawOnfound = true; obj.parity = 0; obj.active = true; obj.useBackCamera = true obj.canvas = document.getElementById('scan_code_canvas') obj.scan_code_video = document.getElementById('scan_code_video') obj.canvas_getContext = document.getElementById('scan_code_canvas').getContext("2d"); // 获取摄像头模式,默认设置是后置摄像头 const facingMode = obj.useBackCamera ? { exact: 'environment' } : 'user'; // 摄像头视频处理 const handleSuccess = stream => { if (obj.scan_code_video.srcObject !== undefined) { obj.scan_code_video.srcObject = stream; } else if (window.videoEl && window.videoEl.mozSrcObject !== undefined) { obj.scan_code_video.mozSrcObject = stream; } else if (window.URL && window.URL.createObjectURL) { obj.scan_code_video.src = window.URL.createObjectURL(stream); } else if (window.webkitURL) { obj.scan_code_video.src = window.webkitURL.createObjectURL(stream); } else { obj.scan_code_video.src = stream; } // 不希望用户来拖动进度条的话,可以直接使用playsinline属性,webkit-playsinline属性 obj.scan_code_video.playsInline = true; var playPromise = obj.scan_code_video.play(); playPromise.catch(() => { $('#scan_code_video').show() $('#scan_code_canvas').hide() }); // 视频开始播放时进行周期性扫码识别 playPromise.then(()=>{ _this.run() }); }; // 捕获视频流 navigator.mediaDevices .getUserMedia({ video: { facingMode } }) .then(handleSuccess) .catch(() => { navigator.mediaDevices .getUserMedia({ video: true }) .then(handleSuccess) .catch(error => { console.log(error) }); }); } }) $('#scan_bendi').on('change',function (event){ var docObj = document.getElementById("scan_bendi"); console.log(44444,docObj.files[0]) var URL = window.URL || window.webkitURL; // 兼容 var img = new Image(); // 创建图片对象 img.src = URL.createObjectURL(docObj.files[0]);//创建Image的对象的url img.onload = function () { // console.log(22222222,'height:'+this.height+'----width:'+this.width) _this.obj.canvas.width = this.width; _this.obj.canvas.height =this.height; URL.revokeObjectURL(img.src); _this.obj.canvas_getContext.drawImage(img, 0, 0, this.width, this.height) var imageData = _this.obj.canvas_getContext.getImageData( 0, 0, this.width, this.height) var code = jsQR(imageData.data, imageData.width, imageData.height); console.log("Found QR code", code); if(code.data){ obj.code = code.data if(_this.opt.input){ $(_this.opt.input).val(obj.code) } if(_this.opt.callback){ _this.opt.callback(code) } $('#scan_code_scaner').hide() _this.obj.scan_code_video.srcObject.getTracks().forEach(t => t.stop()); } } }) }, closeScan:function (){ $(document).on('click','#scan_code_close_icon',function (){ $('#scan_code_scaner').hide() }) }, drawLine:function (begin, end){ var obj = this.obj obj.canvas_getContext.beginPath(); obj.canvas_getContext.moveTo(begin.x, begin.y); obj.canvas_getContext.lineTo(end.x, end.y); obj.canvas_getContext.lineWidth = obj.lineWidth; obj.canvas_getContext.strokeStyle = obj.lineColor; obj.canvas_getContext.stroke(); }, run:function() { var obj = this.obj if (obj.active) { requestAnimationFrame(()=>{ this.tick() }) } }, tick:function () { var obj = this.obj if (obj.scan_code_video && obj.scan_code_video.readyState === obj.scan_code_video.HAVE_ENOUGH_DATA) { obj.canvas.height = document.documentElement.clientHeight || document.body.clientHeight; obj.canvas.width = document.documentElement.clientWidth || document.body.clientWidth; $('#scan_code_video').attr('height',obj.canvas.height) $('#scan_code_video').attr('width',obj.canvas.width) obj.canvas_getContext.drawImage(obj.scan_code_video, 0, 0, obj.canvas.width, obj.canvas.height); const imageData = obj.canvas_getContext.getImageData(0, 0, obj.canvas.width, obj.canvas.height); var code = false; try { code = jsQR(imageData.data, imageData.width, imageData.height); } catch (e) { console.error(e); } if (code) { this.drawBox(code.location); this.found(code.data); } } this.run(); }, drawBox:function (location) { var obj = this.obj if (obj.drawOnfound) { this.drawLine(location.topLeftCorner, location.topRightCorner); this.drawLine(location.topRightCorner, location.bottomRightCorner); this.drawLine(location.bottomRightCorner, location.bottomLeftCorner); this.drawLine(location.bottomLeftCorner, location.topLeftCorner); } }, found:function (code) { var obj = this.obj if (obj.previousCode !== code) { obj.previousCode = code; } else if (obj.previousCode === code) { obj.parity += 1; } if (obj.parity > 2) { obj.active = true; obj.parity = 0; obj.code = code if(this.opt.input){ $(this.opt.input).val(obj.code) } if(this.opt.callback){ this.opt.callback(code) } $('#scan_code_scaner').hide() obj.scan_code_video.srcObject.getTracks().forEach(t => t.stop()); } }, } })(window)
复制