使用场景:
思路:
1:获取图片的尺寸。
2:再图片上覆盖一个canvas,canvas宽高等于图片的宽高。
3:给canvas绑定鼠标按下事件(mousedown),获取鼠标按下的坐标位置;
4:给canvas绑定鼠标移动事件(mousemove),记录鼠标移动的坐标;
5:给canvas绑定鼠标松开事件(mouseup),得到鼠标绘制的终点坐标;
直接上代码
// <canvas
// ref="contentCanvasRef"
// @mousemove="handleMouseMove($event)"
// @mousedown="handleMouseDown($event)"
// @mouseup="handleMouseUp($event)"
// ></canvas>
<script setup>
const contentTitle = reactive({
isDrawing: false,
x: 0,
y: 0,
ctx: null,
});
const contentImgsizeRef = ref(null);
// 获取canvas dom
const contentCanvasRef = ref(null);
//比粗细
const penSize = ref(40);
//获取img宽高,设置canvas,
const diffWH = () => {
nextTick(() => {
// setTimeout(() => {
if (contentImgsizeRef.value) {
const w = contentImgsizeRef.value.width;
const h = contentImgsizeRef.value.height;
contentCanvasRef.value.width = w;
contentCanvasRef.value.height = h;
const canvas = contentCanvasRef.value;
contentTitle.ctx = canvas.getContext("2d");
}
//}, 300);
});
};
// 鼠标按下 获取按下的位置
const handleMouseDown = (e) => {
contentTitle.isDrawing = true;
contentTitle.x = e.offsetX;
contentTitle.y = e.offsetY;
};
// 开始画
const handleMouseMove = (e) => {
if (contentTitle.isDrawing) {
switch (contentTitle.active.id) {
case 1:
drawMask(contentTitle.ctx, e.offsetX, e.offsetY);
break;
}
}
};
// 画完(松开鼠标)
const handleMouseUp = (e) => {
contentTitle.isDrawing = false;
const size = props.imgData.size.split("x");
// 复制canvas上的像素数据。
let imgData = contentTitle.ctx.getImageData(
0,
0,
contentCanvasRef.value.width,
contentCanvasRef.value.height
);
let data = imgData.data;
for (let i = 0; i < data.length; i += 4) {
// 将线条部分设置为白色
if (data[i + 3] > 128) {
data[i] = 255;
data[i + 1] = 255;
data[i + 2] = 255;
data[i + 3] = 255;
}
}
//新建一个canvas
const newCanvas = document.createElement("canvas");
newCanvas.width = size[0];
newCanvas.height = size[1];
// 把图片信息放到canvas画布上。
newCanvas.getContext("2d").putImageData(imgData, 0, 0);
// 获取新的图片地址(base64格式)
const newImgFile = newCanvas.toDataURL("image/jpeg");
//把地址转成file
const file = base64ToFile(newImgFile, "绘制过后的图片");
const params = {
size: props.imgData.size,
file,
};
$emit("onMouseUpData", params);
};
// 把base64转换成二进制文件 file
const base64ToFile = (base64, fileName) => {
let data = base64.split(",");
let type = data[0].match(/:(.*?);/)[1];
let suffix = type.split("/")[1];
const bstr = window.atob(data[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
const file = new File([u8arr], `${fileName}.${suffix}`, {
type: type,
});
console.log(file, URL.createObjectURL(file));
return file;
};
// 画图函数
const drawMask = (ctx, x, y) => {
ctx.beginPath();
ctx.moveTo(contentTitle.x, contentTitle.y);
ctx.lineTo(x, y);
ctx.strokeStyle = penColor.active.c;
ctx.lineWidth = penSize.value / 2;
ctx.lineCap = "round";
ctx.stroke();
contentTitle.x = x;
contentTitle.y = y;
};
</script>