效果:
小程序自定义扫码区域
小程序中 camera 组件可以调用到相机权限,camera 组件能识别条形码二维码,camera 组件的显示大小是可以自己定义的,但是需要注意的是一个小程序页面只能有一个 camera 组件不能多个使用,博主写了个demo,需要的可以借鉴一下:
scan.wxml
<view class="scan">
<camera mode="scanCode" frame-size='large' flash="{{ cameraFlash }}" class="scan-view" bindscancode='scancode'></camera>
<view class="scan-line" animation="{{animation}}"></view>
</view>
scan.wxss
/* pages/scan/scan.wxss */
.scan {
width: 100%;
height: 100vh;
overflow: hidden;
position: relative;
clear: both;
color: #303030;
letter-spacing: 0.8rpx;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
background-color: #5F6267;
}
.scan_img {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.scan_img image {
width: 100%;
height: 100%;
vertical-align: top;
}
.scan-body{
width: 100%;
height: 100vh;
}
.scan-view {
position: absolute;
width: 85%;
height: 15%;
left: 50%;
top: 14%;
transform: translateX(-50%);
z-index: 999;
border: 2rpx solid red;
}
.scan-line {
position: absolute;
width: 85%;
height: 2rpx;
background-color: greenyellow;
top: 14%;
left: 7.5%;
z-index: 1000;
}
scan.js
// pages/scan/scan.js
var app = getApp();
const animation = wx.createAnimation({}); // 创建移动动画对象
// const innerAudioContext = wx.createInnerAudioContext() // 提示音
// innerAudioContext.src = ' mp3 文件网络地址 '
Page({
/**
* 页面的初始数据
*/
data: {
canScan: true
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
const { height, top } = wx.getMenuButtonBoundingClientRect();
this.setData({
menuButtonTop: `${top}px`,
menuButtonHeight: `${height}px`
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
this.startAnimation()
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
// 添加扫描动画
startAnimation() {
let down = true
setInterval(() => {
if (down) {
animation.translateY(100).step({ duration: 3000 })
} else {
animation.translateY(0).step({ duration: 3000 })
}
down = !down
this.setData({ animation: animation.export() })
}, 3000)
},
scancode(event) {
if (!this.data.canScan) {
return; // 如果不能扫码,直接返回
}
this.setData({ canScan: false }); // 设置为不能扫码
wx.vibrateShort() // 触发手机振动
// innerAudioContext.play() // 提示音
const { result } = event.detail // 获取校验扫描结果
console.log('扫描结果:', result);
//根据扫码结果发起请求
wx.request({
url: app.globalData.apiHost + '?m=Gastore&c=Search&a=suGoods', //这里是博主自己写的请求地址
method: 'POST',
data: {
bcode: result,
},
header: {
'content-type': 'application/x-www-form-urlencoded'
},
success(res) {
if (res.data.code == 0) {
console.log(res.data.data);
// wx.navigateTo({
// url: '/pages/detail/detail?goods_id=' + res.data.data, //扫码成功跳转页面
// })
} else {
wx.showToast({
title: res.data.msg,
icon: 'success',
duration: 2000
})
}
},
fail: function (res) {
console.log(res);
},
complete: () => { //添加连续扫码防抖处理,防止扫码发起多次请求
setTimeout(() => {
this.setData({ canScan: true }); // 恢复扫码状态
}, 5000); // 设置扫码间隔为2秒
}
});
},
})