1.0.1 • Published 3 months ago

vue2-barcode-scan v1.0.1

Weekly downloads
-
License
MIT
Repository
-
Last release
3 months ago

安装:

npm install vue2-barcode-scan --save

引入:

import { QrcodeStream } from "vue2-barcode-scan";

注册:

components: { QrcodeStream },

组件中使用:

<qrcode-stream
   capture="camera"
   camera="rear"
   :torch="torchActive"
   @decode="onDecode"
   @init="onInit"
 >
</qrcode-stream>

Demo(H5页面中使用):

<template>
  <div class="scan-container">
    <div class="reader-box">
      <div class="ku-scanner">
        <qrcode-stream
          capture="camera"
          camera="rear"
          :torch="torchActive"
          @decode="scanCode"
          @init="onInit"
        >
          <div class="ku-scanner-content">
            <div class="ku-scanner-tooltip">将二维码/条码放入框内,即自动扫描</div>
            <div class="ku-scanner-section">
              <div class="ku-scanner-section-animation-line"></div>
              <div class="ku-scanner-section-angle"></div>
            </div>
          </div>
        </qrcode-stream>
      </div>
      <div class="ku-scanner-error">错误信息:{{ errorMsg }}</div>
      <div class="ku-scanner-decode-result">扫描结果:{{ resultMsg }}</div>
      <van-button type="default" @click="openFlash">打开手电筒</van-button>
    </div>
  </div>
</template>

<script>
import { Toast } from 'vant';
import { QrcodeStream } from 'vue2-barcode-scan';

export default {
	name: 'ScanBarCode',
	components: { NavBar, QrcodeStream },
	data() {
		return {
			title: '扫一扫',
			isWx: false,
			errorMsg: '',
			resultMsg: '',
			torchActive: false
		};
	},
	created() {
		// 判断是否是微信浏览器
		this.isWx = this.$store.getters.isWx;
	},
	mounted() {},
	methods: {
		scanCode(result) {
			this.resultMsg = result;
			Toast(result);
		},
		// 打开手电筒
		openFlash() {
			switch (this.torchActive) {
				case true:
					this.torchActive = false;
					break;
				case false:
					this.torchActive = true;
					break;
			}
		},
		// 检查是否调用摄像头
		async onInit(promise) {
			try {
				await promise;
			} catch (error) {
				if (error.name === 'NotAllowedError') {
					this.errorMsg = 'ERROR: 您需要授予相机访问权限';
				} else if (error.name === 'NotFoundError') {
					this.errorMsg = 'ERROR: 这个设备上没有摄像头';
				} else if (error.name === 'NotSupportedError') {
					this.errorMsg = 'ERROR: 所需的安全上下文(HTTPS、本地主机)';
				} else if (error.name === 'NotReadableError') {
					this.errorMsg = 'ERROR: 相机被占用';
				} else if (error.name === 'OverconstrainedError') {
					this.errorMsg = 'ERROR: 安装摄像头不合适';
				} else if (error.name === 'StreamApiNotSupportedError') {
					this.errorMsg = 'ERROR: 此浏览器不支持流API';
				}
			}
			Toast(this.errorMsg);
		}
	}
};
</script>

<style scoped lang="scss">
.scan-container {
	box-sizing: border-box;
	height: 100vh;
	overflow: hidden;
}
.reader-box{
	padding: 20px;
}
.ku-scanner-error {
	font-weight: bold;
	font-size: 14px;
	color: red;
}
.ku-scanner-decode-result {
	font-size: 14px;
	color: #000;
}
.ku-scanner {
	height: 282px;
	.ku-scanner-content {
		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;
		width: 100%;
		height: 281px;
		position: relative;
		background-color: rgba(18, 18, 18, 0);
		// 提示信息
		.ku-scanner-tooltip {
			width: 100%;
			height: 35px;
			line-height: 35px;
			font-size: 14px;
			text-align: center; /* color: #f9f9f9; */
			margin: 0 auto;
			position: absolute;
			top: 0;
			left: 0;
			color: #ffffff;
		}
		.ku-scanner-section {
			width: 213px;
			height: 213px;
			position: absolute;
			left: 50%;
			top: 50%;
			transform: translate(-50%, -50%);
			overflow: hidden;
			border: 0.1rem solid rgba(0, 255, 51, 0.2);
			// 装饰角
			&:after {
				content: '';
				display: block;
				position: absolute;
				width: 12px;
				height: 12px;
				border: 0.2rem solid transparent;
				top: 0;
				border-top-color: #00ff33;
				right: 0;
				border-right-color: #00ff33;
			}
			&:before {
				content: '';
				display: block;
				position: absolute;
				width: 12px;
				height: 12px;
				border: 0.2rem solid transparent;
				top: 0;
				border-top-color: #00ff33;
				left: 0;
				border-left-color: #00ff33;
			}
			// 装饰角
			.ku-scanner-section-angle {
				&:after {
					content: '';
					display: block;
					position: absolute;
					width: 12px;
					height: 12px;
					border: 0.2rem solid transparent;
					bottom: 0;
					border-bottom-color: #00ff33;
					right: 0;
					border-right-color: #00ff33;
				}
				&:before {
					content: '';
					display: block;
					position: absolute;
					width: 12px;
					height: 12px;
					border: 0.2rem solid transparent;
					bottom: 0;
					border-bottom-color: #00ff33;
					left: 0;
					border-left-color: #00ff33;
				}
			}
			// 扫描活动线
			.ku-scanner-section-animation-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;
			}
		}
	}
}
// 扫描活动线--上下 动画
@keyframes radar-beam {
	0% {
		transform: translateY(-100%);
	}

	100% {
		transform: translateY(0);
	}
}
</style>