vue canvas实现手写签字

news/2024/7/24 12:24:08 标签: vue.js, 前端, canvas

小编最近的项目与合同有关,与合同有关就避免不了合同的签署,自然而然就需要搞个签名版啦,废话少说,上代码比较实在。

sign.vue

<template>
  <div class="signHandle">
    <canvas
      ref="signHandle"
      class="canvas"
      id="canvas"
      @touchstart="drawStart"
      @touchmove="drawing"
      @touchend="draeEnd"
    >
    </canvas>
    <div class="btn-box">
      <span class="clear-btn" @click.stop="clearSign">重置</span>
      <span class="submit-btn" @click.stop="saveSign">提交</span>
    </div>
  </div>
</template>
<script>
const { clientWidth, clientHeight } = document.documentElement;
export default {
  props: {
    //canvas 宽度
    canvasWidth: {
      type: Number,
      default: clientWidth,
    },
    //canvas 高度
    canvasHeight: {
      type: Number,
      default: clientHeight,
    },
    //canvas 背景色
    canvasBackground: {
      type: String,
      default: "#fff",
    },
    //线条颜色
    lineColor: {
      type: String,
      default: "#000",
    },
    //线条宽度
    lineWidth: {
      type: Number,
      default: 3,
    },
    //线条两端形状
    lineRound: {
      type: String,
      default: "round", //圆形
    },
  },
  data() {
    return {
      direction: false, //屏幕方向  true:横屏  false:竖屏
      el: "", //canvas dom
      ctx: "", //canvas内容
    };
  },
  created() {
    this.initPhoneDirection();
  },
  mounted() {
    this.draw();
  },
  methods: {
    /**
     * 判断当前手机为竖屏还是横屏
     */
    initPhoneDirection() {
      window.addEventListener(
        "onorientationchange" in window ? "oorientationchange" : "resize",
        () => {
          if (window.orientation === 180 || window.orientation === 0) {
            this.direction = false;
            this.draw();
          }
          if (window.orientation === 90 || window.orientation === -90) {
            this.direction = true;
            this.draw();
          }
        },
        false
      );
    },
    /**
     * 添加绘制线
     */
    draw() {
      document.addEventListener("touchmove", (e) => e.preventDefault(), {
        passive: false,
      });
      this.el = this.$refs.signHandle;
      this.initCanvas();
    },
    /**
     * 初始化canvas配置
     */
    initCanvas() {
      this.el.width = this.canvasWidth;
      this.el.height = this.canvasHeight;
      this.ctx = this.el.getContext("2d");
      this.setCanvas();
    },
    /**
     * canvas配置
     */
    setCanvas() {
      this.ctx.fillStyle = this.canvasBackground;
      //绘制矩形
      if (this.direction) {
        this.ctx.fillRect(0, 0, this.canvasHeight, this.canvasWidth);
      } else {
        this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
      }
      //设置线条颜色
      this.ctx.strokeStyle = this.lineColor;
      //设置线条宽度
      this.ctx.lineWidth = this.lineWidth;
      //设置线条两端形状
      this.ctx.lineCap = this.lineRound;
    },
    /**
     * 开始绘制
     */
    drawStart(e) {
      this.ctx.beginPath();
      this.ctx.moveTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY);
    },
    /**
     * 绘制过程
     */
    drawing(e) {
      this.ctx.lineTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY);
      this.ctx.stroke();
    },
    /**
     * 绘制结束
     */
    drawEnd(e) {
      this.ctx.closePath();
    },
    /**
     * 重置
     */
    clearSign() {
      this.initCanvas();
    },
    /**
     * 提交
     */
    saveSign() {
      const imagesBase64 = this.el.toDataURL();
      console.log("imagesBase64", imagesBase64);
    },
  },
};
</script>
<style lang="scss" scoped>
.signHandle {
  width: 100%;
  canvas {
    display: blick;
  }
  .btn-box {
    width: 100%;
    display: flex;
    justify-content: space-between;
    span {
      display: block;
      width: 50%;
      height: 44px;
      text-align: center;
      line-height: 44px;
      color: #333;
      background: #fff;
    }
    .submit-btn {
      color: #fff;
      background: #fa5050;
    }
  }
}
</style>

在开发过程中,小编发现了一个问题,不知道有没有童鞋遇到,问题:只要canvascanvas的父级或canvas的父级的父级,总而言之,只要canvas设置了定位,无论是什么定位,只要存在偏移,绘制就会出错,也不能说出错,是下笔的地方与实际绘制出的地方就会偏移设置定位偏移的量,听起来有些拗口,假设,小编原本在(10,10)坐标下笔开始绘制的,但是捏,小编设置定位距离顶部10px,那么绘制的时候,它可能就是从(10,20)坐标开始绘制的。小编猜测,是设置定位之后,x轴和y轴改变了,导致坐标都改变了导致的。小编想了个较笨的解决方案,就是,如果距离左右有偏移,在moveTo和lineTo的x轴坐标就需要进行相应的加减,如果是距离上下有偏移,则y轴坐标就需要进行相应的加减,至于加减多少就需要自己调试了;如果有偏移,该组件就无法进行通用了,但如果没有偏移,这个组件是通用的哦~希望对各位同学有帮助。


http://www.niftyadmin.cn/n/1202671.html

相关文章

Struts 2读书笔记-----Struts 2的异常处理

对于MVC框架而言。我们希望&#xff1a;当Action处理用户请求时。如果出现了异常1&#xff0c;则系统就会转入视图资源1&#xff0c;在该视图资源上输入服务器提示&#xff1b;如果出现了异常2&#xff0c;则系统会转入子图资源2&#xff0c;在该视图资源上输入服务器提示&…

Webpack源码基础-Tapable从使用Hook到源码解析

当我第一次看webpack源码的时候&#xff0c;会被其中跳转频繁的源码所迷惑&#xff0c;很多地方不断点甚至找不到头绪&#xff0c;因为plugin是事件系统&#xff0c;没有明确的调用栈。这一切都是因为没有先去了解webpack的依赖库Tapable。 Tapble是webpack在打包过程中&#x…

Struts 2读书笔记------struts 2的标签

Struts 2提供了大量的标签来开发表现层页面。这些标签的大部分&#xff0c;都可以在各种表现层技术中使用。 Struts 2 将所有标签分为以下三类&#xff1a; UI(用户界面)&#xff1a;主要用于生成HTML元素的标签 非UI标签&#xff1a;主要用于数据访问、逻辑控制等的标签 Ajax标…

小程序如何使用async和await

大家都知道在使用promise的时候能配合async和await是非常爽的一件事&#xff0c;但是在原生小程序开发中默认是不可以使用async和await的&#xff0c;如果直接使用会报一个错误“regeneratorRuntime is not defined”&#xff0c;那么我们改如何使用呢&#xff0c;我们可以直接…

类的关系-依赖

一、简单的依赖方法 import datetime#依赖 class Project:def __init__(self, name, team, start_date):self.name nameself.team teamself.start_date start_datedef __repr__(self):return f<Project :{self.name}>class Developer:def __init__(self, name, skills…

Struts 2读书笔记-----struts 的action配置

当实现Action处理类后&#xff0c;我们就可以在struts.xml文件中配置该Action了。配置Action的目的就是让Struts 2知道哪个Action处理哪个请求。也就是完成用户请求和Action之间的对应关系。 在 Action 映射中可以指定 result types 、异常处理器及拦截器&#xff0c;但是&…

GitLab 发布安全修复版本 11.9.7, 11.8.7 和 11.7.11

开发四年只会写业务代码&#xff0c;分布式高并发都不会还做程序员&#xff1f; >>> GitLab 为社区版和企业版发布了最新的 11.9.7, 11.8.7 和 11.7.11 版本。官方表示主要是为了修复企业版本中的重要安全问题&#xff0c;虽然社区版不受影响&#xff0c;但为了保持…

Struts 2读书笔记------Struts 2的类型转换

所有的MVC 框架&#xff0c;都需要负责解析 HTTP 请求参数&#xff0c;并将请求参数传给控制器组件。由于 HTTP 请求参数都是字符串类型&#xff0c;但是 java 是强类型的语言。&#xff0c;因此 MVC 框架必须将这些字符串参数转换成相应的数据类型。 Struts 2提供了非常强大的…