Skip to content

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(): 在页面初次渲染完成时触发。此函数的主要作用是:
    1. 使用 uni.createSelectorQuery() 获取 .canvas-wrapper 元素的尺寸。
    2. 将获取到的宽高赋值给 canvasWidthcanvasHeight,确保画布铺满容器。
    3. 调用 uni.createCanvasContext("signatureCanvas", this) 创建并获取画布上下文。
    4. 初始化画布的画笔属性,如线宽 (setLineWidth)、线条末端样式 (setLineCap)、线条连接样式 (setLineJoin) 和画笔颜色 (setStrokeStyle)。

方法 (methods)

  • onTouchStart(event):

    • 作用: 手指触摸屏幕时触发,开始一次新的笔画。
    • 流程:
      1. 设置 isSignedtrue,隐藏占位符。
      2. 获取触摸点的 xy 坐标。
      3. 将当前点存为 lastPoint,作为笔画的起点。
      4. 调用 canvasContext.beginPath() 开始一条新的绘图路径。
  • onTouchMove(event):

    • 作用: 手指在屏幕上滑动时连续触发,是绘制平滑笔迹的核心。
    • 流程:
      1. 获取当前触摸点 currentPoint
      2. 计算上一个点 lastPoint 和当前点 currentPoint 的中点 midPoint
      3. 调用 canvasContext.moveTo() 将画笔移动到 lastPoint
      4. 使用 canvasContext.quadraticCurveTo(currentPoint.x, currentPoint.y, midPoint.x, midPoint.y) 绘制一条从 lastPointmidPoint 的二次贝塞尔曲线。currentPoint作为控制点,可以使线条走向更贴合手势,实现平滑效果。
      5. 调用 canvasContext.stroke()canvasContext.draw(true) 实时将该小段曲线绘制到画布上。draw(true)true 参数表示本次绘 制是基于上一次绘制结果的增量更新,不清空画布,性能更高。
      6. lastPoint 更新为 midPoint,为绘制下一小段曲线做准备。
  • onTouchEnd():

    • 作用: 手指离开屏幕时触发,结束当前笔画。
    • 流程: 调用 canvasContext.draw(true) 确保所有缓存的绘制命令都被执行,防止丢失最后一小段笔迹。
  • resetSignature():

    • 作用: "重签"按钮的点击事件处理函数。
    • 流程:
      1. 设置 isSignedfalse,重新显示占位符。
      2. 调用 canvasContext.clearRect() 清空整个画布矩形区域。
      3. 调用 canvasContext.draw() 将清空操作应用到画布上。
  • confirmSignature():

    • 作用: "确定"按钮的点击事件处理函数。
    • 流程:
      1. 检查 isSigned,如果用户未签名则通过 uni.showToast 弹出提示。
      2. 调用 uni.canvasToTempFilePath() 将当前画布内容导出为临时的 PNG 图片文件。
      3. success 回调中: a. 通过 this.getOpenerEventChannel() 获取到上一个页面的事件通道。 b. 调用 eventChannel.emit('onSignComplete', { signaturePath: res.tempFilePath }) 将包含图片临时路径的对象发送回上一个页面。 c. 调用 uni.navigateBack() 返回上一页。
      4. fail 回调中处理导出失败的情况,并给出提示。

3.3 页面样式 (<style lang="scss" scoped>)

  • 使用 SCSS 预处理器编写样式,并添加了 scoped 属性确保样式只作用于当前组件。
  • 采用 Flex 布局 (display: flex, flex-direction: column) 构建了经典的 "上-中-下" 页面结构,使得页面能自适应不同屏幕高度。
  • 对画布、按钮等元素进行了详细的样式设置,以提供清晰、美观的用户界面。

本内容仅限内部使用,包含机密和专有信息。严禁任何形式的复制、分发或泄露给任何第三方