uniapp中如何实现手势密码功能

1. 前言

手势密码是一种很常见的安全验证方式,现在很多应用都会采用这种方式,如手机解锁等。本文主要介绍如何在uniapp中实现手势密码功能。我们会使用uniapp自带的touchstart、touchmove和touchend事件来实现这个功能。

2. 实现过程

2.1 创建手势密码页面

我们先创建一个手势密码的页面,包含一个画布和一些必要的变量。画布用来绘制手势密码,变量用来保存手势密码的状态和路径等信息。

// 创建手势密码页面的vue实例

<template>

<view class="gesture-container">

<canvas canvas-id="gesture-canvas" @touchstart="canvasTouchStart" @touchmove="canvasTouchMove"

@touchend="canvasTouchEnd"></canvas>

</view>

</template>

<script>

export default {

data() {

return {

// 画布的宽度和高度

canvasWidth: 0,

canvasHeight: 0,

// 手势密码的状态

status: 'normal', // 初始状态

message: '请输入手势密码', // 状态提示信息

// 手势密码的路径

path: [],

lastX: null,

lastY: null,

}

}

}

</script>

在上面的代码中,我们创建了一个名为gesture-container的页面容器,其中包含了一个canvas标签,用于绘制手势密码。我们还声明了一些变量,包括canvas的宽度和高度,手势密码的状态(包括normal、right和wrong等状态)、提示信息以及手势密码的路径,以及最后一个点的坐标。

2.2 绘制手势密码

接下来,我们需要实现绘制手势密码的功能。首先,我们需要在touchstart事件里记录下手指的起始坐标,并且设置手势密码的状态为normal状态。

canvasTouchStart(e) {

const { x, y } = this.getEventPosition(e)

this.status = 'normal'

this.message = '请输入手势密码'

this.lastX = x

this.lastY = y

this.path = [{ x, y }]

}

在touchmove事件里,我们需要绘制手势密码的路径,为了避免重复绘制,我们需要判断当前点是否已经在路径中出现过,在这种情况下,我们不需要再绘制当前点,否则,我们需要通过path的push方法将当前点加入路径中,并且在当前点和上一个点之间绘制一条线段。

canvasTouchMove(e) {

if (this.status === 'right') {

return

}

const { x, y } = this.getEventPosition(e)

const point = { x, y }

const lastPoint = this.path[this.path.length - 1]

if (lastPoint.x !== point.x || lastPoint.y !== point.y) {

this.path.push(point)

this.drawLine(lastPoint.x, lastPoint.y, x, y)

}

this.lastX = x

this.lastY = y

}

在touchend事件里,我们需要判断手势密码是否正确,如果正确,则设置手势密码的状态为right状态,并且提示手势密码已经设置成功,否则,设置手势密码的状态为wrong状态,并且提示手势密码设置失败,需要重新输入。我们还需要将画布上的路径清除。

canvasTouchEnd() {

if (this.path.length <= 1) {

return

}

const password = this.getLocalPassword() // 获取本地存储的手势密码

if (password) {

const psw = this.getPathString(this.path) // 将path转换为字符串

if (psw === password) {

this.status = 'right'

this.message = '手势密码设置成功'

this.saveLocalPassword(psw) // 保存手势密码到本地

setTimeout(() => {

// 成功后跳转

uni.redirectTo({ url: '/pages/index/index' })

}, 1000)

} else {

this.status = 'wrong'

this.message = '手势密码设置失败,请重新输入'

this.clearCanvas() // 清除画布上的路径

setTimeout(() => {

this.status = 'normal'

this.message = '请输入手势密码'

}, 1000)

}

} else {

const psw = this.getPathString(this.path)

this.status = 'normal'

this.message = '请再次输入手势密码'

this.saveLocalPassword(psw)

setTimeout(() => {

this.clearCanvas() // 清除画布上的路径

this.path = []

this.lastX = null

this.lastY = null

}, 1000)

}

}

2.3 其他功能

我们还可以添加一些其他的功能,如用来清除画布上的路径的clearCanvas方法,用来获取鼠标或手指相对于画布左上角的坐标的getEventPosition方法,以及用来将path转换为字符串的getPathString方法等。

clearCanvas() {

const ctx = uni.createCanvasContext('gesture-canvas', this)

ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight)

ctx.draw(false)

},

getEventPosition(event) {

const { clientX, clientY } = event.touches[0]

const { left, top } = uni.createSelectorQuery()

.in(this)

.select('.gesture-container')

.boundingClientRectSync()

const x = clientX - left

const y = clientY - top

return { x, y }

},

getPathString(path) {

return path.map(p => `${p.x},${p.y}`).join('-')

},

// 获取本地存储的手势密码

getLocalPassword() {

return uni.getStorageSync('gesture_password') || ''

},

// 保存手势密码到本地

saveLocalPassword(password) {

uni.setStorageSync('gesture_password', password)

}

3. 总结

在上面的代码中,我们使用了uniapp自带的touchstart、touchmove和touchend事件实现了手势密码的功能。我们在touchstart事件里记录下起始点的坐标,在touchmove事件里绘制手势密码的路径,并在touchend事件中判断手势密码是否正确,并对画布进行清除等操作。通过以上的步骤,我们可以轻松地实现手势密码功能。