Skip to content
This repository was archived by the owner on Apr 3, 2021. It is now read-only.

Commit 98ffdf3

Browse files
authored
Merge pull request #10 from ProgrammingLab/kp/qr-reader
QR Reader
2 parents 5ab2689 + 5bac491 commit 98ffdf3

3 files changed

Lines changed: 110 additions & 0 deletions

File tree

‎components/QRReader.vue‎

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<template>
2+
<div>
3+
<canvas id="capture" ref="capture">unavailable</canvas>
4+
</div>
5+
</template>
6+
7+
<style scoped>
8+
#capture {
9+
width: 100%;
10+
height: 100%;
11+
}
12+
</style>
13+
14+
<script>
15+
import jsQR from 'jsqr';
16+
17+
export default {
18+
data: () => ({
19+
running: false,
20+
video: null,
21+
dim: { width: 1280, height: 720 },
22+
offset: { x: 0, y: 0 },
23+
result: null,
24+
}),
25+
26+
async mounted() {
27+
this.$refs.capture.width = this.$refs.capture.scrollWidth;
28+
this.$refs.capture.height = this.$refs.capture.scrollHeight;
29+
this.dim = { width: this.$refs.capture.width, height: this.$refs.capture.height };
30+
},
31+
32+
methods: {
33+
async capture() {
34+
if (!this.running) {
35+
this.running = true;
36+
}
37+
38+
if (!this.video) {
39+
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
40+
try {
41+
const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment', ...this.dim } });
42+
this.video = document.createElement('video');
43+
this.video.srcObject = stream;
44+
45+
const settings = stream.getVideoTracks()[0].getSettings();
46+
this.offset.x = Math.floor((this.dim.width - settings.width) / 2);
47+
this.offset.y = Math.floor((this.dim.height - settings.height) / 2);
48+
} catch (err) {
49+
// eslint-disable-next-line no-console
50+
console.error(err);
51+
return;
52+
}
53+
}
54+
}
55+
if (this.video.paused) {
56+
this.video.play();
57+
}
58+
59+
const { capture } = this.$refs;
60+
const ctx = capture.getContext('2d');
61+
ctx.clearRect(0, 0, capture.width, capture.height);
62+
63+
window.requestAnimationFrame(this.capture_loop);
64+
},
65+
66+
stop() {
67+
this.video.pause();
68+
this.running = false;
69+
},
70+
71+
async capture_loop() {
72+
const ctx = this.$refs.capture.getContext('2d');
73+
ctx.drawImage(this.video, this.offset.x, this.offset.y);
74+
const code = jsQR(
75+
ctx.getImageData(0, 0, this.dim.width, this.dim.height).data,
76+
this.dim.width, this.dim.height,
77+
);
78+
79+
if (code) {
80+
this.video.pause();
81+
this.running = false;
82+
83+
// limeで囲う
84+
ctx.strokeStyle = 'lime';
85+
ctx.lineWidth = 2;
86+
ctx.beginPath();
87+
ctx.moveTo(code.location.topLeftCorner.x, code.location.topLeftCorner.y);
88+
ctx.lineTo(code.location.bottomLeftCorner.x, code.location.bottomLeftCorner.y);
89+
ctx.lineTo(code.location.bottomRightCorner.x, code.location.bottomRightCorner.y);
90+
ctx.lineTo(code.location.topRightCorner.x, code.location.topRightCorner.y);
91+
ctx.closePath();
92+
ctx.stroke();
93+
94+
this.result = code.data;
95+
this.$emit('success', code.data);
96+
}
97+
98+
if (this.running) {
99+
window.requestAnimationFrame(this.capture_loop);
100+
}
101+
},
102+
},
103+
};
104+
</script>

‎package-lock.json‎

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"dependencies": {
1616
"@nuxtjs/axios": "^5.3.6",
1717
"@nuxtjs/bulma": "^1.2.4",
18+
"jsqr": "^1.2.0",
1819
"nuxt": "^2.0.0"
1920
},
2021
"devDependencies": {

0 commit comments

Comments
 (0)