微信小程序自定义扫码界面

news/2024/7/20 1:22:43 标签: 微信小程序, 小程序

因扫码功能需支持自定义输入,调用微信 scanCode 无法自定义界面补充输入框,所以使用原生组件 camera。

一、Demo 演示

小程序自定义扫码演示

二、核心逻辑

1、调用摄像头扫码

将媒体组件 camera 应用模式设置为 scanCode,并绑定扫码识别成功方法

// wxml
<camera mode="scanCode" bindscancode='scancode' />

// js
scancode(event){
  const { result } = event.detail // 获取校验扫描结果
  wx.showToast({ title: `扫描结果:${result}`, icon: 'none' })
}
2、模拟扫码动画

为提升体验,模拟扫码动画

// wxml
<view class="scan-container">
  <view class="scan-box" />
  <view class='scan-animation' animation="{{animation}}" />
</view>

// js
const animation = wx.createAnimation({}); // 创建移动动画对象

// 扫描动画
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)
}

三、完整代码

JS 代码

const animation = wx.createAnimation({}); // 创建移动动画对象
const innerAudioContext = wx.createInnerAudioContext() // 提示音
innerAudioContext.src = 'https://qdstorage.okii.com/retail-app/common/beep.mp3'

Page({
  
  /**
   * Lifecycle function--Called when page load
   */
  onLoad() {
    const { height, top } = wx.getMenuButtonBoundingClientRect();

    this.setData({ 
      menuButtonTop: `${top}px`,
      menuButtonHeight: `${height}px`
    })
  },

  /**
   * Lifecycle function--Called when page show
   */
  onShow() {
    this.startAnimation()
  },

  // 扫描动画
  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){
    wx.vibrateShort() // 触发手机振动
    innerAudioContext.play() // 提示音
    const { result } = event.detail // 获取校验扫描结果

    wx.showToast({ title: `扫描结果:${result}`, icon: 'none' })
  },
  changeInputType() {
    wx.showToast({ title: '请自定义实现', icon: 'none' })
  },
  // 返回上一级
  goBack() {
    wx.showToast({ title: '请自定义实现', icon: 'none' })
  },
})

wxml 代码

<view class="custom-scan">
  <!-- 扫码区域 -->
  <camera
    mode="scanCode"
    frame-size='large'
    flash="{{ cameraFlash }}"
    class="scan-view"
    bindscancode='scancode' 
  >
    <view class="navigation-container" style="{{ 'height: ' + menuButtonHeight + ';padding-top: ' + menuButtonTop }}">
      <icon class="icon-close" type="cancel" size="30" color="#fff" bindtap="goBack" />
    </view>

    <view class="header-container">
      <view class="input-button" bindtap="changeInputType">手动输入</view>
    </view>
    <view class="scan-container">
      <view class="scan-box" />
      <view class='scan-animation' animation="{{animation}}" />
    </view>
  </camera>
</view>

less 代码

.custom-scan {
  width: 100vw;
  height: 100vh;

  .scan-view {
    width: 100%;
    height: 100%;
  }

  .navigation-container {
    display: flex;
    align-items: center;

    .icon-close {
      padding-left: 22px;
    }
  }

  .header-container {
    display: flex;
    justify-content: flex-end;
    padding: 80rpx 30rpx 40rpx 30rpx;
  
    .input-button {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 130rpx;
      height: 64rpx;
      border-radius: 54rpx;
      color: #eee;
      font-size: 24rpx;
      background-color: rgba(50, 50, 50, 0.6);
    }
  }

  .scan-container {
    display: flex;
    justify-content: center;
    margin-top: 60rpx;
    width: 100%;
    height: 100%;

    .scan-box {
      position: relative;
      width: 500rpx;
      height: 220rpx;
      border-radius: 20rpx;
      background-image: url("https://qdstorage.okii.com/retail-app/common/scan-box.png");
      background-size: 100% 100%;
    }

    .scan-animation {
      position: absolute;
      margin-top: 10rpx;
      width: 530rpx;
      height: 6rpx;
      background-color: #ddd;
      border-radius: 50%;
    }
  }
}

http://www.niftyadmin.cn/n/621608.html

相关文章

《Android学习指南》目录

Android学习指南的内容分类&#xff1a; 分类 描述 0.学习Android必备的Java基础知识 没有Java基础的朋友&#xff0c;请不要先看Android的课程&#xff0c;这样会很累。 1.Android学习指南基础篇 对于有Java基础的朋友&#xff0c;可以通过本分类60讲左右的课程&#xff0c;打…

linux升级内核_小水谈内核---Linux内核升级

#CentOS61.下载内核版本,选择需要更新的内核版本下载&#xff0c;以3.10为例https://www.kernel.org/pub/linux/kernel/v3.x/2.把下载的文件包拷贝到/user/src下&#xff0c;然后解压cp linux-3.10.tar.xz /usr/src/cd /usr/srctar jxvf linux-3.10.tar.xzmv linux-3.10 kernel…

python 数据库密码加密_数据库账号密码加密详解及实例

数据库账号密码加密详解及实例数据库中经常有对数据库账号密码的加密&#xff0c;但是碰到一个问题&#xff0c;在使用UserService对密码进行加密的时候&#xff0c;spring security 也是需要进行同步配置的&#xff0c;因为spring security 中验证的加密方式是单独配置的。如下…

如何创建ini文件_如何轻松归档文件?2种方法轻松创建归档文件!

ZIP 归档可以把一个或多个文件压缩成占用空间更小的单一文件。当你想释放硬盘空间&#xff0c;或者需要通过邮件和《信息》发送多个文件时&#xff0c;ZIP 的重要性不言而喻。macOS 的《访达》内置了 ZIP 压缩功能&#xff0c;使用方法非常简单。下面就来看看它的基本用法&…

python按指定条件筛选_Python之根据条件筛选特定行|python教程|python入门|python教程...

https://www.xin3721.com/eschool/pythonxin3721/转载于博主flash胜龙的文章&#xff0c;感谢博主的总结与分享。原博客链接https://blog.csdn.net/u010770993/article/details/70312506一、选取几列组成新的dataframe&#xff1a;df df[[A列列名, S列列名, H列列名]]二、选取…

lte tm模式_(LTE)机制与流程-第4章LTE空中接口(《LTE教程:机制与流程》学习笔记)...

什么是空中接口&#xff1f;空中接口连接哪些设备&#xff1f;空中接口上传递哪些信息&#xff1f;用什么来承载这些信息&#xff1f;LTE空中接口采用怎样的协议栈&#xff1f;与WCDMA空中接口相比&#xff0c;LTE空中接口发生了哪些变化&#xff1f;空中接口为什么要定义信道&…

python更改list数据类型_python笔记2-数据类型:列表[List]常用操作

序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置&#xff0c;或索引&#xff0c;索引从0开始&#xff0c;依此类推。序列都可以进行的操作&#xff1a;包括 索引&#xff0c;切片&#xff0c;加&#xff0c;乘&#xff0c;检查成员。列表是最常用的…

win10可用空间变成未分配_Win10专业版下第二个硬盘未分配,如何解决?

有时您可能会在PC上遇到硬盘未分配的消息。如果发生这种情况&#xff0c;您将无法访问您的硬盘驱动器或任何文件。这可能是一个大问题&#xff0c;但您可以使用我们的解决方案解决它。如果您的第二个硬盘驱动器未分配&#xff0c;则可能无法正常访问它。这不是未分配空间的唯一…