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

相关推荐
小白小白从不日白6 分钟前
react 组件通讯
前端·react.js
罗_三金16 分钟前
前端框架对比和选择?
javascript·前端框架·vue·react·angular
Fan_web1 小时前
JavaScript高级——闭包应用-自定义js模块
开发语言·前端·javascript·css·html
冯宝宝^1 小时前
基于mongodb+flask(Python)+vue的实验室器材管理系统
vue.js·python·flask
叫我:松哥1 小时前
基于Python flask的医院管理学院,医生能够增加/删除/修改/删除病人的数据信息,有可视化分析
javascript·后端·python·mysql·信息可视化·flask·bootstrap
cc蒲公英2 小时前
Vue2+vue-office/excel 实现在线加载Excel文件预览
前端·vue.js·excel
好名字08212 小时前
monorepo基础搭建教程(从0到1 pnpm+monorepo+vue)
前端·javascript
森叶2 小时前
Electron-vue asar 局部打包优化处理方案——绕开每次npm run build 超级慢的打包问题
vue.js·electron·npm
Flying_Fish_roe2 小时前
浏览器的内存回收机制&监控内存泄漏
java·前端·ecmascript·es6
c#上位机2 小时前
C#事件的用法
java·javascript·c#