手写签名(vue2+vant2)

先看效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
*直接贴代码 *
使用签名的页面文件

<template>
  <div class="about">
    <h1>This is an about1 page</h1>
    <div>
      <span class="danger">*</span>
      手写签名
    </div>
    <div class="disColumn">
      <img
        v-if="signvalue"
        :src="signvalue"
        class="nullSign"
        @click="signCompentShow"
      />
      <div v-else class="nullSign" @click="signCompentShow" />
    </div>
      <van-popup
        v-model="signPopup"
        close-on-popstate
      >
        <CostomSignToImg
          v-show="signPopup"
          ref="costomSignToImg"
          :cancel="cancel"
          :confirm="confirm"
        />
      </van-popup>
  </div>
</template>

<script>
import CostomSignToImg from "./CostomSignToImg.vue";
export default {
  components:{
    CostomSignToImg
  },
  data() {
    return {
      signvalue: false,
      signPopup: false
    };
  },
  methods: {
    
    signCompentShow() {
      console.log(111);
      this.scrollTop = document.documentElement.scrollTop;
      document.body.scrollTop = document.documentElement.scrollTop = 0;
      setTimeout(() => {
        this.signPopup = true;
      }, 100);
    },
    cancel() {
      document.body.scrollTop = document.documentElement.scrollTop = this.scrollTop;
      this.signPopup = false;
    },
    confirm(img, a) {
      document.body.scrollTop = document.documentElement.scrollTop = this.scrollTop;
      this.signPopup = false;
      console.log(img);
      console.log(a);
      this.signvalue = a;
      this.blob = img;
    },
    
  
  },
};
</script>

<style>
.questItem {
  padding: 0.625rem;
}

/* /deep/ .van-checkbox__label {
  color: #f76a38;
} */

.nullSign {
  background: #ebebeb;
  height: 6.25rem;
  width: 80vw;
  margin: 0.625rem auto 0 auto;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
  opacity: 0;
}

.searchLi:hover {
  background-color: var(--color);
  color: #fff;
}

.searchBox {
  height: 9.375rem;
}
</style>

签名的组件

<template>
  <div ref="container" class="container">
      <canvas ref="myCanvas"></canvas>
      <div class="control-ops control " ref="control" style="justify-content: space-around">
          <van-button type="default" @click="onCancel">返回</van-button>
          <van-button type="default" @click="clearArea">重新签名</van-button>
          <van-button type="default" @click="onConfirm">确认</van-button>
      </div>
  </div>
</template>

<script>

  export default {
      props: ['confirm', 'cancel'],
      data() {
          return {
              lastX: null,
              lastY: null,
              initialized: false,
              orientation: "portrait",
              isSigned:false,
          };
      },
      mounted() {
          var mql = window.matchMedia("(orientation: portrait)");
          this.onMatchMeidaChange(mql);
          mql.addListener(this.onMatchMeidaChange);
      },
      methods: {
        getIsSigned(){
          console.log(this.isSigned);
          sessionStorage.setItem("isSigned",this.isSigned);
          return this.isSigned;
        },
          onMatchMeidaChange(mql) {
              if (mql.matches) {
                  this.orientation = "portrait";
              } else {
                  this.orientation = "landscape";
              }
              this.$nextTick(this.init);
          },
          onConfirm() {
              const c = this.$refs.myCanvas;
              let image = c.toDataURL("image/png");
              //得到生成后的签名base64位  url 地址
              c.toBlob(async blob => {
                  const url = URL.createObjectURL(blob);
                  console.log(url, 'url');
                  if (this.orientation === "portrait") {
                      image = await this.rotateImage(url);
                  } else {
                      this.confirm(blob, image);
                  }
                  URL.revokeObjectURL(url);
              });
              this.clearArea()
          },
          onCancel() {
              this.clearArea()
              this.cancel();
          },
          clearArea() {
              var c = this.$refs.myCanvas;
              var ctx = c.getContext("2d");
              // Use the identity matrix while clearing the canvas
              ctx.setTransform(1, 0, 0, 1, 0, 0);
              ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
          },
          rotateImage(url) {
              let that =this
              const width = window.innerWidth;
              const height = window.innerHeight;
              const canvas = document.createElement("canvas");
              canvas.width = height;
              canvas.height = width;
              const ctx = canvas.getContext("2d");
              ctx.rotate(-Math.PI / 2);
              ctx.translate(-width, 0);
              const image = new Image();
              image.src = url;
              image.setAttribute("crossOrigin", "anonymous");
              return new Promise((resolve, reject) => {
                  image.onload = function () {
                      ctx.drawImage(this, 0, 0, width, height);
                      canvas.toBlob(async blob => {
                          that.confirm(blob, canvas.toDataURL("image/png"));
                      });
                      resolve(canvas.toDataURL("image/png"));
                  };
                  image.onerror = e => {
                      reject(e);
                  };
              });
          },
          setControl() {
        
          },
          init() {
              const width = window.innerWidth;
              const height = window.innerHeight;
              var mousePressed = false;
              var c = this.$refs.myCanvas;
              const ctx = c.getContext("2d");
              const squareLen = Math.max(width, height);
              c.setAttribute("width", `${width}px`);
              c.setAttribute("height", `${height - 4}px`);
              ctx.moveTo(0, 0);
              ctx.fillStyle = "#fff";
              ctx.fillRect(0, 0, squareLen, squareLen);
              this.setControl();
              var vm = this;

              // 触摸屏
              //签名开始
              c.addEventListener(
                  "touchstart",
                  function (event) {
                      if (event.targetTouches.length == 1) {
                          event.preventDefault(); // 阻止浏览器默认事件,重要
                          var touch = event.targetTouches[0];
                          mousePressed = true;
                          vm.draw(
                              touch.pageX - this.offsetLeft,
                              touch.pageY - this.offsetTop,
                              false
                          );
                          this.isSigned = true;
          sessionStorage.setItem("isSigned",this.isSigned);
                      }
                  },
                  false
              );
          //签名移动开始
              c.addEventListener(
                  "touchmove",
                  function (event) {
                      if (event.targetTouches.length == 1) {
                          event.preventDefault(); // 阻止浏览器默认事件,重要
                          var touch = event.targetTouches[0];
                          if (mousePressed) {
                              vm.draw(
                                  touch.pageX - this.offsetLeft,
                                  touch.pageY - this.offsetTop,
                                  true
                              );
                          this.isSigned = true
                          
          sessionStorage.setItem("isSigned",this.isSigned);
                          console.log(sessionStorage.getItem("isSigned"));
                          }
                      }
                  },
                  false
              );

              c.addEventListener(
                  "touchend",
                  function (event) {
                      if (event.targetTouches.length == 1) {
                          event.preventDefault(); // 阻止浏览器默认事件,防止手写的时候拖动屏幕,重要
                          // var touch = event.targetTouches[0];
                          mousePressed = false;
                      }
                  },
                  false
              );

              //		   鼠标
              c.onmousedown = function (event) {
                  mousePressed = true;
                  vm.draw(
                      event.pageX - this.offsetLeft,
                      event.pageY - this.offsetTop,
                      false
                  );
                  this.isSigned = true
              };

              c.onmousemove = function (event) {
                  if (mousePressed) {
                      vm.draw(
                          event.pageX - this.offsetLeft,
                          event.pageY - this.offsetTop,
                          true
                      );
                          this.isSigned = true
                  }
              };

              c.onmouseup = function () {
                  mousePressed = false;
                  this.isSigned = true
                  console.log(this.isSigned);
              };

              
          },
          draw(x, y, isDown) {
              var c = this.$refs.myCanvas;
              var ctx = c.getContext("2d");
              if (isDown) {
                  ctx.beginPath();
                  ctx.strokeStyle = "#666"; //颜色
                  ctx.lineWidth = 3; //线宽
                  ctx.lineJoin = "round";
                  ctx.moveTo(this.lastX, this.lastY);
                  ctx.lineTo(x, y);
                  ctx.closePath();
                  ctx.stroke();
              }
              this.lastX = x;
              this.lastY = y;
          }
      }
  };
</script>

<style >
  canvas {
      background: #fff;
  }

  .container {
      position: relative;
  }

  .control {
      position: absolute;
      bottom: 0;
      background: #ddd;
  }

  @media screen and (orientation: portrait) {
      .control {
          left: 0;
          top: 0;
          display: flex;
          flex-direction: column;
          height: 100vh;
      }
      .van-button {
          transform: rotate(90deg);
      }
  }

  @media screen and (orientation: landscape) {
      .control {
          left: 0;
          width: 100%;
      }
  }
</style>

最终的签名图片是base64格式的
在父组件的 confirm函数里面我也有打印

终-----------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值