最近项目中遇到一个需求,要求前端实现截图,并使用canvas描边,然后以文件流的方式传给后台.记录一下在实现这一过程中主要的几个步骤: base64转为file,canvas鼠标画线.
关于cropper的使用可以参考:https://blog.youkuaiyun.com/weixin_38023551/article/details/78792400,作者写的比较详细,这里就不再赘述.
使用cropper的getCroppedCanvas()方法可以获得一个截图的画布,使用toDataURL()将canvas画布内容转化为base64,再向后台传输,但是由于图片太大(30MB的图片,甚至更大)可能造成浏览器卡死,所以将其转为file传给后台.
base64转为file:
function converBase64UrlToBlob(base64) {
var bytes = window.atob(base64, split(',')[1])
var ab = new ArrayBuffer(bytes.length)
var ia = new Uint8Array(ab)
for (var i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i)
}
return new Blob([ab], {
type: 'image/jpeg'
})
}
使用canvas鼠标画线:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<canvas id="canvasInAPerfectWorld" width="490" height="220">
<span>该浏览器不支持canvas内容</span>
</canvas>
</body>
<script src="https://cdn.bootcss.com/jquery/3.2.0/jquery.min.js"></script>
<script>
var context = document.getElementById('canvasInAPerfectWorld').getContext("2d");
var canvas = document.getElementById('canvasInAPerfectWorld')
var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;
// 记录鼠标坐标点
function addClick(x, y, dragging) {
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
//
function redraw() {
canvas.width = canvas.width; // Clears the canvas
context.strokeStyle = "#df4b26";
context.lineJoin = "round";
context.lineWidth = 5;
for (var i = 0; i < clickX.length; i++) {
context.beginPath();
if (clickDrag[i] && i) { //当是拖动而且i!=0时,从上一个点开始画线。
context.moveTo(clickX[i - 1], clickY[i - 1]);
} else {
context.moveTo(clickX[i] - 1, clickY[i]);
}
context.lineTo(clickX[i], clickY[i]);
context.closePath();
context.stroke();
}
}
// 鼠标按下事件
$('#canvasInAPerfectWorld').mousedown(function (e) {
console.log('mousedown')
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
paint = true;
// addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
addClick(mouseX, mouseY)
redraw();
});
// 鼠标移动事件
$('#canvasInAPerfectWorld').mousemove(function (e) {
if (paint) { //是不是按下了鼠标
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
redraw();
}
});
// 鼠标松开事件
$('#canvasInAPerfectWorld').mouseup(function (e) {
paint = false;
});
// 鼠标移开事件
$('#canvasInAPerfectWorld').mouseleave(function (e) {
paint = false;
});
</script>
</html>
效果如下: