背景:最近在做一款俄语学习的微信小程序(跨端),由于俄语的特殊性同时方便用户在移动端练习书写俄语,开发了一个手写板的小功能(即签字班功能)。主要是实现方式是利用canvas绘制能力。
展示效果:
上代码
<template>
<view class="signature-container">
<canvas
ref="signatureCanvas"
canvas-id="signatureCanvas"
style="width: 100%; height: 300px"
@touchstart="startDrawing"
@touchmove="draw"
@touchend="endDrawing"
@touchcancel="endDrawing"
></canvas>
<button @click="clearSignature">清空</button>
<button @click="saveSignature">保存</button>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { onReady } from '@dcloudio/uni-app'
const signatureCanvas = ref(null)
let ctx = null
let isDrawing = false
let lastX = 0
let lastY = 0
// 禁用下拉刷新和上拉加载
onReady(() => {
uni.stopPullDownRefresh() // 禁用下拉刷新
})
onMounted(() => {
// 获取 canvas 上下文
ctx = uni.createCanvasContext('signatureCanvas')
})
// 开始绘制
const startDrawing = (e) => {
isDrawing = true
const touch = e.touches[0]
lastX = touch.x
lastY = touch.y
}
// 绘制签名
const draw = (e) => {
if (!isDrawing) return
const touch = e.touches[0]
const currentX = touch.x
const currentY = touch.y
// 绘制线条
ctx.beginPath()
ctx.moveTo(lastX, lastY)
ctx.lineTo(currentX, currentY)
ctx.strokeStyle = '#000' // 设置绘制颜色
ctx.lineWidth = 2 // 设置线宽
ctx.lineCap = 'round' // 设置圆角连接
ctx.lineJoin = 'round' // 设置圆角连接
ctx.stroke()
ctx.closePath()
lastX = currentX // 更新上一个点坐标
lastY = currentY
ctx.draw(true) // 确保更新 canvas 内容
}
// 结束绘制
const endDrawing = () => {
isDrawing = false
}
// 清空签名
const clearSignature = () => {
ctx.clearRect(0, 0, 300, 300) // 清除签名区域
ctx.draw(true)
}
// 保存签名
const saveSignature = () => {
// 将 canvas 转为图片 (base64)
uni.canvasToTempFilePath({
canvasId: 'signatureCanvas',
success(res) {
console.log('签名图片:', res.tempFilePath)
// 可以上传图片或者保存
},
fail(err) {
console.log('保存失败', err)
},
})
}
</script>
<style scoped>
.signature-container {
padding: 20rpx;
text-align: center;
}
</style>