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

相关推荐
鱼与宇1 小时前
苍穹外卖-VUE
前端·javascript·vue.js
mapbar_front2 小时前
React 中 useCallback 的基本使用和原理解析
react.js
用户47949283569152 小时前
Safari 中文输入法的诡异 Bug:为什么输入 @ 会变成 @@? ## 开头 做 @ 提及功能的时候,测试同学用 Safari 测出了个奇怪的问题
前端·javascript·浏览器
裴嘉靖2 小时前
Vue 生成 PDF 完整教程
前端·vue.js·pdf
毕设小屋vx ylw2824262 小时前
Java开发、Java Web应用、前端技术及Vue项目
java·前端·vue.js
冴羽3 小时前
今日苹果 App Store 前端源码泄露,赶紧 fork 一份看看
前端·javascript·typescript
蒜香拿铁3 小时前
Angular【router路由】
前端·javascript·angular.js
时间的情敌3 小时前
Vite 大型项目优化方案
vue.js
西洼工作室4 小时前
高效管理搜索历史:Vue持久化实践
前端·javascript·vue.js
樱花开了几轉4 小时前
element ui下拉框踩坑
开发语言·javascript·ui