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. 将获取到的宽高赋值给 canvasWidth 和 canvasHeight,确保画布铺满容器。
    3. 调用 uni.createCanvasContext("signatureCanvas", this) 创建并获取画布上下文。
    4. 初始化画布的画笔属性,如线宽 (setLineWidth)、线条末端样式 (setLineCap)、线条连接样式 (setLineJoin) 和画笔颜色 (setStrokeStyle)。

方法 (methods) ​

  • onTouchStart(event):

    • 作用: 手指触摸屏幕时触发,开始一次新的笔画。
    • 流程:
      1. 设置 isSigned 为 true,隐藏占位符。
      2. 获取触摸点的 x、y 坐标。
      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) 绘制一条从 lastPoint 到 midPoint 的二次贝塞尔曲线。currentPoint作为控制点,可以使线条走向更贴合手势,实现平滑效果。
      5. 调用 canvasContext.stroke() 和 canvasContext.draw(true) 实时将该小段曲线绘制到画布上。draw(true) 的 true 参数表示本次绘 制是基于上一次绘制结果的增量更新,不清空画布,性能更高。
      6. 将 lastPoint 更新为 midPoint,为绘制下一小段曲线做准备。
  • onTouchEnd():

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

    • 作用: "重签"按钮的点击事件处理函数。
    • 流程:
      1. 设置 isSigned 为 false,重新显示占位符。
      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) 构建了经典的 "上-中-下" 页面结构,使得页面能自适应不同屏幕高度。
  • 对画布、按钮等元素进行了详细的样式设置,以提供清晰、美观的用户界面。

本内容仅限内部使用,技术细节以实际代码为准