vue或react当中canvas实现电子签名组件和使用canvas进行图片压缩

javascript 复制代码
<template>
  <div>
    <h1>vue3</h1>
    <canvas id="canvasWrite"> 浏览器不支持Canvas,请升级浏览器 </canvas>
    <div>
      <button class="submit" @click="submitWrite">提交签名</button>
      <button class="clear" @click="clearLine">清空签名</button>
    </div>
    <img :src="writeSrc" alt="" />
    <div>
      <button @click="compressImg(writeSrc, 1, setAfterCompression)">
        压缩图片
      </button>
      <div>
        <img :src="afterCompression" alt="" />
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      cvs: "",
      ctx: "",
      writeSrc: "",
      afterCompression: "",
    };
  },
  components: {},
  methods: {
    setAfterCompression(base64Data) {
      this.afterCompression = base64Data;
    },
    // 第二种压缩图片的方法(图片base64,图片类型,压缩比例,回调函数)
    // 该方法只能将图片压缩为为image/jpeg和image/webp两种类型的图片base64
    // 压缩结果存在一定误差  但比第一种方法更加准确
    compressImg(base64, rate = 1, callback) {
      // 声明一个Image对象
      var _img = new Image();
      // 将图片的地址赋予这个Image
      _img.src = base64;
      console.log("base6411", base64);
      // 在图片加载完成后
      _img.onload = function () {
        // 创建canvas标签
        var _canvas = document.createElement("canvas");
        // 设置canvas画布的宽高属性
        // this 指的是当前Image对象
        var w = this.width;
        var h = this.height;
        _canvas.setAttribute("width", w);
        _canvas.setAttribute("height", h);
        // 将图片渲染到canvas画布上 并设置渲染图片的宽高与画布的宽高一致
        _canvas.getContext("2d").drawImage(this, 0, 0, w, h);
        // 将canvas画布转换成base64 但第一个参数 转换后的图片类型只能为image/jpeg或image/webp
        // 根据压缩比例设置第二个参数图片质量(范围0-1)
        var base64 = _canvas.toDataURL("image/gif", rate);
        // 将结果通过回调函数传递给方法的调用者
        callback(base64);
      };
    },
    submitWrite() {
      const aTag = document.createElement("a");
      const base64 = this.cvs.toDataURL("image/gif", 1); //把我们的图片转成base64输出传送给后端;
      this.writeSrc = base64;
      console.log("base64", base64);
      aTag.href = base64;
      aTag.download = "签名";
      // this.getDom("body").appendChild(aTag).click();
      // aTag.remove();
    },
    getDom(selectStr) {
      return document.querySelector(selectStr);
    },
    clearLine() {
      // this.ctx.clearRect(清除的起点x轴,清除的起点y轴,清除画布的宽,清除画布的高);
      console.log("this.ctx", this.ctx);
      console.log("this.ctx.clearRect", this.ctx.clearRect);
      this.ctx.clearRect(0, 0, this.cvs.width, this.cvs.height);
    },
  },
  mounted() {
    let cvs = this.getDom("#canvasWrite");
    let ctx = cvs.getContext("2d");
    this.cvs = cvs;
    this.ctx = ctx;
    // 设置画线线条的粗细
    ctx.lineWidth = 3; //默认值是1
    // 设置线端样式,折角样式
    ctx.lineCap = "round";
    ctx.lineJoin = "round";
    cvs.onmousedown = (e) => {
      // 开始绘制名字
      ctx.beginPath();
      // 将画笔起点设置为当前位置
      ctx.moveTo(e.offsetX, e.offsetY);
      cvs.onmousemove = (ev) => {
        // 画笔跟着鼠标绘制线;
        ctx.lineTo(ev.offsetX, ev.offsetY);
        // 给绘制的线条上色
        // ctx.strokeStyle = "#f00"; //如果不给线条颜色上色默认是看不到绘制的线条的;
        ctx.stroke();
      };
    };
    cvs.onmouseup = () => (cvs.onmousemove = null);
    // this.getDom(".clear").onclick = () => {
    //   console.log("ctx.clearReact", ctx.clearRect);
    //   ctx.clearRect(0, 0, cvs.width, cvs.height);
    // };
  },
};
</script>

<style>
#canvasWrite {
  width: 400;
  height: 260;
  margin: 20px;
  box-shadow: 0px 0px 4px #aaa;
  /* cursor: url('./鼠标形状的icon'),auto; */
  cursor: pointer;
}
.submit {
  margin-left: 20px;
  padding: 5px 15px;
}
.clear {
  margin-left: 20px;
  padding: 5px 15px;
}
</style>

具体压缩可以参考
https://blog.csdn.net/weixin_45092437/article/details/129113469

相关推荐
daols882 小时前
vue vxe-table 自适应列宽,根据内容自适应宽度的2种使用方式
vue.js·vxe-table
OEC小胖胖4 小时前
告别 undefined is not a function:TypeScript 前端开发优势与实践指南
前端·javascript·typescript·web
行云&流水4 小时前
Vue3 Lifecycle Hooks
前端·javascript·vue.js
老虎06274 小时前
JavaWeb(苍穹外卖)--学习笔记04(前端:HTML,CSS,JavaScript)
前端·javascript·css·笔记·学习·html
三水气象台5 小时前
用户中心Vue3网页开发(1.0版)
javascript·css·vue.js·typescript·前端框架·html·anti-design-vue
烛阴5 小时前
Babel 完全上手指南:从零开始解锁现代 JavaScript 开发的超能力!
前端·javascript
CN-Dust6 小时前
[FMZ][JS]第一个回测程序--让时间轴跑起来
javascript
盛夏绽放6 小时前
Vue3 中 Excel 导出的性能优化与实战指南
vue.js·excel
全宝7 小时前
🎨前端实现文字渐变的三种方式
前端·javascript·css
yanlele7 小时前
前端面试第 75 期 - 2025.07.06 更新前端面试问题总结(12道题)
前端·javascript·面试