Appearance
js+canvas 签名板
演示
<template>
<div class="box">
<div ref="container">
<canvas ref="canvas"></canvas>
</div>
<div style="margin-top: 20px;">
<el-button @click="clear">清空</el-button>
<el-button @click="getBase64" type="primary">获取图片</el-button>
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
const props = withDefaults(defineProps<{
width?: string | number;
height?: string | number;
lineWidth?: number;
lineColor?: string;
backgroundColor?: string;
}>(), {
width: "100%",
height: "300px",
lineWidth: 2,
lineColor: "#000000",
backgroundColor: "#F6F6F6"
})
const container = ref<HTMLDivElement>();
const canvas = ref<HTMLCanvasElement>();
onMounted(() => {
if (container.value && canvas.value) {
// 容器和canvas的宽高设置
container.value.style.width = (isNaN(Number(props.width)) ? props.width : `${props.width}px`) as string;
container.value.style.height = (isNaN(Number(props.height)) ? props.height : `${props.height}px`) as string;
const { clientWidth, clientHeight } = container.value;
canvas.value.width = clientWidth;
canvas.value.height = clientHeight;
// 画布设置
const ctx = canvas.value.getContext("2d") as CanvasRenderingContext2D;
ctx.fillStyle = props.backgroundColor;
ctx.fillRect(0, 0, clientWidth, clientHeight);
ctx.lineWidth = props.lineWidth;
ctx.lineJoin = "round";
ctx.strokeStyle = props.lineColor;
// 画布事件绑定
canvas.value.onmousedown = (e) => {
ctx.beginPath();
ctx.moveTo(e.offsetX, e.offsetY);
canvas.value!.onmousemove = (e) => {
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
};
canvas.value!.onmouseup = () => {
canvas.value!.onmousemove = null;
};
canvas.value!.onmouseleave = () => {
canvas.value!.onmousemove = null;
};
};
}
})
const clear = () => {
const ctx = canvas.value?.getContext("2d") as CanvasRenderingContext2D;
if (ctx) {
ctx.clearRect(0, 0, canvas.value!.width, canvas.value!.height);
ctx.fillStyle = props.backgroundColor;
ctx.fillRect(0, 0, canvas.value!.width, canvas.value!.height);
}
}
const getBase64 = () => {
const base = canvas.value?.toDataURL() as string;
console.log(base);
}
</script>
<style lang="scss" scoped>
.box {
display: flex;
flex-direction: column;
align-items: center;
}
</style>