canvas签名组件 vue h5 保存签名图片为file文件,并将文件上传至七牛

组件代码: 

<template>
  <div>
    <div id="canvas" ref="canvas">
      <div id="clearCanvas" ref="clearCanvas" @click="clearSign">清除</div>
      <!-- <p id="saveCanvas" ref="saveCanvas">保存</p> -->
    </div>
  </div>
</template>
<script>
export default {
  name: 'sign-canvas',
  data () {
    return {
      signUrl: ''
    }
  },
  methods: {
    lineCanvas (obj) {
      this.linewidth = 2
      this.color = '#000000'
      this.background = '#ffffff'
      for (var i in obj) {
        this[i] = obj[i]
      }
      this.canvas = document.createElement('canvas')
      this.el.appendChild(this.canvas)
      this.ctx = this.canvas.getContext('2d')
      this.canvas.width = this.el.clientWidth
      this.canvas.height = this.el.clientHeight
      //开始绘制
      this.canvas.addEventListener('touchstart', function (e) {
        e.preventDefault()
        this.ctx.beginPath()
        this.top = this.el.offsetTop
        console.log('this.top', this.top)
        this.ctx.fillStyle = this.background
        this.ctx.fillRect(0, this.top, this.canvas.width, this.top + this.canvas.height)
        this.ctx.strokeStyle = this.color
        this.ctx.lineWidth = this.linewidth
        this.ctx.lineCap = 'round'
        this.ctx.moveTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY - this.top);
      }.bind(this), false)
      //绘制中
      this.canvas.addEventListener('touchmove', function (e) {
        e.preventDefault()
        this.ctx.lineTo(e.changedTouches[0].pageX, e.changedTouches[0].pageY - this.top);
        this.ctx.stroke()
      }.bind(this), false)
      //结束绘制
      this.canvas.addEventListener('touchend', function (e) {
        e.preventDefault()
        this.ctx.closePath()
        let dataurl = this.canvas.toDataURL('image/png')
        var arr = dataurl.split(','),
          mime = arr[0].match(/:(.*?);/)[1],
          bstr = atob(arr[1]),
          n = bstr.length,
          u8arr = new Uint8Array(n);
        while (n--) {
          u8arr[n] = bstr.charCodeAt(n);
        }
        var file = new File([u8arr], 'sign', { type: mime });
        // file.lastModifiedDate = new Date()
        console.info(file)
        this.$emit('getSignUrl', file)
      }.bind(this), false)
      //清除画布
      // this.clearEl.addEventListener('click', function () {
      //   this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
      //   this.$emit('clearSign')
      // }.bind(this), false)
      //保存图片,直接转base64
      // this.saveEl.addEventListener('click', function () {
      //   let imgBase64 = this.canvas.toDataURL()
      //   this.$emit('getSignUrl', imgBase64)
      // }.bind(this), false)
    },
    clearSign () {
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
      this.$emit('clearSign')
    }
    // toClear () {
    //   this.ctx.clearRect(0, 0, 300, 150)
    // },
    // toSave () {
    //   let base64Img = this.canvas.toDataURL()
    //   console.log(123, base64Img)
    // }
  },
  mounted () {
    this.lineCanvas({
      el: this.$refs.canvas,
      clearEl: this.$refs.clearCanvas,
      saveEl: this.$refs.saveCanvas
    })
  }

}
</script>
<style>
#canvas {
  width: 100%;
  height: 4rem /* 300/75 */;
  position: relative;
}
.mySign {
  width: 100%;
  height: 4rem /* 300/75 */;
}
.sign-img {
  width: 100%;
  height: 100%;
}
canvas {
  display: block;
}
#clearCanvas {
  position: absolute;
  top: -0.666667rem /* 50/75 */;
  right: 0.4rem /* 30/75 */;
  z-index: 1;
  color: #007eff;
}
#saveCanvas {
  width: 50%;
  height: 40px;
  line-height: 40px;
  text-align: center;
  position: absolute;
  bottom: 0;
  right: 0;
  border: 1px solid #dedede;
  z-index: 1;
}
</style>

上传七牛代码:

 getUploadToken () {
      return new Promise((resolve, reject) => {
        this.$http.get(`/cl-system/medias/uploadToken?mimeType=image/png&type=IMAGE`).then(result => {
          resolve(result.data)
        })
      })
    },
    async handleSign () {
      if (this.signUrl) {
        const tokenData = await this.getUploadToken()
        await this.uploadFile(this.signUrl, tokenData)
        const url = tokenData.fileUrl
        this.form.electronicSignatureImgUrl = url
      }
    },
    uploadFile (file, { token, fileName }) {
      const fd = new FormData()
      fd.append('file', file)
      fd.append('key', fileName)
      fd.append('token', token)
      var xhr = new XMLHttpRequest()
      xhr.open('POST', 'https://up.qbox.me/', true)
      return new Promise(resolve => {
        xhr.onload = function () {
          if (xhr.readyState === 4) {
            if (xhr.status === 200) {
              var data = JSON.parse(xhr.responseText)
              resolve(data.key)
            } else {
              console.log(xhr.statusText)
            }
          }
        }
        xhr.onerror = function (e) {
          console.log(xhr.statusText)
        }
        xhr.send(fd)
      })
    },

 

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页