在现代网页应用中,手写签名功能常常作为一个个性化的互动体验,尤其是在合同签署、个性化订单确认等场景中,越来越受到开发者的青睐。而要实现这个功能,Canvas 是一种既高效又灵活的工具。今天,我们来一起了解如何使用 HTML5 的 元素和 JavaScript 来开发一个简单的手写签名板,支持签名、清除、导出等功能,还可以调整画笔粗细和颜色。跟随我一起动手实践吧!
一、项目结构
首先,我们来定义一个简单的 HTML 页面结构:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 手写签名板</title>
<link rel="stylesheet" href="./css/index.css" />
</head>
<body>
<div class="container">
<h2>手写签名</h2>
<canvas id="signatureCanvas" width="800" height="300"></canvas>
<div class="controls">
<button id="clearButton">清除签名</button>
<button id="exportButton">导出签名</button>
</div>
<div class="controls">
<div class="range-wrapper">
<label for="brushSize" class="control-label">画笔粗细:</label>
<input type="range" id="brushSize" min="1" max="10" value="3" />
</div>
<div class="color-wrapper">
<label for="colorPicker" class="control-label">画笔颜色:</label>
<input type="color" id="colorPicker" value="#000000" />
</div>
</div>
</div>
<script src="./js/script.js"></script>
</body>
</html>
这段 HTML 代码构建了一个包含签名板的页面,页面上有一个 元素用于绘制签名,两个按钮分别实现清除和导出签名,还有一些控件让用户调节画笔的粗细和颜色。
二、Canvas 绘制手写签名
1、获取 Canvas 元素
const canvas = document.getElementById('signatureCanvas')
const ctx = canvas.getContext('2d')
首先,我们通过 getElementById
获取到 <canvas>
元素,并利用 getContext('2d')
获取 2D
绘图上下文,这样我们就可以开始在 canvas
上进行绘制了。
2、画笔设置
ctx.strokeStyle = '#000' // 默认画笔颜色
ctx.lineWidth = 3 // 默认画笔粗细
ctx.lineJoin = 'round' // 设置连接点样式
ctx.lineCap = 'round' // 设置端点样式
我们为签名板设置了一些初始参数,strokeStyle
设置画笔颜色,lineWidth
设置画笔粗细,lineJoin
和 lineCap
用于设置线条的连接和端点样式,使得签名的线条更加圆润自然。
3、获取鼠标/触摸位置
function getPosition(e) {
const rect = canvas.getBoundingClientRect() // 获取canvas相对于视口的位置
let x, y
if (e.touches && e.touches.length) {
x = e.touches[0].clientX - rect.left
y = e.touches[0].clientY - rect.top
} else {
x = e.clientX - rect.left
y = e.clientY - rect.top
}
// 适配屏幕缩放
const scaleX = canvas.width / rect.width
const scaleY = canvas.height / rect.height
x = (x - window.scrollX) * scaleX
y = (y - window.scrollY) * scaleY
return { x, y }
}
为了确保无论在 PC 还是移动端都能准确捕捉到用户的签名,我们需要通过 getBoundingClientRect()
方法计算 Canvas
的位置,并且在触摸设备上,使用 touches
属性来获取触摸位置。这也使得我们的签名板具备了良好的跨设备适应性。
4、绘制功能
let isDrawing = false
let points = []
function startDrawing(e) {
if (!isInCanvas(e)) return
isDrawing = true
const position = getPosition(e)
points.push(position)
}
function draw(e) {
if (!isDrawing || !isInCanvas(e)) return
const position = getPosition(e)
points.push(position)
ctx.beginPath()
ctx.moveTo(points[points.length - 2].x, points[points.length - 2].y)
ctx.lineTo(position.x, position.y)
ctx.stroke()
}
function stopDrawing() {
isDrawing = false
points = [] // 清空路径
}
我们通过监听鼠标或触摸事件来控制开始绘制、绘制中和停止绘制。每次鼠标移动时,我们会根据鼠标位置绘制一条线段,并实时显示在 Canvas
上。
三、功能实现
1、清除签名
document.getElementById('exportButton').addEventListener('click', () => {
const dataURL = canvas.toDataURL('image/png') // 获取签名图片的 DataURL
const link = document.createElement('a')
link.href = dataURL
link.download = 'signature.png' // 下载文件名
link.click() // 模拟点击链接以下载图片
})
点击“清除签名”按钮时,我们通过 clearRect
方法清除整个 Canvas
上的内容。
2、导出签名
document.getElementById('exportButton').addEventListener('click', () => {
const dataURL = canvas.toDataURL('image/png') // 获取签名图片的 DataURL
const link = document.createElement('a')
link.href = dataURL
link.download = 'signature.png' // 下载文件名
link.click() // 模拟点击链接以下载图片
})
点击“导出签名”按钮时,我们通过 toDataURL()
方法将 Canvas
内容转换为图片的 Data URL
,并通过一个动态创建的链接实现图片下载。
3、调节画笔粗细和颜色
document.getElementById('brushSize').addEventListener('input', (e) => {
ctx.lineWidth = e.target.value
})
document.getElementById('colorPicker').addEventListener('input', (e) => {
ctx.strokeStyle = e.target.value
})
用户可以通过滑动条调节画笔的粗细,通过颜色选择器选择画笔的颜色,使得签名过程更加个性化。
四、结语
通过上面简单的代码,我们成功实现了一个功能齐全的 Canvas
手写签名板。它不仅支持触摸设备,还提供了丰富的交互体验,包括调节画笔粗细、选择颜色、清除签名和导出签名等功能。无论是用于表单签署还是在线互动,它都能为你的网页增添不少亮点。