用 Canvas 实现手写签名板,给你的网页加点“个人风格”!

476 阅读3分钟

在现代网页应用中,手写签名功能常常作为一个个性化的互动体验,尤其是在合同签署、个性化订单确认等场景中,越来越受到开发者的青睐。而要实现这个功能,Canvas 是一种既高效又灵活的工具。今天,我们来一起了解如何使用 HTML5 的 元素和 JavaScript 来开发一个简单的手写签名板,支持签名、清除、导出等功能,还可以调整画笔粗细和颜色。跟随我一起动手实践吧!

GitHub | Gitee

一、项目结构

首先,我们来定义一个简单的 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 设置画笔粗细,lineJoinlineCap 用于设置线条的连接和端点样式,使得签名的线条更加圆润自然。

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 手写签名板。它不仅支持触摸设备,还提供了丰富的交互体验,包括调节画笔粗细、选择颜色、清除签名和导出签名等功能。无论是用于表单签署还是在线互动,它都能为你的网页增添不少亮点。