在 Vue 中实现一个简单的签名画板,可以使用 canvas 元素结合 Vue 的响应式数据和事件来完成。以下是一个简单的实现步骤。

步骤 1: 使用 <canvas> 元素绘制签名

首先,我们需要一个 <canvas> 元素来绘制签名。通过监听鼠标或触摸事件,我们可以实现绘制。

步骤 2: 设置 Vue 组件

我们可以通过 Vue 组件来管理签名画板的状态和行为,例如清除画板和保存签名。

以下是一个基本的签名画板实现:

<template>
  <div class="signature-board">
    <canvas ref="canvas" class="signature-canvas" @mousedown="startDrawing" @mousemove="draw" @mouseup="stopDrawing" @mouseleave="stopDrawing"></canvas>
    <div class="controls">
      <button @click="clearCanvas">清除</button>
      <button @click="saveSignature">保存签名</button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isDrawing: false,  // 是否正在绘制
      lastX: 0,         // 上一个鼠标位置
      lastY: 0,         // 上一个鼠标位置
      canvasWidth: 500,  // canvas 宽度
      canvasHeight: 200, // canvas 高度
    };
  },
  mounted() {
    const canvas = this.$refs.canvas;
    canvas.width = this.canvasWidth;
    canvas.height = this.canvasHeight;
  },
  methods: {
    startDrawing(e) {
      this.isDrawing = true;
      const canvas = this.$refs.canvas;
      this.lastX = e.offsetX || e.touches[0].clientX - canvas.offsetLeft;
      this.lastY = e.offsetY || e.touches[0].clientY - canvas.offsetTop;
    },
    draw(e) {
      if (!this.isDrawing) return;

      const canvas = this.$refs.canvas;
      const ctx = canvas.getContext('2d');

      const currentX = e.offsetX || e.touches[0].clientX - canvas.offsetLeft;
      const currentY = e.offsetY || e.touches[0].clientY - canvas.offsetTop;

      ctx.beginPath();
      ctx.moveTo(this.lastX, this.lastY);
      ctx.lineTo(currentX, currentY);
      ctx.strokeStyle = '#000'; // 画笔颜色
      ctx.lineWidth = 2; // 画笔宽度
      ctx.lineCap = 'round'; // 圆形线头
      ctx.lineJoin = 'round'; // 圆形连接
      ctx.stroke();

      this.lastX = currentX;
      this.lastY = currentY;
    },
    stopDrawing() {
      this.isDrawing = false;
    },
    clearCanvas() {
      const canvas = this.$refs.canvas;
      const ctx = canvas.getContext('2d');
      ctx.clearRect(0, 0, canvas.width, canvas.height); // 清除画布
    },
    saveSignature() {
      const canvas = this.$refs.canvas;
      const dataUrl = canvas.toDataURL(); // 获取 canvas 图像的 base64 数据
      console.log('签名图片数据:', dataUrl);
      // 可以将 dataUrl 保存为图片文件,或上传到服务器
      // 比如通过 API 将签名数据上传
    },
  },
};
</script>

<style scoped>
.signature-board {
  position: relative;
  display: inline-block;
}

.signature-canvas {
  border: 1px solid #000;
  cursor: crosshair;
}

.controls {
  margin-top: 10px;
}

button {
  margin-right: 10px;
  padding: 5px 10px;
  background-color: #4CAF50;
  color: white;
  border: none;
  cursor: pointer;
}

button:hover {
  background-color: #45a049;
}
</style>

代码解释

  1. Canvas 元素:
  • 使用 <canvas ref="canvas"> 创建一个画布。
  • 设置画布的宽度和高度为 500x200(可以根据需要调整)。
  1. 鼠标和触摸事件:
  • @mousedown="startDrawing": 鼠标按下开始绘制。
  • @mousemove="draw": 鼠标移动时绘制路径。
  • @mouseup="stopDrawing" 和 @mouseleave="stopDrawing": 停止绘制。
  1. 绘制函数:
  • startDrawing:记录鼠标按下的位置。
  • draw:在鼠标移动时,使用 CanvasRenderingContext2D API 绘制路径。
  • stopDrawing:结束绘制,停止监听鼠标事件。
  1. 控制按钮:
  • clearCanvas:清空画布。
  • saveSignature:保存签名为 base64 数据,可以进一步将其上传到服务器或下载为图片。
  1. 样式:
  • signature-canvas 为画布样式,设置了边框和光标样式。
  • controls 为控制按钮的样式。

进一步优化

  • 支持触摸事件:如果你希望支持移动端,可以在 startDrawingdraw 中使用 touchstarttouchmovetouchend 事件来替代 mousedownmousemove
  • 图片保存和上传saveSignature 方法中获取的 base64 数据(canvas.toDataURL())可以上传到服务器,或者保存为图片文件。
  • 清除功能:可以扩展为绘制不同颜色、线条宽度等。

总结

通过结合 Vue 的事件处理和 canvas API,我们可以实现一个简单的签名画板,允许用户在画布上进行自由绘制、清除和保存操作。