Appearance
sign.vue 页面使用说明文档
1. 概述
sign.vue 是一个用于 uni-app 项目的独立签名页面。它提供了一个全屏的画布区域供用户进行手写签名,并支持重签和确认操作。确认后,签名将被保存 为一张图片,并将其临时路径返回给调用该页面的前一个页面。
该组件的核心亮点是采用了二次贝塞尔曲线 (quadraticCurveTo) 来平滑处理笔迹,即使用户快速书写,也能生成流畅、自然的线条,避免了因触摸点采样率 不足而导致的线条断续问题。
2. 如何使用
要使用此签名页面,您需要从其他页面通过 uni.navigateTo 跳转过来,并通过 eventChannel 监听签名完成事件以接收返回的签名图片路径。
调用示例 (在需要发起签名的页面中):
javascript
// pages/somepage/index.vue
methods: {
goToSign() {
uni.navigateTo({
url: '/pages/office/sign', // 请确保路径与您项目中的路径一致
events: {
// 监听签名完成事件
// 当sign.vue页面调用 eventChannel.emit('onSignComplete', ...) 时触发
onSignComplete: (data) => {
console.log('签名完成,图片路径:', data.signaturePath);
// 在这里处理获取到的签名图片路径,例如上传到服务器或在当前页面显示
this.signatureImage = data.signaturePath;
}
},
fail(err) {
console.error('跳转到签名页失败', err);
}
});
}
}3. 组件详解
3.1 页面结构 (<template>)
页面由以下几个主要部分组成:
- 导航栏 (
<c-navBar>): 页面顶部的标题栏,包含标题“签名签署”和返回按钮。 - 提示信息 (
<section class="tips">): 提示用户在指定区域内签名,避免超出范围。 - 画布区域 (
<section class="canvas-wrapper">):<canvas>: 核心的签名区域,监听touchstart,touchmove,touchend事件来捕捉用户输入。placeholder: 在用户尚未开始签名时,画布中央会显示的占位提示文字“请在此区域内签名”。
- 底部操作按钮 (
<section class="footer">):- 重签按钮: 点击后调用
resetSignature方法清空画布。 - 确定按钮: 点击后调用
confirmSignature方法确认签名并返回。
- 重签按钮: 点击后调用
3.2 脚本逻辑 (<script>)
数据属性 (data)
canvasContext:Object|null- 画布的绘图上下文对象,通过uni.createCanvasContext创建,用于执行所有绘图操作。isSigned:Boolean- 标志位,用于判断用户是否已经开始签名。初始为false,触摸开始后变为true。canvasWidth:Number- 画布的实际宽度(单位 px),在onReady生命周期中动态获取。canvasHeight:Number- 画布的实际高度(单位 px),在onReady生命周期中动态获取。lastPoint:Object|null- 记录上一个触摸点的坐标{x, y},用于计算贝塞尔曲线,实现笔迹平滑。
生命周期 (onReady)
onReady(): 在页面初次渲染完成时触发。此函数的主要作用是:- 使用
uni.createSelectorQuery()获取.canvas-wrapper元素的尺寸。 - 将获取到的宽高赋值给
canvasWidth和canvasHeight,确保画布铺满容器。 - 调用
uni.createCanvasContext("signatureCanvas", this)创建并获取画布上下文。 - 初始化画布的画笔属性,如线宽 (
setLineWidth)、线条末端样式 (setLineCap)、线条连接样式 (setLineJoin) 和画笔颜色 (setStrokeStyle)。
- 使用
方法 (methods)
onTouchStart(event):- 作用: 手指触摸屏幕时触发,开始一次新的笔画。
- 流程:
- 设置
isSigned为true,隐藏占位符。 - 获取触摸点的
x、y坐标。 - 将当前点存为
lastPoint,作为笔画的起点。 - 调用
canvasContext.beginPath()开始一条新的绘图路径。
- 设置
onTouchMove(event):- 作用: 手指在屏幕上滑动时连续触发,是绘制平滑笔迹的核心。
- 流程:
- 获取当前触摸点
currentPoint。 - 计算上一个点
lastPoint和当前点currentPoint的中点midPoint。 - 调用
canvasContext.moveTo()将画笔移动到lastPoint。 - 使用
canvasContext.quadraticCurveTo(currentPoint.x, currentPoint.y, midPoint.x, midPoint.y)绘制一条从lastPoint到midPoint的二次贝塞尔曲线。currentPoint作为控制点,可以使线条走向更贴合手势,实现平滑效果。 - 调用
canvasContext.stroke()和canvasContext.draw(true)实时将该小段曲线绘制到画布上。draw(true)的true参数表示本次绘 制是基于上一次绘制结果的增量更新,不清空画布,性能更高。 - 将
lastPoint更新为midPoint,为绘制下一小段曲线做准备。
- 获取当前触摸点
onTouchEnd():- 作用: 手指离开屏幕时触发,结束当前笔画。
- 流程: 调用
canvasContext.draw(true)确保所有缓存的绘制命令都被执行,防止丢失最后一小段笔迹。
resetSignature():- 作用: "重签"按钮的点击事件处理函数。
- 流程:
- 设置
isSigned为false,重新显示占位符。 - 调用
canvasContext.clearRect()清空整个画布矩形区域。 - 调用
canvasContext.draw()将清空操作应用到画布上。
- 设置
confirmSignature():- 作用: "确定"按钮的点击事件处理函数。
- 流程:
- 检查
isSigned,如果用户未签名则通过uni.showToast弹出提示。 - 调用
uni.canvasToTempFilePath()将当前画布内容导出为临时的 PNG 图片文件。 - 在
success回调中: a. 通过this.getOpenerEventChannel()获取到上一个页面的事件通道。 b. 调用eventChannel.emit('onSignComplete', { signaturePath: res.tempFilePath })将包含图片临时路径的对象发送回上一个页面。 c. 调用uni.navigateBack()返回上一页。 - 在
fail回调中处理导出失败的情况,并给出提示。
- 检查
3.3 页面样式 (<style lang="scss" scoped>)
- 使用
SCSS预处理器编写样式,并添加了scoped属性确保样式只作用于当前组件。 - 采用
Flex布局 (display: flex,flex-direction: column) 构建了经典的 "上-中-下" 页面结构,使得页面能自适应不同屏幕高度。 - 对画布、按钮等元素进行了详细的样式设置,以提供清晰、美观的用户界面。
