Vue3 Canvas signature board component package

insert image description here

<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>
<script>
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,
    };
  },
};
</script>
<style scoped>
    * {
    
    
  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;
}
</style>

Guess you like

Origin blog.csdn.net/weixin_49295874/article/details/125998559