@ -0,0 +1,16 @@ |
|||||
|
{ |
||||
|
"version" : "1.0", |
||||
|
"configurations" : [ |
||||
|
{ |
||||
|
"playground" : "standard", |
||||
|
"type" : "uni-app:app-android" |
||||
|
}, |
||||
|
{ |
||||
|
"app-plus" : |
||||
|
{ |
||||
|
"launchtype" : "local" |
||||
|
}, |
||||
|
"type" : "uniCloud" |
||||
|
} |
||||
|
] |
||||
|
} |
@ -0,0 +1,46 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
<mumu-one-code @success='door' definition :readers='["code_128_reader"]'></mumu-one-code> |
||||
|
|
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import MumuOneCode from '@/uni_modules/mumu-oneCode/components/mumu-oneCode/mumu-oneCode.vue' |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
components:{ |
||||
|
MumuOneCode |
||||
|
}, |
||||
|
methods: { |
||||
|
door(code) { |
||||
|
// uni.scanCode({ |
||||
|
// success: (res) => { |
||||
|
// console.log(res); |
||||
|
// console.log(res.result); |
||||
|
// const houseIdMatch = res.result.match(/&houseId=([^&]*)/); |
||||
|
// const houseIdValue = houseIdMatch ? houseIdMatch[1] : null; |
||||
|
// uni.navigateTo({ |
||||
|
// url: `/subpages/house/pages/housePortrait/housePortrait?resiId=${houseIdValue}` |
||||
|
// }); |
||||
|
// }, |
||||
|
// fail: (err) => { |
||||
|
// console.error(err); |
||||
|
// } |
||||
|
// }); |
||||
|
console.log(code); |
||||
|
// .then(res => { |
||||
|
// uni.navigateBack() |
||||
|
// }) |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style> |
||||
|
|
||||
|
</style> |
@ -0,0 +1,18 @@ |
|||||
|
## 1.1.2(2023-01-03) |
||||
|
1. 修复在新版本 HBuilderX(3.6.15) 报错问题(ReferenceError: Can't find variable: typeot) |
||||
|
2. 更换 ES6 导入方式 |
||||
|
3. 更新一维码开源库(Quagga [最新github地址](https://github.com/ericblade/quagga2)) |
||||
|
## 1.1.1(2022-06-18) |
||||
|
1. 提高相机的清晰度 |
||||
|
2. 增加识别错误判断 |
||||
|
3. 对开源库的错误抓取,发生错误重新识别 |
||||
|
## 1.0.3(2022-06-13) |
||||
|
1. 修改 Quagga 库导入方式,改为本地导入 |
||||
|
2. 演示代码中添加商品码演示。默认一维码类型是 code_128_reader(企业码) |
||||
|
## 1.0.2(2022-05-30) |
||||
|
|
||||
|
更新 |
||||
|
## 1.0.1(2022-05-30) |
||||
|
更改介绍 |
||||
|
## 1.0.0(2022-05-30) |
||||
|
本版上线 |
@ -0,0 +1,16 @@ |
|||||
|
function loadJs() { |
||||
|
return new Promise((resolve,reject)=>{ |
||||
|
let script = document.createElement('script'); |
||||
|
script.type = "text/javascript"; |
||||
|
script.src= '//h5plugin.mumudev.top/public/getOneCode/quagga.min.js'; |
||||
|
document.body.appendChild(script); |
||||
|
script.onload = ()=>{ |
||||
|
resolve(); |
||||
|
} |
||||
|
script.onerror = ()=>{ |
||||
|
reject(); |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export default loadJs |
@ -0,0 +1,408 @@ |
|||||
|
<template> |
||||
|
<view class="canvasBox"> |
||||
|
<view class="box"> |
||||
|
<view class="line"></view> |
||||
|
<view class="angle"></view> |
||||
|
</view> |
||||
|
<view class="box2" v-if="isUseTorch"> |
||||
|
<view class="track" @click="openTrack"> |
||||
|
<svg t="1653920715959" class="icon" viewBox="0 0 1024 1024" version="1.1" |
||||
|
xmlns="http://www.w3.org/2000/svg" p-id="1351" width="32" height="32"> |
||||
|
<path |
||||
|
d="M651.353043 550.479503H378.752795L240.862609 364.315031c-3.688944-4.897391-5.660621-10.876025-5.660621-17.045466v-60.040745c0-15.773416 12.847702-28.621118 28.621118-28.621118h502.459627c15.773416 0 28.621118 12.847702 28.621118 28.621118v59.977143c0 6.105839-1.971677 12.084472-5.660621 17.045466l-137.890187 186.228074zM378.752795 598.308571v398.024348c0 15.328199 12.402484 27.667081 27.667081 27.667081h217.266087c15.328199 0 27.667081-12.402484 27.66708-27.667081V598.308571H378.752795z m136.300124 176.942112c-14.564969 0-26.331429-11.76646-26.331428-26.331428v-81.283975c0-14.564969 11.76646-26.331429 26.331428-26.331429 14.564969 0 26.331429 11.76646 26.331429 26.331429v81.283975c0 14.564969-11.76646 26.331429-26.331429 26.331428zM512 222.608696c-17.554286 0-31.801242-14.246957-31.801242-31.801243V31.801242c0-17.554286 14.246957-31.801242 31.801242-31.801242s31.801242 14.246957 31.801242 31.801242v159.006211c0 17.554286-14.246957 31.801242-31.801242 31.801243zM280.932174 205.881242c-9.47677 0-18.889938-4.197764-25.122981-12.275279L158.242981 67.991056a31.864845 31.864845 0 0 1 5.597019-44.648944 31.864845 31.864845 0 0 1 44.648944 5.597018l97.502609 125.551305a31.864845 31.864845 0 0 1-5.597019 44.648944c-5.787826 4.579379-12.656894 6.741863-19.46236 6.741863zM723.987081 205.881242c-6.805466 0-13.674534-2.162484-19.462361-6.678261a31.794882 31.794882 0 0 1-5.597018-44.648944l97.566211-125.551304a31.794882 31.794882 0 0 1 44.648944-5.597019 31.794882 31.794882 0 0 1 5.597019 44.648944l-97.566211 125.551305c-6.360248 8.077516-15.709814 12.27528-25.186584 12.275279z" |
||||
|
fill="#ffffff" p-id="1352"></path> |
||||
|
</svg> |
||||
|
{{ trackStatus ? '关闭闪光灯' : '打开闪光灯' }} |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="mask1 mask" :style="'height:' + maskHeight + 'px;'"></view> |
||||
|
<view class="mask2 mask" :style="'width:' + maskWidth + 'px;top:' + maskHeight + 'px'"></view> |
||||
|
<view class="mask3 mask" :style="'height:' + maskHeight + 'px;'"></view> |
||||
|
<view class="mask4 mask" :style="'width:' + maskWidth + 'px;top:' + maskHeight + 'px'"></view> |
||||
|
</view> |
||||
|
</template> |
||||
|
<script> |
||||
|
import Quagga from './quagga.min.js' |
||||
|
export default { |
||||
|
props: { |
||||
|
continue: { |
||||
|
type: Boolean, |
||||
|
default: false // false 监听一次 true 持续监听 |
||||
|
}, |
||||
|
exact: { |
||||
|
type: String, |
||||
|
default: 'environment' // environment 后摄像头 user 前摄像头 |
||||
|
}, |
||||
|
definition: { |
||||
|
type: Boolean, |
||||
|
default: false // fasle 正常 true 高清 |
||||
|
}, |
||||
|
readers: { |
||||
|
// 一维码类型 |
||||
|
type: Array, |
||||
|
default: () => ['code_128_reader'] |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
windowWidth: 0, |
||||
|
windowHeight: 0, |
||||
|
video: null, |
||||
|
canvas2d: null, |
||||
|
canvasDom: null, |
||||
|
canvasDom2: null, // 用于画框 |
||||
|
canvas2d2: null, |
||||
|
canvasWidth: 300, |
||||
|
canvasHeight: 200, |
||||
|
maskWidth: 0, |
||||
|
maskHeight: 0, |
||||
|
cpu: 1, |
||||
|
inter: 0, |
||||
|
|
||||
|
track: null, |
||||
|
isUseTorch: false, |
||||
|
trackStatus: false, |
||||
|
|
||||
|
isParse: false, |
||||
|
|
||||
|
data1: '', |
||||
|
data2: '' |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
if (origin.indexOf('https') === -1) throw '请在 https 环境中使用摄像头组件。' |
||||
|
|
||||
|
this.windowWidth = document.documentElement.clientWidth || document.body.clientWidth |
||||
|
this.windowHeight = document.documentElement.clientHeight || document.body.clientHeight |
||||
|
this.isParse = true |
||||
|
this.$nextTick(() => { |
||||
|
this.video = document.createElement('video') |
||||
|
this.video.width = this.windowWidth |
||||
|
this.video.height = this.windowHeight |
||||
|
|
||||
|
const canvas = document.createElement('canvas') |
||||
|
this.canvas = canvas |
||||
|
canvas.id = 'canvas' |
||||
|
canvas.width = this.canvasWidth |
||||
|
canvas.height = this.canvasHeight |
||||
|
canvas.style = 'display:none;' |
||||
|
|
||||
|
// 设置当前宽高 满屏 |
||||
|
const canvasBox = document.querySelector('.canvasBox') |
||||
|
canvasBox.append(this.video) |
||||
|
canvasBox.append(canvas) |
||||
|
canvasBox.style = `width:${this.windowWidth}px;height:${this.windowHeight}px;` |
||||
|
|
||||
|
this.canvas2d = canvas.getContext('2d') |
||||
|
|
||||
|
// 创建第二个canvas |
||||
|
const canvas2 = document.createElement('canvas') |
||||
|
this.canvas2 = canvas2 |
||||
|
canvas2.id = 'canvas2' |
||||
|
canvas2.width = this.canvasWidth |
||||
|
canvas2.height = this.canvasHeight |
||||
|
canvas2.style = |
||||
|
'position: absolute;top: 50%;left: 50%;z-index: 20;transform: translate(-50%, -50%);' |
||||
|
this.canvas2d2 = canvas2.getContext('2d') |
||||
|
canvasBox.append(canvas2) |
||||
|
|
||||
|
this.cpu = 1 // navigator.hardwareConcurrency || 1 |
||||
|
// console.log(navigator.hardwareConcurrency ) |
||||
|
|
||||
|
this.createMsk() |
||||
|
setTimeout(() => { |
||||
|
this.openScan() |
||||
|
}, 500) |
||||
|
}) |
||||
|
}, |
||||
|
methods: { |
||||
|
openScan() { |
||||
|
let width = this.transtion(this.windowHeight) |
||||
|
let height = this.transtion(this.windowWidth) |
||||
|
|
||||
|
const videoParam = { |
||||
|
audio: false, |
||||
|
video: { |
||||
|
facingMode: { |
||||
|
exact: this.exact |
||||
|
}, |
||||
|
width, |
||||
|
height |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
navigator.mediaDevices |
||||
|
.getUserMedia(videoParam) |
||||
|
.then(stream => { |
||||
|
this.video.srcObject = stream |
||||
|
this.video.setAttribute('playsinline', true) |
||||
|
this.video.play() |
||||
|
this.tick() |
||||
|
|
||||
|
this.track = stream.getVideoTracks()[0] |
||||
|
setTimeout(() => { |
||||
|
this.isUseTorch = this.track.getCapabilities().torch || null |
||||
|
}, 500) |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
console.log('设备不支持', err) |
||||
|
}) |
||||
|
}, |
||||
|
tick() { |
||||
|
if (!this.isParse) return |
||||
|
try { |
||||
|
if (this.video.readyState === this.video.HAVE_ENOUGH_DATA) { |
||||
|
this.canvas2d.drawImage( |
||||
|
this.video, |
||||
|
this.transtion(this.maskWidth), |
||||
|
this.transtion(this.maskHeight), |
||||
|
this.transtion(300), |
||||
|
this.transtion(200), |
||||
|
0, |
||||
|
0, |
||||
|
this.canvasWidth, |
||||
|
this.canvasHeight |
||||
|
) |
||||
|
const img = this.canvas.toDataURL('image/jpg') |
||||
|
|
||||
|
Quagga.decodeSingle({ |
||||
|
inputStream: { |
||||
|
size: 300 * 2 |
||||
|
}, |
||||
|
locator: { |
||||
|
patchSize: 'large', |
||||
|
halfSample: true |
||||
|
}, |
||||
|
numOfWorkers: this.cpu, |
||||
|
decoder: { |
||||
|
readers: this.readers |
||||
|
}, |
||||
|
locate: true, |
||||
|
src: img |
||||
|
}, |
||||
|
result => { |
||||
|
this.canvas2d2.clearRect(0, 0, this.canvasWidth, this.canvasHeight) |
||||
|
requestAnimationFrame(this.tick) |
||||
|
if (!result || !result.codeResult) return |
||||
|
|
||||
|
if (!this.data1) return (this.data1 = result.codeResult.code) |
||||
|
this.data2 = result.codeResult.code |
||||
|
console.log(this.data1, '-', this.data2) |
||||
|
if (this.data2 !== this.data1) return (this.data1 = '') |
||||
|
this.drawLine(result.box, result.line) |
||||
|
if (!this.continue) { |
||||
|
this.closeCamera() |
||||
|
} |
||||
|
this.$emit('success', result.codeResult.code) |
||||
|
} |
||||
|
) |
||||
|
} else { |
||||
|
requestAnimationFrame(this.tick) |
||||
|
} |
||||
|
} catch (e) { |
||||
|
console.log('出错了'); |
||||
|
requestAnimationFrame(this.tick) |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
drawLine(box, line) { |
||||
|
if (!line[0] || !line[0]['x']) return |
||||
|
this.canvas2d2.beginPath() |
||||
|
this.canvas2d2.moveTo(line[0]['x'] / 2, line[0]['y'] / 2) |
||||
|
this.canvas2d2.lineTo(line[1]['x'] / 2, line[1]['y'] / 2) |
||||
|
this.canvas2d2.lineWidth = 2 |
||||
|
this.canvas2d2.strokeStyle = '#FF3B58' |
||||
|
this.canvas2d2.stroke() |
||||
|
}, |
||||
|
|
||||
|
createMsk() { |
||||
|
this.maskWidth = this.windowWidth / 2 - 150 |
||||
|
this.maskHeight = this.windowHeight / 2 - 100 |
||||
|
}, |
||||
|
closeCamera() { |
||||
|
this.isParse = false |
||||
|
if (this.video.srcObject) { |
||||
|
this.video.srcObject.getTracks().forEach(track => { |
||||
|
track.stop() |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
transtion(number) { |
||||
|
return this.definition ? number * 2.6 : number * 1.6 |
||||
|
}, |
||||
|
|
||||
|
openTrack() { |
||||
|
this.trackStatus = !this.trackStatus |
||||
|
this.track.applyConstraints({ |
||||
|
advanced: [{ |
||||
|
torch: this.trackStatus |
||||
|
}] |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
beforeDestroy() { |
||||
|
this.closeCamera() |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style scoped> |
||||
|
page { |
||||
|
background-color: #333333; |
||||
|
} |
||||
|
|
||||
|
.canvasBox { |
||||
|
width: 100vw; |
||||
|
position: relative; |
||||
|
|
||||
|
background-image: linear-gradient(0deg, |
||||
|
transparent 24%, |
||||
|
rgba(32, 255, 77, 0.1) 25%, |
||||
|
rgba(32, 255, 77, 0.1) 26%, |
||||
|
transparent 27%, |
||||
|
transparent 74%, |
||||
|
rgba(32, 255, 77, 0.1) 75%, |
||||
|
rgba(32, 255, 77, 0.1) 76%, |
||||
|
transparent 77%, |
||||
|
transparent), |
||||
|
linear-gradient(90deg, |
||||
|
transparent 24%, |
||||
|
rgba(32, 255, 77, 0.1) 25%, |
||||
|
rgba(32, 255, 77, 0.1) 26%, |
||||
|
transparent 27%, |
||||
|
transparent 74%, |
||||
|
rgba(32, 255, 77, 0.1) 75%, |
||||
|
rgba(32, 255, 77, 0.1) 76%, |
||||
|
transparent 77%, |
||||
|
transparent); |
||||
|
background-size: 3rem 3rem; |
||||
|
background-position: -1rem -1rem; |
||||
|
z-index: 10; |
||||
|
background-color: #1110; |
||||
|
} |
||||
|
|
||||
|
.box { |
||||
|
width: 300px; |
||||
|
height: 200px; |
||||
|
position: absolute; |
||||
|
left: 50%; |
||||
|
top: 50%; |
||||
|
transform: translate(-50%, -50%); |
||||
|
overflow: hidden; |
||||
|
border: 0.1rem solid rgba(0, 255, 51, 0.2); |
||||
|
z-index: 11; |
||||
|
} |
||||
|
|
||||
|
.line { |
||||
|
height: calc(100% - 2px); |
||||
|
width: 100%; |
||||
|
background: linear-gradient(180deg, rgba(0, 255, 51, 0) 43%, #00ff33 211%); |
||||
|
border-bottom: 3px solid #00ff33; |
||||
|
transform: translateY(-100%); |
||||
|
animation: radar-beam 2s infinite alternate; |
||||
|
animation-timing-function: cubic-bezier(0.53, 0, 0.43, 0.99); |
||||
|
animation-delay: 1.4s; |
||||
|
} |
||||
|
|
||||
|
.box2 { |
||||
|
width: 300px; |
||||
|
height: 200px; |
||||
|
position: absolute; |
||||
|
left: 50%; |
||||
|
top: 50%; |
||||
|
transform: translate(-50%, -50%); |
||||
|
z-index: 20; |
||||
|
} |
||||
|
|
||||
|
.track { |
||||
|
position: absolute; |
||||
|
bottom: -100px; |
||||
|
left: 50%; |
||||
|
transform: translateX(-50%); |
||||
|
z-index: 20; |
||||
|
color: #fff; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.box:after, |
||||
|
.box:before, |
||||
|
.angle:after, |
||||
|
.angle:before { |
||||
|
content: ''; |
||||
|
display: block; |
||||
|
position: absolute; |
||||
|
width: 3vw; |
||||
|
height: 3vw; |
||||
|
z-index: 12; |
||||
|
border: 0.2rem solid transparent; |
||||
|
} |
||||
|
|
||||
|
.box:after, |
||||
|
.box:before { |
||||
|
top: 0; |
||||
|
border-top-color: #00ff33; |
||||
|
} |
||||
|
|
||||
|
.angle:after, |
||||
|
.angle:before { |
||||
|
bottom: 0; |
||||
|
border-bottom-color: #00ff33; |
||||
|
} |
||||
|
|
||||
|
.box:before, |
||||
|
.angle:before { |
||||
|
left: 0; |
||||
|
border-left-color: #00ff33; |
||||
|
} |
||||
|
|
||||
|
.box:after, |
||||
|
.angle:after { |
||||
|
right: 0; |
||||
|
border-right-color: #00ff33; |
||||
|
} |
||||
|
|
||||
|
@keyframes radar-beam { |
||||
|
0% { |
||||
|
transform: translateY(-100%); |
||||
|
} |
||||
|
|
||||
|
100% { |
||||
|
transform: translateY(0); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.msg { |
||||
|
text-align: center; |
||||
|
padding: 20rpx 0; |
||||
|
} |
||||
|
|
||||
|
.mask { |
||||
|
position: absolute; |
||||
|
z-index: 10; |
||||
|
background-color: rgba(0, 0, 0, 0.55); |
||||
|
} |
||||
|
|
||||
|
.mask1 { |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
} |
||||
|
|
||||
|
.mask2 { |
||||
|
right: 0; |
||||
|
height: 200px; |
||||
|
} |
||||
|
|
||||
|
.mask3 { |
||||
|
right: 0; |
||||
|
left: 0; |
||||
|
bottom: 0; |
||||
|
} |
||||
|
|
||||
|
.mask4 { |
||||
|
left: 0; |
||||
|
height: 200px; |
||||
|
} |
||||
|
</style> |
@ -0,0 +1,86 @@ |
|||||
|
{ |
||||
|
"id": "mumu-oneCode", |
||||
|
"displayName": "H5调用摄像头识别条形码(一维码),可开闪光灯(原生H5调用,不需要任何sdk,本地扫描识别,不需要后端)", |
||||
|
"version": "1.1.2", |
||||
|
"description": "在浏览器中调用手机摄像头进行扫码识别条形码 一维码识别 可开闪光灯,无须任何sdk。", |
||||
|
"keywords": [ |
||||
|
"一维码识别", |
||||
|
"条形码", |
||||
|
"条形码识别", |
||||
|
"摄像头", |
||||
|
"闪光灯", |
||||
|
"" |
||||
|
], |
||||
|
"repository": "", |
||||
|
"engines": { |
||||
|
"HBuilderX": "^3.1.0" |
||||
|
}, |
||||
|
"dcloudext": { |
||||
|
"sale": { |
||||
|
"regular": { |
||||
|
"price": "0.00" |
||||
|
}, |
||||
|
"sourcecode": { |
||||
|
"price": "0.00" |
||||
|
} |
||||
|
}, |
||||
|
"contact": { |
||||
|
"qq": "" |
||||
|
}, |
||||
|
"declaration": { |
||||
|
"ads": "无", |
||||
|
"data": "无", |
||||
|
"permissions": "摄像头" |
||||
|
}, |
||||
|
"npmurl": "", |
||||
|
"type": "component-vue" |
||||
|
}, |
||||
|
"uni_modules": { |
||||
|
"dependencies": [], |
||||
|
"encrypt": [], |
||||
|
"platforms": { |
||||
|
"cloud": { |
||||
|
"tcb": "y", |
||||
|
"aliyun": "y" |
||||
|
}, |
||||
|
"client": { |
||||
|
"Vue": { |
||||
|
"vue2": "y", |
||||
|
"vue3": "y" |
||||
|
}, |
||||
|
"App": { |
||||
|
"app-vue": "n", |
||||
|
"app-nvue": "n" |
||||
|
}, |
||||
|
"H5-mobile": { |
||||
|
"Safari": "y", |
||||
|
"Android Browser": "y", |
||||
|
"微信浏览器(Android)": "y", |
||||
|
"QQ浏览器(Android)": "y" |
||||
|
}, |
||||
|
"H5-pc": { |
||||
|
"Chrome": "y", |
||||
|
"IE": "n", |
||||
|
"Edge": "y", |
||||
|
"Firefox": "u", |
||||
|
"Safari": "y" |
||||
|
}, |
||||
|
"小程序": { |
||||
|
"微信": "n", |
||||
|
"阿里": "n", |
||||
|
"百度": "n", |
||||
|
"字节跳动": "n", |
||||
|
"QQ": "n", |
||||
|
"钉钉": "n", |
||||
|
"快手": "n", |
||||
|
"飞书": "n", |
||||
|
"京东": "n" |
||||
|
}, |
||||
|
"快应用": { |
||||
|
"华为": "u", |
||||
|
"联盟": "u" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,82 @@ |
|||||
|
## 插件简绍 |
||||
|
### 实现原理 |
||||
|
|
||||
|
> 一维码识别功能使用的是Quagga这个库。调用摄像头使用的 navigator.mediaDevices.getUserMedia 这个H5的api。通过 video 和 canvas 把摄像头获取到的数据展现到页面上,同时调用监听Quagga解析。 |
||||
|
|
||||
|
|
||||
|
### 使用环境 |
||||
|
需要https环境才能使用,本地测试可以在 manifest.json 中点击源码展示,找到h5 ,添加:"devServer" : { "https" : true} |
||||
|
|
||||
|
**请勿使用 UC浏览器 与 夸克等阿里旗下的浏览器,发现他们使用的内核都较低,无法正常获取视频流。在微信中可以正常使用,推荐在微信内打开演示案例 ** |
||||
|
|
||||
|
需要https环境才能使用!!! |
||||
|
|
||||
|
需要https环境才能使用!!! |
||||
|
|
||||
|
需要https环境才能使用!!! |
||||
|
|
||||
|
**打开闪光灯只有在安装chrome内核中可以使用。苹果设备上的浏览器全都是Webkit。** |
||||
|
|
||||
|
### 插件使用 |
||||
|
**插件已支持 uni_modules 支持组件easycom,以下代码演示的是普通使用** |
||||
|
|
||||
|
``` html |
||||
|
<!-- HTML --> |
||||
|
<mumu-one-code @success='handlerSuccess' definition :readers='["code_128_reader"]'></mumu-one-code> |
||||
|
``` |
||||
|
|
||||
|
``` javascript |
||||
|
// js |
||||
|
import MumuOneCode from '@/uni_modules/mumu-oneCode/components/mumu-oneCode/mumu-oneCode.vue' |
||||
|
|
||||
|
export default { |
||||
|
components: { MumuOneCode }, |
||||
|
methods: { |
||||
|
handlerSuccess(code) { |
||||
|
uni.showModal({ |
||||
|
content: code |
||||
|
}).then(res => { |
||||
|
uni.navigateBack() |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
``` |
||||
|
readers是一维码类型,需要更具实际需求填入。数组中可填多个,但是不推荐,因为不同类型中的一维码可能会被其他类型给解码出来,这样会导致解码不正确。具体类型规则可以百度。 |
||||
|
|
||||
|
- code_128_reader:企业内部常用,可带字母。一些电子产品类别的一维码就是这个编码 |
||||
|
- ean_reader :商品常用 |
||||
|
|
||||
|
|
||||
|
|
||||
|
### 相关API |
||||
|
|
||||
|
##### 可传属性(Props) |
||||
|
|
||||
|
| 参数 | 说明 | 类型 | 默认值 | |
||||
|
| ---------- | ------------------------------------------------------------ | ------- | ------------------- | |
||||
|
| continue | 是否连续获取。false 监听一次 true 持续监听 | Boolean | false | |
||||
|
| exact | 选调用摄像头。environment 后摄像头 user 前摄像头 | String | environment | |
||||
|
| readers | 一维码类型。可选: code_128_reader ean_reader ean_8_reader code_39_reader code_39_vin_reader codabar_reader upc_reader upc_e_reader i2of5_reader 2of5_reader code_93_reade | Array | ["code_128_reader"] | |
||||
|
| definition | 调用摄像头清晰度。fasle 正常 true 高清 | Boolean | false | |
||||
|
|
||||
|
|
||||
|
|
||||
|
##### 事件(Events) |
||||
|
|
||||
|
| 事件名 | 说明 | 回调参数 | |
||||
|
| ------- | ------------------------------ | ---------- | --- | |
||||
|
| success | 检查到二维码并读取到数据是回调 | 二维码数据 | |
||||
|
|
||||
|
### 案例演示 |
||||
|
 |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
 |
||||
|
|
||||
|
## 支持作者 |
||||
|
|
||||
|
 |
After Width: | Height: | Size: 5.7 KiB |
After Width: | Height: | Size: 2.0 KiB |
@ -0,0 +1,25 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="zh-CN"> |
||||
|
|
||||
|
<head> |
||||
|
<meta charset="UTF-8" /> |
||||
|
<script> |
||||
|
var __UniViewStartTime__ = Date.now(); |
||||
|
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') || |
||||
|
CSS.supports('top: constant(a)')) |
||||
|
document.write( |
||||
|
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' + |
||||
|
(coverSupport ? ', viewport-fit=cover' : '') + '" />') |
||||
|
</script> |
||||
|
<title>View</title> |
||||
|
<link rel="stylesheet" href="view.css" /> |
||||
|
</head> |
||||
|
|
||||
|
<body> |
||||
|
<div id="app"></div> |
||||
|
<script src="__uniappes6.js"></script> |
||||
|
<script src="view.umd.min.js"></script> |
||||
|
<script src="app-view.js"></script> |
||||
|
</body> |
||||
|
|
||||
|
</html> |
@ -0,0 +1,154 @@ |
|||||
|
/******/ (function(modules) { // webpackBootstrap
|
||||
|
/******/ // install a JSONP callback for chunk loading
|
||||
|
/******/ function webpackJsonpCallback(data) { |
||||
|
/******/ var chunkIds = data[0]; |
||||
|
/******/ var moreModules = data[1]; |
||||
|
/******/ var executeModules = data[2]; |
||||
|
/******/ |
||||
|
/******/ // add "moreModules" to the modules object,
|
||||
|
/******/ // then flag all "chunkIds" as loaded and fire callback
|
||||
|
/******/ var moduleId, chunkId, i = 0, resolves = []; |
||||
|
/******/ for(;i < chunkIds.length; i++) { |
||||
|
/******/ chunkId = chunkIds[i]; |
||||
|
/******/ if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) { |
||||
|
/******/ resolves.push(installedChunks[chunkId][0]); |
||||
|
/******/ } |
||||
|
/******/ installedChunks[chunkId] = 0; |
||||
|
/******/ } |
||||
|
/******/ for(moduleId in moreModules) { |
||||
|
/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { |
||||
|
/******/ modules[moduleId] = moreModules[moduleId]; |
||||
|
/******/ } |
||||
|
/******/ } |
||||
|
/******/ if(parentJsonpFunction) parentJsonpFunction(data); |
||||
|
/******/ |
||||
|
/******/ while(resolves.length) { |
||||
|
/******/ resolves.shift()(); |
||||
|
/******/ } |
||||
|
/******/ |
||||
|
/******/ // add entry modules from loaded chunk to deferred list
|
||||
|
/******/ deferredModules.push.apply(deferredModules, executeModules || []); |
||||
|
/******/ |
||||
|
/******/ // run deferred modules when all chunks ready
|
||||
|
/******/ return checkDeferredModules(); |
||||
|
/******/ }; |
||||
|
/******/ function checkDeferredModules() { |
||||
|
/******/ var result; |
||||
|
/******/ for(var i = 0; i < deferredModules.length; i++) { |
||||
|
/******/ var deferredModule = deferredModules[i]; |
||||
|
/******/ var fulfilled = true; |
||||
|
/******/ for(var j = 1; j < deferredModule.length; j++) { |
||||
|
/******/ var depId = deferredModule[j]; |
||||
|
/******/ if(installedChunks[depId] !== 0) fulfilled = false; |
||||
|
/******/ } |
||||
|
/******/ if(fulfilled) { |
||||
|
/******/ deferredModules.splice(i--, 1); |
||||
|
/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]); |
||||
|
/******/ } |
||||
|
/******/ } |
||||
|
/******/ |
||||
|
/******/ return result; |
||||
|
/******/ } |
||||
|
/******/ |
||||
|
/******/ // The module cache
|
||||
|
/******/ var installedModules = {}; |
||||
|
/******/ |
||||
|
/******/ // object to store loaded and loading chunks
|
||||
|
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
||||
|
/******/ // Promise = chunk loading, 0 = chunk loaded
|
||||
|
/******/ var installedChunks = { |
||||
|
/******/ "app-config": 0 |
||||
|
/******/ }; |
||||
|
/******/ |
||||
|
/******/ var deferredModules = []; |
||||
|
/******/ |
||||
|
/******/ // The require function
|
||||
|
/******/ function __webpack_require__(moduleId) { |
||||
|
/******/ |
||||
|
/******/ // Check if module is in cache
|
||||
|
/******/ if(installedModules[moduleId]) { |
||||
|
/******/ return installedModules[moduleId].exports; |
||||
|
/******/ } |
||||
|
/******/ // Create a new module (and put it into the cache)
|
||||
|
/******/ var module = installedModules[moduleId] = { |
||||
|
/******/ i: moduleId, |
||||
|
/******/ l: false, |
||||
|
/******/ exports: {} |
||||
|
/******/ }; |
||||
|
/******/ |
||||
|
/******/ // Execute the module function
|
||||
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); |
||||
|
/******/ |
||||
|
/******/ // Flag the module as loaded
|
||||
|
/******/ module.l = true; |
||||
|
/******/ |
||||
|
/******/ // Return the exports of the module
|
||||
|
/******/ return module.exports; |
||||
|
/******/ } |
||||
|
/******/ |
||||
|
/******/ |
||||
|
/******/ // expose the modules object (__webpack_modules__)
|
||||
|
/******/ __webpack_require__.m = modules; |
||||
|
/******/ |
||||
|
/******/ // expose the module cache
|
||||
|
/******/ __webpack_require__.c = installedModules; |
||||
|
/******/ |
||||
|
/******/ // define getter function for harmony exports
|
||||
|
/******/ __webpack_require__.d = function(exports, name, getter) { |
||||
|
/******/ if(!__webpack_require__.o(exports, name)) { |
||||
|
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); |
||||
|
/******/ } |
||||
|
/******/ }; |
||||
|
/******/ |
||||
|
/******/ // define __esModule on exports
|
||||
|
/******/ __webpack_require__.r = function(exports) { |
||||
|
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { |
||||
|
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); |
||||
|
/******/ } |
||||
|
/******/ Object.defineProperty(exports, '__esModule', { value: true }); |
||||
|
/******/ }; |
||||
|
/******/ |
||||
|
/******/ // create a fake namespace object
|
||||
|
/******/ // mode & 1: value is a module id, require it
|
||||
|
/******/ // mode & 2: merge all properties of value into the ns
|
||||
|
/******/ // mode & 4: return value when already ns object
|
||||
|
/******/ // mode & 8|1: behave like require
|
||||
|
/******/ __webpack_require__.t = function(value, mode) { |
||||
|
/******/ if(mode & 1) value = __webpack_require__(value); |
||||
|
/******/ if(mode & 8) return value; |
||||
|
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; |
||||
|
/******/ var ns = Object.create(null); |
||||
|
/******/ __webpack_require__.r(ns); |
||||
|
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); |
||||
|
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); |
||||
|
/******/ return ns; |
||||
|
/******/ }; |
||||
|
/******/ |
||||
|
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
|
/******/ __webpack_require__.n = function(module) { |
||||
|
/******/ var getter = module && module.__esModule ? |
||||
|
/******/ function getDefault() { return module['default']; } : |
||||
|
/******/ function getModuleExports() { return module; }; |
||||
|
/******/ __webpack_require__.d(getter, 'a', getter); |
||||
|
/******/ return getter; |
||||
|
/******/ }; |
||||
|
/******/ |
||||
|
/******/ // Object.prototype.hasOwnProperty.call
|
||||
|
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; |
||||
|
/******/ |
||||
|
/******/ // __webpack_public_path__
|
||||
|
/******/ __webpack_require__.p = "/"; |
||||
|
/******/ |
||||
|
/******/ var jsonpArray = this["webpackJsonp"] = this["webpackJsonp"] || []; |
||||
|
/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray); |
||||
|
/******/ jsonpArray.push = webpackJsonpCallback; |
||||
|
/******/ jsonpArray = jsonpArray.slice(); |
||||
|
/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]); |
||||
|
/******/ var parentJsonpFunction = oldJsonpFunction; |
||||
|
/******/ |
||||
|
/******/ |
||||
|
/******/ // run deferred modules from other chunks
|
||||
|
/******/ checkDeferredModules(); |
||||
|
/******/ }) |
||||
|
/************************************************************************/ |
||||
|
/******/ ([]); |
@ -0,0 +1 @@ |
|||||
|
{"@platforms":["android","iPhone","iPad"],"id":"__UNI__0A9CAB7","name":"epmet-work-mp","version":{"name":"1.0.0","code":"100"},"description":"{\r \"pagePath\": \"pages/information/information\",\r \"text\": \"数据\",\r \"iconPath\": \"images/home/information.png\",\r \"selectedIconPath\": \"images/home/informationSelected.png\"\r },","launch_path":"__uniappview.html","developer":{"name":"","email":"","url":""},"permissions":{"UniNView":{"description":"UniNView原生渲染"}},"plus":{"useragent":{"value":"uni-app","concatenate":true},"splashscreen":{"target":"id:1","autoclose":true,"waiting":true,"delay":0},"popGesture":"close","launchwebview":{"id":"1","kernel":"WKWebview"},"statusbar":{"immersed":"supportedDevice","style":"dark","background":"#fff"},"usingComponents":true,"nvueStyleCompiler":"uni-app","compilerVersion":3,"distribute":{"google":{"permissions":["<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>","<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>","<uses-permission android:name=\"android.permission.VIBRATE\"/>","<uses-permission android:name=\"android.permission.READ_LOGS\"/>","<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>","<uses-feature android:name=\"android.hardware.camera.autofocus\"/>","<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>","<uses-permission android:name=\"android.permission.CAMERA\"/>","<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>","<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>","<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>","<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>","<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>","<uses-feature android:name=\"android.hardware.camera\"/>","<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"]},"apple":{},"plugins":{"audio":{"mp3":{"description":"Android平台录音支持MP3格式文件"}}}},"uniStatistics":{"enable":false},"allowsInlineMediaPlayback":true,"safearea":{"background":"#FFFFFF","bottom":{"offset":"auto"}},"uni-app":{"compilerVersion":"4.29","control":"uni-v3","nvueCompiler":"uni-app","renderer":"auto","nvue":{"flex-direction":"column"},"nvueLaunchMode":"normal"},"tabBar":{"color":"#333333","selectedColor":"#3A80E7","backgroundColor":"#FFFFFF","borderStyle":"rgba(255,255,255,0.4)","custom":true,"list":[{"pagePath":"pages/index/index","text":"消息","iconPath":"static/images/home/message.png","selectedIconPath":"static/images/home/messageSelected.png"},{"pagePath":"pages/resiAndHouse/resiAndHouse","text":"人房","iconPath":"static/images/home/resiAndHouse.png","selectedIconPath":"static/images/home/resiAndHouseSelected.png"},{"pagePath":"pages/work2/work2","text":"工作","iconPath":"static/images/home/work.png","selectedIconPath":"static/images/home/workSelected.png"},{"pagePath":"pages/statistics/statistics","text":"统计","iconPath":"static/images/home/information.png","selectedIconPath":"static/images/home/informationSelected.png"},{"pagePath":"pages/mine/mine","text":"我的","iconPath":"static/images/home/mine.png","selectedIconPath":"static/images/home/mineSelected.png"}],"height":"50px","child":["lauchwebview"],"selected":0},"launch_path":"__uniappview.html"}} |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 380 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 665 B |
After Width: | Height: | Size: 520 B |
After Width: | Height: | Size: 573 B |
After Width: | Height: | Size: 464 B |
After Width: | Height: | Size: 668 B |
After Width: | Height: | Size: 519 B |
After Width: | Height: | Size: 659 B |
After Width: | Height: | Size: 505 B |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 499 B |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 3.3 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 3.7 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 7.4 KiB |
After Width: | Height: | Size: 612 B |
After Width: | Height: | Size: 607 B |
After Width: | Height: | Size: 770 B |
After Width: | Height: | Size: 943 B |
After Width: | Height: | Size: 238 B |
After Width: | Height: | Size: 967 B |
After Width: | Height: | Size: 91 KiB |
After Width: | Height: | Size: 891 B |
After Width: | Height: | Size: 447 B |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 793 B |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 857 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 565 B |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 96 KiB |
After Width: | Height: | Size: 1018 B |
After Width: | Height: | Size: 538 B |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 24 KiB |