提交 2e1fd333 编写于 作者: MuGuiLin's avatar MuGuiLin 🏡

add demo

上级 89f1f5cb
......@@ -4,32 +4,67 @@
}
.h1 {
padding: 10px;
padding : 10px;
text-align: center;
}
.menu{
.menu {
text-align: center;
}
.menu nav{
display: inline-block;
padding: 20px;
font-size: 20px;
.menu nav {
display : inline-block;
padding : 20px;
font-size : 20px;
font-weight: bold;
cursor: pointer;
cursor : pointer;
}
.menu nav.active{
.menu nav.active {
color: #42b983;
}
.main{
.main {
position: relative;
z-index : 1;
}
.main .create {
text-align: center;
}
.main .create input {
position : relative;
margin : 20px 0;
padding : 12px;
width : 300px;
font-size: 18px;
border : 1px solid #42b983;
overflow: hidden;
}
.main .create input[type="button"] {
color : white;
border : none;
background: #42b983;
cursor : pointer;
}
.main .create .qrcode img {
margin : 20px auto;
padding : 30px;
width : 360px;
height : 360px;
border-radius: 8px;
border : 2px solid gray;
}
.main .reader {
display : none;
text-align: center;
font-size: 16px;
font-size : 16px;
}
.main .reader .sweep {
......@@ -73,7 +108,7 @@
font-size : 16px;
}
.canvas {
.main .reader .canvas {
display : none;
box-sizing: border-box;
position : fixed;
......
......@@ -11,15 +11,20 @@
<body>
<menu class="menu" id="menu">
<nav>二维码生成</nav> |
<nav class="active">二维码识别</nav>
<nav class="active">二维码生成</nav> |
<nav>二维码识别</nav>
</menu>
<h1 class="h1">纯前端 JS :二维码:生成、扫描、识别 (HTML版)</h1>
<hr />
<main class="main">
<div class="reader">
<aside class="create">
<input type="text" id="code" value="http://www.muguilin.com" placeholder="请在这里输入要生成的内容!" />
<input type="button" value="生成" onclick="create()" />
<div class="qrcode" id="qrcode"></div>
</aside>
<aside class="reader">
<button class="sweep" onclick="sweep()">扫一扫</button>
<button class="sweep">
<input type="file" id="file" onchange="upload()" />从相册选择
......@@ -30,21 +35,39 @@
alt="当前识别的二维码" />
</div>
<textarea class="result" id="result" cols="32" rows="6" placeholder="二维码识别结果!"></textarea>
</div>
<canvas class="canvas" id="canvas"></canvas>
</aside>
</main>
<canvas class="canvas" id="canvas"></canvas>
<!-- 二维码生成 -->
<script src="./js/qrcode.js"></script>
<script>
const text = document.querySelector('#code');
const qrcode = new QRCode(document.querySelector('#qrcode'), {
text: "http://www.muguilin.com",
width: 300,
height: 300,
colorDark: "blue",
colorLight: "white",
correctLevel: QRCode.CorrectLevel.H
});
// 生成
function create() {
qrcode.clear();
qrcode.makeCode(text.value);
};
</script>
<!-- 二维码识别 -->
<script src="./js/jimp.js"></script>
<script src="./js/jsqr.js"></script>
<script src="./js/jsqr.min.js"></script>
<script src="./js/base.js"></script>
<script>
const result = document.querySelector('#result');
const QrCode = new QrCodeRecognition({
sweepId: '#canvas', // 扫一扫
uploadId: '#file', // 从相册选择
sweepId: '#canvas',
uploadId: '#file',
error: function (err) {
// 识别错误反馈
result.value = err;
......@@ -55,16 +78,33 @@
}
});
// 扫一扫
function sweep() {
result.value = '';
QrCode.sweep();
}
};
// 从相册选择
function upload() {
result.value = '';
QrCode.upload();
}
};
</script>
<!-- Demo页面交互 -->
<script>
const menu = [...document.querySelectorAll('nav')];
const aside = [...document.querySelectorAll('aside')];
menu.forEach((nav, n) => {
nav.onclick = () => {
aside.forEach((ele, a) => {
ele.style.display = 'none';
menu[a].classList.remove('active');
});
menu[n].classList.add('active');
aside[n].style.display = 'block';
}
});
</script>
</body>
......
......@@ -95,7 +95,9 @@
this.untie();
});
}).catch(error => {
console.error(error.name + "" + error.message + "" + error.constraint);
this.cance();
alert('对不起:未识别到扫描设备!');
// console.error(error.name + ":" + error.message + "," + error.constraint);
});
} else if (navigator.getUserMedia) {
navigator.getUserMedia({
......@@ -109,12 +111,15 @@
this.untie();
});
}, (error) => {
console.error(error.name + "" + error.message + "" + error.constraint);
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('对不起:未识别到扫描设备!');
}
};
......
此差异已折叠。
......@@ -4,6 +4,10 @@ GitHub:[https://github.com/MuGuiLin/QRCode](https://github.com/MuGuiLin/QRCode
### 纯前端 HTML / Vue :二维码:生成、扫描、识别、解析、扫一扫
### Demo:[https://muguilin.github.io/QRCode](https://muguilin.github.io/QRCode)
---
> 该Demo功能共分为:HTML版 和 Vue版 两个版本!
>
> 不依赖任何关于微信环境、微信JS-SDK,微信受权等!
......
* {
margin : 0;
padding: 0;
}
.h1 {
padding : 10px;
text-align: center;
}
.menu {
text-align: center;
}
.menu nav {
display : inline-block;
padding : 20px;
font-size : 20px;
font-weight: bold;
cursor : pointer;
}
.menu nav.active {
color: #42b983;
}
.main {
position: relative;
z-index : 1;
}
.main .create {
text-align: center;
}
.main .create input {
position : relative;
margin : 20px 0;
padding : 12px;
width : 300px;
font-size: 18px;
border : 1px solid #42b983;
overflow: hidden;
}
.main .create input[type="button"] {
color : white;
border : none;
background: #42b983;
cursor : pointer;
}
.main .create .qrcode img {
margin : 20px auto;
padding : 30px;
width : 360px;
height : 360px;
border-radius: 8px;
border : 2px solid gray;
}
.main .reader {
display : none;
text-align: center;
font-size : 16px;
}
.main .reader .sweep {
position : relative;
margin : 20px;
padding : 12px;
width : 300px;
font-size : 18px;
cursor : pointer;
color : white;
background: #42b983;
border : 1px solid #42b983;
overflow : hidden;
}
.main .reader .sweep input {
position : absolute;
font-size: 100px;
opacity : 0;
}
.main .reader .imgurl {
margin : 20px;
text-align: center;
}
.main .reader .imgurl img {
margin : 20px;
padding : 10px;
border : 1px solid gray;
border-radius: 8px;
width : 280px;
height : 260px;
}
.main .reader .result {
box-sizing : border-box;
padding : 10px;
border : 1px solid gray;
border-radius: 8px;
font-size : 16px;
}
.main .reader .canvas {
display : none;
box-sizing: border-box;
position : fixed;
top : 0;
right : 0;
bottom : 0;
left : 0;
width : 100vw;
height : 100vh;
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>二维码:生成、扫描、识别</title>
<link rel="stylesheet" href="./css/base.css" />
</head>
<body>
<menu class="menu" id="menu">
<nav class="active">二维码生成</nav> |
<nav>二维码识别</nav>
</menu>
<h1 class="h1">纯前端 JS :二维码:生成、扫描、识别 (HTML版)</h1>
<hr />
<main class="main">
<aside class="create">
<input type="text" id="code" value="http://www.muguilin.com" placeholder="请在这里输入要生成的内容!" />
<input type="button" value="生成" onclick="create()" />
<div class="qrcode" id="qrcode"></div>
</aside>
<aside class="reader">
<button class="sweep" onclick="sweep()">扫一扫</button>
<button class="sweep">
<input type="file" id="file" onchange="upload()" />从相册选择
</button>
<div class="imgurl">
<img id="imgurl"
src="https://raw.githubusercontent.com/MuGuiLin/QRCode/master/VueQRCode/src/assets/github.com.png"
alt="当前识别的二维码" />
</div>
<textarea class="result" id="result" cols="32" rows="6" placeholder="二维码识别结果!"></textarea>
<canvas class="canvas" id="canvas"></canvas>
</aside>
</main>
<!-- 二维码生成 -->
<script src="./js/qrcode.js"></script>
<script>
const text = document.querySelector('#code');
const qrcode = new QRCode(document.querySelector('#qrcode'), {
text: "http://www.muguilin.com",
width: 300,
height: 300,
colorDark: "blue",
colorLight: "white",
correctLevel: QRCode.CorrectLevel.H
});
// 生成
function create() {
qrcode.clear();
qrcode.makeCode(text.value);
};
</script>
<!-- 二维码识别 -->
<script src="./js/jimp.js"></script>
<script src="./js/jsqr.min.js"></script>
<script src="./js/base.js"></script>
<script>
const result = document.querySelector('#result');
const QrCode = new QrCodeRecognition({
sweepId: '#canvas',
uploadId: '#file',
error: function (err) {
// 识别错误反馈
result.value = err;
},
seuccess: function (res) {
// 识别成功反馈
result.value = res.data;
}
});
// 扫一扫
function sweep() {
result.value = '';
QrCode.sweep();
};
// 从相册选择
function upload() {
result.value = '';
QrCode.upload();
};
</script>
<!-- Demo页面交互 -->
<script>
const menu = [...document.querySelectorAll('nav')];
const aside = [...document.querySelectorAll('aside')];
menu.forEach((nav, n) => {
nav.onclick = () => {
aside.forEach((ele, a) => {
ele.style.display = 'none';
menu[a].classList.remove('active');
});
menu[n].classList.add('active');
aside[n].style.display = 'block';
}
});
</script>
</body>
</html>
\ No newline at end of file
; (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);
});
};
};
};
}));
\ No newline at end of file
此差异已折叠。
此差异已折叠。
此差异已折叠。
文件已添加
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册