//获取应用实例
const app = getApp()
const util = require('../../utils/util.js')
const bletool = require('../../utils/bletool.js')
Page({
data: {
// lists: [{ 'order_no': '1111', 'car_no': '321', 'car_type'绝枣: '尚好捷', 'order_date': '2018-01-02 08:00', 'order_money': '16.00', 'order_time': '4' }],
car_no: '',
order_no: '',
lists: [],
serviceId: '',//592B3370-3900-9A71-4535-35D4212D2837
serviceMac: '',//散陵C9:9B:4C:E7:DE:10
service_psd: '',//855525B837253705595800000329
service_uuid: '',
deviceId:'',
characteristics:[] //特征值
},
onLoad: function (options) {
this.initBle()
},
onReady: function () {
// 页面渲染完成
},
onShow: function () {
if (app.globalData.car_no.length>0){
this.getDeviceInfo()
}
},
onHide: function () {
// 页面隐藏
},
onUnload: function () {
// 页面关闭
app.globalData.car_no=''
},
//蓝牙相关
//初始化蓝牙
initBle: function () {
var that = this
wx.onBluetoothAdapterStateChange(function (res) {
console.log('adapterState changed, now is', res)
app.globalData.ble_state = res.available
if (res.available) {
that.initBle()
} else {
util.showToast('手机蓝牙已关闭')
app.globalData.ble_isonnectting = false
}
})
//打开蓝牙适配器
wx.openBluetoothAdapter({
success: function (res) {
console.log('打开蓝牙适配器成功冲宏戚')
that.getBluetoothAdapterState()
app.globalData.ble_state = true
that.onBluetoothDeviceFound()
},
fail: function (res) {
// fail
console.log(res)
util.showToast('请打开手机蓝牙')
},
complete: function (res) {
// complete
}
})
},
onBluetoothDeviceFound:function(){
var that = this
//监听扫描
wx.onBluetoothDeviceFound(function (res) {
// res电脑模拟器返回的为数组;手机返回的为蓝牙设备对象
console.log('监听搜索新设备:', res)
that.updateBleList([res])
})
},
getBluetoothAdapterState: function () {
var that = this
wx.getBluetoothAdapterState({
success: function (res) {
var available = res.available
var discovering = res.discovering
if (!available) {
util.showToast('蓝牙不可用')
} else {
if (!discovering) {
// that.startBluetoothDevicesDiscovery()
}
}
}
})
},
startBluetoothDevicesDiscovery: function () {
var that = this
var services = []
services.push(this.data.serviceId)
wx.showLoading({
title: '设备搜索中'
})
setTimeout(function () {
wx.hideLoading()
if (app.globalData.deviceId.length==0){
util.showModal('设备搜索失败,请重试')
}
}, 10000)
if(bletool.isIOS()){
wx.startBluetoothDevicesDiscovery({
services: services,
allowDuplicatesKey: true,
success: function (res) {
console.log('ios搜索成功')
console.log(res)
},
fail: function (err) {
console.log(err)
}
})
}else{
wx.startBluetoothDevicesDiscovery({
// services: services,
allowDuplicatesKey: true,
success: function (res) {
console.log('Android搜索成功')
console.log(res)
},
fail: function (err) {
console.log(err)
wx.hideLoading()
that.startBluetoothDevicesDiscovery()
// that.getBluetoothAdapterState()
util.showToast('搜索失败')
}
})
}
},
startConnectDevices: function (ltype, array) {
var that = this
clearTimeout(that.getConnectedTimer)
that.getConnectedTimer = null
wx.stopBluetoothDevicesDiscovery({
success: function (res) {
// success
}
})
app.globalData.ble_isonnectting = true
console.log('连接前:'+that.deviceId)
wx.createBLEConnection({
deviceId: that.deviceId,
success: function (res) {
if (res.errCode == 0) {
console.log('连接成功:')
that.getService(that.deviceId)
}
},
fail: function (err) {
console.log('连接失败:', err)
wx.hideLoading()
util.showModal('设备连接失败,请重试')
// if (ltype == 'loop') {
// that.connectDeviceIndex += 1
// that.loopConnect(array)
// } else {
// that.startBluetoothDevicesDiscovery()
// that.getConnectedBluetoothDevices()
// }
app.globalData.ble_isonnectting = false
},
complete: function () {
}
})
},
getService: function (deviceId) {
var that = this
// 监听蓝牙连接
wx.onBLEConnectionStateChange(function (res) {
console.log(res)
app.globalData.ble_isonnectting = res.connected
if (!res.connected) {
util.showToast('连接断开')
}
})
// 获取蓝牙设备service值
wx.getBLEDeviceServices({
deviceId: deviceId,
success: function (res) {
console.log('获取蓝牙设备service值')
console.log(res)
that.getCharacter(deviceId, res.services)
}
})
},
getCharacter: function (deviceId, services) {
var that = this
services.forEach(function (value, index, array) {
if (value.isPrimary) {
that.setData({
service_uuid: value.uuid,
deviceId: deviceId
})
app.globalData.service_uuid= value.uuid
app.globalData.deviceId=deviceId
}
})
//监听通知
wx.onBLECharacteristicValueChange(function (res) {
// callback
console.log('value change', res)
const hex = bletool.buf2char(res.value)
console.log('返回的数据:', hex)
//配对密码
if (hex.indexOf('855800000106') != -1) {
wx.hideLoading()
var charact_write = that.data.characteristics[1]
bletool.writeDataToDevice(that.data.deviceId, that.data.service_uuid, charact_write, that.data.service_psd)
wx.showToast({
title: '设备已连接',
icon: 'success',
duration: 3000
})
setTimeout(function () {
bletool.writeDataToDevice(that.data.deviceId, that.data.service_uuid, charact_write, '235525B837253705590400000273')
}, 2000)
} else if (hex.indexOf('23040000') != -1) {
//启动成功
that.starRenting()
}
})
wx.getBLEDeviceCharacteristics({
deviceId: deviceId,
serviceId: that.getServiceUUID(),
success: function (res) {
wx.getBLEDeviceCharacteristics({
deviceId: deviceId,
serviceId: that.getServiceUUID(),
success: function (res) {
console.log('特征', res)
that.setData({
characteristics:res.characteristics
})
app.globalData.characteristics = res.characteristics
var charact_read = res.characteristics[0]
},
loopConnect: function (devicesId) {
var that = this
var listLen = devicesId.length
if (devicesId[this.connectDeviceIndex]) {
this.deviceId = devicesId[this.connectDeviceIndex]
this.startConnectDevices('loop', devicesId)
} else {
console.log('已配对的设备小程序蓝牙连接失败')
that.startBluetoothDevicesDiscovery()
that.getConnectedBluetoothDevices()
}
},
//更新数据 devices为数组类型
updateBleList: function (devices) {
console.log('设备数据:',devices)
var newData = this.data.bleList
var that = this
var tempDevice = null
for (var i = 0i <devices.lengthi++) {
//ios设备
if (devices[i].devices != null) {
if (devices[i].devices.length >0) {
tempDevice = devices[i].devices[0]
}
else {
continue
}
}
//安卓
else {
tempDevice = devices[i]
}
if (!this.isExist(tempDevice)) {
newData.push(tempDevice)
}
}
console.log('数据:')
console.log(newData)
this.setData({
bleList: newData
})
if (!app.globalData.ble_isonnectting) {
var that = this
this.data.bleList.forEach(function (value, index, array) {
//找到对应id的设备,ios判断服务id安卓判断mac地址
var deviceId = value['deviceId']
if(bletool.isIOS()){
let advertisServiceUUID = value['advertisServiceUUIDs'][0]
if (advertisServiceUUID == that.data.serviceId.toUpperCase()){
that.deviceId = deviceId
console.log(that.deviceId)
that.startConnectDevices()
}
}else{
if (deviceId == that.data.serviceMac) {
that.deviceId = deviceId
console.log(that.deviceId)
that.startConnectDevices()
}
}
})
}
},
//是否已存在 存在返回true 否则false
isExist: function (device) {
var tempData = this.data.bleList
for (var i = 0i <tempData.lengthi++) {
if (tempData[i].deviceId == device.deviceId) {
return true
}
}
return false
},
//服务uuid
getServiceUUID: function () {
return bletool.stringTransition(this.data.service_uuid)
},
getDeviceInfo: function () {
let car_no = app.globalData.car_no
var that = this
wx.request({
url: app.globalData.serverURL + '?c=car&a=getDeviceInfo&open_id=' + app.globalData.open_id + '&car_no=' + car_no,
method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
header: { 'content-type': 'application/json' }, // 设置请求的 header
success: function (res) {
// success
var data = res.data
console.log(data)
if (data.result == 1) {
app.globalData.serviceId = data.data.service_id
app.globalData.serviceMac = data.data.service_mac,
app.globalData.service_psd = '85' + data.data.service_psd + '5800000329'
that.setData({
serviceId: data.data.service_id,
serviceMac: data.data.service_mac,
service_psd: '85' + data.data.service_psd+'5800000329',
})
app.startBluetoothDevicesDiscovery()
// that.onBLECharacteristicValueChange()
} else {
util.showModal(data.msg)
}
},
fail: function () {
},
complete: function () {
// complete
}
})
},
})
整个功能基于canvas实现,首先添加画布组件,并设定样式<!--index.wxml--><view class="container">
<canvas canvas-id="id-gesture-lock" class="gesture-lock" bindtouchstart="onTouchStart"
bindtouchmove="onTouchMove" bindtouchend="onTouchEnd"></canvas></view>.gesture-lock {
margin: 100rpx auto
width: 300px
height: 300px
background-color: #ffffff
}123456789101112
手势解锁实现代码在gesture_lock.js中(完整源码地址见末尾)。
初始化
constructor(canvasid, context, cb, opt){this.touchPoints = [] this.checkPoints = [] this.canvasid = canvasid this.ctx = context this.width = opt &&opt.width || 300//画布长度
this.height = opt &&opt.height || 300//画布宽度族毕
this.cycleNum = opt &&opt.cycleNum || 3 this.radius = 0 //触摸点半径
this.isParamOk = false this.marge = this.margeCircle = 25//触摸点及触摸点和画布边界间隔
this.initColor = opt &&opt.initColor || '#C5C5C3'
this.checkColor = opt &&opt.checkColor || '陆厅#5AA9EC' this.errorColor = opt &&opt.errorColor || '#e19984' this.touchState = "unTouch" this.checkParam() this.lastCheckPoint = null if (this.isParamOk) {// 计算触摸点的半径长度
this.radius = (this.width - this.marge * 2 - (this.margeCircle * (this.cycleNum - 1))) / (this.cycleNum * 2)this.radius = Math.floor(this.radius) // 计算每个触摸点的圆心位置
this.calCircleParams()
}this.onEnd = cb//滑动手势结束时的回调函数
}1234567891011121314151617181920212223242526
主要设置一些参数,如canvas的长宽,canvas的context,手势锁的个数(3乘3, 4乘4),手势锁的颜色,手势滑动结束时的回调函数等。并计算出手势锁的半径。
计算每个手早穗隐势锁的圆心位置
calCircleParams() {let n = this.cycleNum let count = 0 for (let i = 0i <ni++) {for (let j = 0j <nj++){
count++ let touchPoint = {
x: this.marge + i * (this.radius * 2 + this.margeCircle) + this.radius,
y: this.marge + j * (this.radius * 2 + this.margeCircle) + this.radius,
index: count,
check: "uncheck",
}this.touchPoints.push(touchPoint)
}
}
}1234567891011121314151617
绘制手势锁
for (let i = 0i <this.touchPoints.lengthi++){this.drawCircle(this.touchPoints[i].x, this.touchPoints[i].y, this.radius, this.initColor)
} this.ctx.draw(true)1234
接下来就是识别用户的滑动行为,判断用户划过了哪些圆圈,进而识别出用户的手势。
在touchstart和touchmove事件中检测触发并更新画布
onTouchStart(e) {// 不识别多点触控
if (e.touches.length >1){this.touchState = "unTouch" return
}this.touchState = "startTouch" this.checkTouch(e) let point = {x:e.touches[0].x, y:e.touches[0].y} this.drawCanvas(this.checkColor, point)
}
onTouchMove(e) {if (e.touchState === "unTouch") {return
}if (e.touches.length >1){this.touchState = "unTouch" return
}this.checkTouch(e) let point = {x:e.touches[0].x, y:e.touches[0].y} this.drawCanvas(this.checkColor, point)
}123456789101112131415161718192021222324
检测用户是否划过某个圆圈
checkTouch(e) {for (let i = 0i <this.touchPoints.lengthi++){let point = this.touchPoints[i] if (isPointInCycle(e.touches[0].x, e.touches[0].y, point.x, point.y, this.radius)) {if (point.check === 'uncheck') {this.checkPoints.push(point) this.lastCheckPoint = point
}
point.check = "check"
return
}
}
}12345678910111213
更新画布
drawCanvas(color, point) {//每次更新之前先清空画布
this.ctx.clearRect(0, 0, this.width, this.height) //使用不同颜色和形式绘制已触发和未触发的锁
for (let i = 0i <this.touchPoints.lengthi++){let point = this.touchPoints[i] if (point.check === "check") {this.drawCircle(point.x, point.y, this.radius, color) this.drawCircleCentre(point.x, point.y, color)
}else {this.drawCircle(this.touchPoints[i].x, this.touchPoints[i].y, this.radius, this.initColor)
}
}//绘制已识别锁之间的线段
if (this.checkPoints.length >1) { let lastPoint = this.checkPoints[0]for (let i = 1i <this.checkPoints.lengthi++) { this.drawLine(lastPoint, this.checkPoints[i], color)
lastPoint = this.checkPoints[i]
}
}//绘制最后一个识别锁和当前触摸点之间的线段
if (this.lastCheckPoint &&point) {this.drawLine(this.lastCheckPoint, point, color)
}this.ctx.draw(true)
}12345678910111213141516171819202122232425262728
当用户滑动结束时调用回调函数并传递识别出的手势
onTouchEnd(e) {typeof this.onEnd === 'function' &&this.onEnd(this.checkPoints, false)
}
onTouchCancel(e) {typeof this.onEnd === 'function' &&this.onEnd(this.checkPoints, true)
}1234567
重置和显示手势错误
gestureError() {this.drawCanvas(this.errorColor)
}
reset() {for (let i = 0i <this.touchPoints.lengthi++) {this.touchPoints[i].check = 'uncheck'
}this.checkPoints = [] this.lastCheckPoint = null this.drawCanvas(this.initColor)
}123456789101112
如何调用
在onload方法中创建lock对象并在用户触摸事件中调用相应方法
onLoad: function () {
var s = this this.lock = new Lock("id-gesture-lock", wx.createCanvasContext("id-gesture-lock"), function(checkPoints, isCancel) {
console.log('over')
s.lock.gestureError()
setTimeout(function() {
s.lock.reset()
}, 1000)
}, {width:300, height:300})this.lock.drawGestureLock()
console.log('onLoad')var that = this
//调用应用实例的方法获取全局数据
app.getUserInfo(function(userInfo){
//更新数据
that.setData({
userInfo:userInfo
})
that.update()
})
},
onTouchStart: function (e) {
this.lock.onTouchStart(e)
},
onTouchMove: function (e) {
this.lock.onTouchMove(e)
},
onTouchEnd: function (e) {
this.lock.onTouchEnd(e)
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)