Vue 中如何实现手写签名的功能?

1. 简介

在很多应用中,由于用户可能需要通过手写来填写信息,因此手写签名的功能就成为了一种很常见的需求。在 Vue 中实现手写签名,需要用到以下技术:HTML5 的 Canvas、JavaScript 绘图 API 和 Vue 的生命周期函数。

2. HTML5 的 Canvas

Canvas 是HTML5 的一种新增元素,它可以用于通过 JavaScript 来绘制图像、动画或者其他图形。我们可以利用 Canvas 实现绘制、保存、撤销等功能。

2.1. Canvas 的基本用法

要在 HTML 页面中创建一个 Canvas 元素,需要使用以下代码:

<canvas id="myCanvas"></canvas>

然后在 JavaScript 中获取这个 Canvas 元素对象,即可开始绘制。下面的代码演示了如何在 Canvas 上绘制一条红线:

var canvas = document.getElementById("myCanvas");

var ctx = canvas.getContext("2d");

ctx.lineWidth = 5;

ctx.strokeStyle = "red";

ctx.moveTo(0, 0);

ctx.lineTo(200, 100);

ctx.stroke();

上面的代码中,首先获取了 ID 为 "myCanvas" 的 Canvas 元素对象,然后通过 getContext() 方法获得画布上绘图的上下文,接着设置线条的宽度和颜色,并用 moveTo() 和 lineTo() 方法绘制了一条斜线,最后用 stroke() 方法将线条渲染到画布上。

2.2. 实现手写签名

要实现手写签名的功能,需要先创建一个 Canvas 元素,然后在该元素上绘制用户的手写轨迹。我们可以监听鼠标/触摸事件,获取用户的手写坐标,并用之前介绍过的绘图 API 在 Canvas 上绘制路径。

假设我们已经创建了一个 Canvas 元素,且其 ID 为 "myCanvas",我们可以使用下面的代码来实现手写签名:

new Vue({

el: '#app',

data: {

isDrawing: false,

lastX: 0,

lastY: 0

},

mounted: function() {

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

// 设置 Canvas 大小

canvas.width = 500;

canvas.height = 300;

// 绑定事件

canvas.addEventListener('mousedown', this.onStartDrawing);

canvas.addEventListener('mousemove', this.onDrawing);

canvas.addEventListener('mouseup', this.onStopDrawing);

canvas.addEventListener('mouseout', this.onStopDrawing);

},

methods: {

onStartDrawing: function(e) {

this.isDrawing = true;

var pos = this.getPosition(e);

this.lastX = pos.x;

this.lastY = pos.y;

},

onDrawing: function(e) {

if (!this.isDrawing) return;

var pos = this.getPosition(e);

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

ctx.lineWidth = 2;

ctx.strokeStyle = "black";

ctx.beginPath();

ctx.moveTo(this.lastX, this.lastY);

ctx.lineTo(pos.x, pos.y);

ctx.stroke();

this.lastX = pos.x;

this.lastY = pos.y;

},

onStopDrawing: function(e) {

this.isDrawing = false;

},

getPosition: function(e) {

var canvas = document.getElementById('myCanvas');

var rect = canvas.getBoundingClientRect();

return {

x: e.clientX - rect.left,

y: e.clientY - rect.top

};

}

}

});

上述代码中,我们在 Vue 的 mounted() 生命周期函数中绑定了鼠标/触摸事件,并绘制了手写轨迹。isDrawing、lastX、lastY 是我们需要在 data 中定义的属性,用于追踪鼠标/触摸事件和手写轨迹。

需要注意的是,我们在获取鼠标/触摸事件的坐标时,需要减去 Canvas 元素在页面中的位置,这可以通过 Canvas 元素的 getBoundingClientRect() 方法得到。

3. 其他功能

除了手写签名,我们很可能还需要添加一些其他功能,例如保存、清除、撤销等。下面的代码演示了如何实现这些功能:

new Vue({

el: '#app',

data: {

isDrawing: false,

lastX: 0,

lastY: 0,

undoList: []

},

mounted: function() {

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

// 设置 Canvas 大小

canvas.width = 500;

canvas.height = 300;

// 绑定事件

canvas.addEventListener('mousedown', this.onStartDrawing);

canvas.addEventListener('mousemove', this.onDrawing);

canvas.addEventListener('mouseup', this.onStopDrawing);

canvas.addEventListener('mouseout', this.onStopDrawing);

// 添加 Clear 按钮

var buttonClear = document.createElement('button');

buttonClear.textContent = '清除';

buttonClear.addEventListener('click', this.onClear);

document.body.appendChild(buttonClear);

// 添加 Save 按钮

var buttonSave = document.createElement('button');

buttonSave.textContent = '保存';

buttonSave.addEventListener('click', this.onSave);

document.body.appendChild(buttonSave);

// 添加 Undo 按钮

var buttonUndo = document.createElement('button');

buttonUndo.textContent = '撤销';

buttonUndo.addEventListener('click', this.onUndo);

document.body.appendChild(buttonUndo);

},

methods: {

onStartDrawing: function(e) {

this.isDrawing = true;

var pos = this.getPosition(e);

this.lastX = pos.x;

this.lastY = pos.y;

},

onDrawing: function(e) {

if (!this.isDrawing) return;

var pos = this.getPosition(e);

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

ctx.lineWidth = 2;

ctx.strokeStyle = "black";

ctx.beginPath();

ctx.moveTo(this.lastX, this.lastY);

ctx.lineTo(pos.x, pos.y);

ctx.stroke();

this.lastX = pos.x;

this.lastY = pos.y;

},

onStopDrawing: function(e) {

this.isDrawing = false;

},

onClear: function(e) {

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

ctx.clearRect(0, 0, canvas.width, canvas.height);

},

onSave: function(e) {

var canvas = document.getElementById('myCanvas');

var dataURL = canvas.toDataURL();

window.open(dataURL, '_blank');

},

onUndo: function(e) {

var canvas = document.getElementById('myCanvas');

var ctx = canvas.getContext('2d');

ctx.clearRect(0, 0, canvas.width, canvas.height);

var img = new Image();

img.onload = function() {

ctx.drawImage(img, 0, 0);

};

var lastUndo = this.undoList.pop();

if (lastUndo) {

img.src = lastUndo;

}

},

getPosition: function(e) {

var canvas = document.getElementById('myCanvas');

var rect = canvas.getBoundingClientRect();

return {

x: e.clientX - rect.left,

y: e.clientY - rect.top

};

}

}

});

上述代码中,我们在 mounted() 生命周期函数中添加了三个按钮:Clear、Save 和 Undo。Clear 按钮用于清除 Canvas 上的手写轨迹,Save 按钮用于将 Canvas 转化为数据 URL 并在新窗口中打开,以便用户下载/保存,Undo 按钮则用于撤销上一步绘画操作,将 Canvas 恢复到上一步绘图的状态。我们用一个 undoList 数组来储存每一步绘图的状态(也可以使用撤销栈)。

4. 总结

在 Vue 中实现手写签名的功能需要用到 HTML5 的 Canvas、JavaScript 绘图 API 和 Vue 的生命周期函数。通过监听鼠标/触摸事件,获取用户的手写坐标,我们可以通过绘图 API 在 Canvas 上绘制手写轨迹。除了手写签名,我们还可以添加 Clear、Save 和 Undo 等功能,使得用户能够清除手写轨迹、将手写签名转化为数据 URL 并保存,以及撤销上一步绘制操作等。