效果如下:
使用
<he-sigin width="800" height="500"></he-sigin>
具体实现:
<template>
<div id="signatureBox" @touchmove.prevent>
<canvas
ref="myCanvas"
id="canvas"
:width="width"
:height="height"
@mousedown="canvasDown($event)"
@mousemove="canvasMove($event)"
@mouseup="canvasUp()"
@mouseleave="canvasLeave()"
>抱歉,您的浏览器不支持canvas元素</canvas
>
<span class="mt-a" @click="clear">清除</span>
<span class="mt-b" @click="ok">确认</span>
</div>
<div @click="save" v-if="imgSrc" class="save">保存图片</div>
</template>
import { ref, reactive, toRefs, onMounted } from "vue";
export default {
props: {
width: { type: String, default: "500" },
height: { type: String, default: "300" },
},
setup() {
const myCanvas = ref(null);
const data = reactive({
ctx: null,
canvasMoveUse: false,
imgSrc: "",
});
const clear = () => {
data.ctx.clearRect(0, 0, data.ctx.canvas.width, data.ctx.canvas.height);
data.imgSrc = "";
};
const ok = () => {
var base64Img = myCanvas.value.toDataURL("image/jpg");
data.imgSrc = base64Img;
};
const save = () => {
var oA = document.createElement("a");
oA.download = ""; // 设置下载的文件名,默认是'下载'
oA.href = data.imgSrc;
document.body.appendChild(oA);
oA.click();
oA.remove(); // 下载之后把创建的元素删除
data.imgSrc = "";
};
const canvasDown = (e) => {
data.canvasMoveUse = true;
const canvasX = e.offsetX;
const canvasY = e.offsetY;
data.ctx.beginPath(); // 移动的起点
data.ctx.moveTo(canvasX, canvasY);
};
const canvasMove = (e) => {
if (data.canvasMoveUse) {
let canvasX;
let canvasY;
canvasX = e.offsetX;
canvasY = e.offsetY;
data.ctx.lineTo(canvasX, canvasY);
data.ctx.stroke();
}
};
const canvasUp = () => {
data.canvasMoveUse = false;
};
const canvasLeave = () => {
data.canvasMoveUse = false;
};
onMounted(() => {
data.ctx = myCanvas.value.getContext("2d");
data.ctx.lineWidth = 5;
});
return {
...toRefs(data),
myCanvas,
clear,
ok,
save,
canvasDown,
canvasMove,
canvasUp,
canvasLeave,
};
},
};
* {
touch-action: pan-y;
}
#signatureBox {
z-index: 9999;
background: #f2f3f7;
position: relative;
}
#canvas {
display: block;
margin: 0 auto;
background: #fff;
cursor: default;
}
.mt-a {
position: absolute;
left: 5%;
top: 40%;
font-size: 50px;
cursor: pointer;
}
.mt-b {
position: absolute;
right: 5%;
top: 40%;
cursor: pointer;
font-size: 50px;
}
.save {
font-size: 28px;
text-align: center;
line-height: 40px;
cursor: pointer;
color: red;
}
#canvas{
border:1px solid #ccc;
border-radius: 20px;
}