• 合同签名


    1.首先先画签名的cavans

    <template>
      <div class="signature">
        <!--touchstart,touchmove,touchend,touchcancel 这-->
        <div class="signature__header">
          <van-nav-bar
            title="电子签名"
            @click-left="onClickLeft"
          >
            <div slot="left">
              <van-icon name="arrow-left" size="25px" color="#b6b6b6" />
            </div>
          </van-nav-bar>
        </div>
        <div class="signature__zang"></div>
        <div>
          <div>
            <canvas id="canvas" :height="tabListHeight">Canvas画板</canvas>
          </div>
          <div class="signature__button">
            <van-button type="primary"
                        size="small"
                        v-on:click="save">保存, 下一步</van-button>
            <van-button type="default"
                        size="small"
                        v-on:click="clear">清除</van-button>
          </div>
        </div>
      </div>
    
    </template>
    
    <script>
    
    var draw
    var preHandler = function (e) {
      e.preventDefault()
    }
    class Draw {
      constructor (el) {
        this.el = el
        this.canvas = document.getElementById(this.el)
        this.canvas.width = document.documentElement.clientWidth
        this.cxt = this.canvas.getContext('2d')
        this.stage_info = this.canvas.getBoundingClientRect()
        this.path = {
          beginX: 0,
          beginY: 0,
          endX: 0,
          endY: 0
        }
      }
      init (btn) {
        var that = this
        this.canvas.addEventListener('touchstart', function (event) {
          document.addEventListener('touchstart', preHandler, { passive: false })
          that.drawBegin(event)
        })
        this.canvas.addEventListener('touchend', function (event) {
          document.addEventListener('touchend', preHandler, { passive: false })
          that.drawEnd()
        })
        this.clear(btn)
      }
      drawBegin (e) {
        var that = this
        window.getSelection()
          ? window.getSelection().removeAllRanges()
          : document.selection.empty()
        this.cxt.strokeStyle = '#000'
        this.cxt.beginPath()
        this.cxt.moveTo(
          e.changedTouches[0].clientX - this.stage_info.left,
          e.changedTouches[0].clientY - this.stage_info.top
        )
        this.path.beginX = e.changedTouches[0].clientX - this.stage_info.left
        this.path.beginY = e.changedTouches[0].clientY - this.stage_info.top
        this.canvas.addEventListener('touchmove', function () {
          that.drawing(event)
        })
      }
      drawing (e) {
        this.cxt.lineTo(
          e.changedTouches[0].clientX - this.stage_info.left,
          e.changedTouches[0].clientY - this.stage_info.top
        )
        this.path.endX = e.changedTouches[0].clientX - this.stage_info.left
        this.path.endY = e.changedTouches[0].clientY - this.stage_info.top
        this.cxt.stroke()
      }
      drawEnd () {
        document.removeEventListener('touchstart', preHandler, { passive: false })
        document.removeEventListener('touchend', preHandler, { passive: false })
        document.removeEventListener('touchmove', preHandler, { passive: false })
        // canvas.ontouchmove = canvas.ontouchend = null
      }
      clear (btn) {
        this.cxt.clearRect(0, 0, this.canvas.width, 600)
      }
      save () {
        return this.canvas.toDataURL('image/png')
      }
    }
    
    export default {
      data () {
        return {
          msg: 'Welcome to Your Vue.js App',
          val: true,
          screenWidth: 0,
          screenHeight: 0
        }
      },
      mounted () {
        draw = new Draw('canvas')
        draw.init()
        this.screenWidth = document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth
        this.screenHeight = document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight
      },
      computed: {
        tabListHeight () {
          return this.screenHeight - 100
        }
      },
      methods: {
        onClickLeft () {
          this.$router.go(-1)
        },
        clear: function () {
          draw.clear()
        },
        save: function () {
          var data = draw.save()
          this.$router.push({ name: 'newidentity' })
          sessionStorage.setItem('imgs', data)
          console.log(111)
          console.log(data)
        },
    
        mutate (word) {
          this.$emit('input', word)
        }
      }
      // data () {
      //   return {
      //     msg: 'Just use canvas to draw',
      //     degree: 0, // 屏幕整体旋转的角度, 可取 -90,90,180等值
      //     scope: [
      //       {
      //         value: 0,
      //         title: '正常',
      //       },
      //       {
      //         value: 90,
      //         title: '顺时针旋转90°',
      //       },
      //       {
      //         value: 180,
      //         title: '顺时针旋转180°',
      //       },
      //       {
      //         value: -90,
      //         title: '逆时针旋转90°',
      //       },
      //     ],
      //   };
      // },
      // components: {
      //   Draw,
      // },
      // mounted () {
      //   this.canvasBox = document.getElementById('canvasBox');
      //   this.initCanvas();
      // },
      // computed: {
      //   getHorizontalStyle () {
      //     console.log(232323)
      //     const d = document;
      //     const w = window.innerWidth || d.documentElement.clientWidth || d.body.clientWidth;
      //     const h = window.innerHeight || d.documentElement.clientHeight || d.body.clientHeight;
      //     let length = (h - w) / 2;
      //     let width = w;
      //     let height = h;
    
      //     switch (this.degree) {
      //       case -90:
      //         length = -length;
      //       case 90:
      //         width = h;
      //         height = w;
      //         break;
      //       default:
      //         length = 0;
      //     }
      //     if (this.canvasBox) {
      //       this.canvasBox.removeChild(document.querySelector('canvas'));
      //       this.canvasBox.appendChild(document.createElement('canvas'));
      //       setTimeout(() => {
      //         this.initCanvas();
      //       }, 200);
      //     }
      //     return {
      //       transform: `rotate(${this.degree}deg) translate(${length}px,${length}px)`,
      //        `${width}px`,
      //       height: `${height}px`,
      //       transformOrigin: 'center center',
      //     };
      //   },
      // },
      // methods: {
      //   initCanvas () {
      //     const canvas = document.querySelector('canvas');
      //     this.draw = new Draw(canvas, -this.degree);
      //   },
      //   clear () {
      //     this.draw.clear();
      //   },
      //   download () {
      //     this.draw.downloadPNGImage(this.draw.getPNGImage());
      //   },
      //   upload () {
      //     const image = this.draw.getPNGImage();
      //     const blob = this.draw.dataURLtoBlob(image);
    
      //     const url = '';
      //     const successCallback = (response) => {
      //       console.log(response);
      //     };
      //     const failureCallback = (error) => {
      //       return this.$toast(res.data.statusText);
      //     };
      //     this.draw.upload(blob, url, successCallback, failureCallback);
      //   },
      // },
    }
    </script>
    
    <style lang="less" scoped>
    h1,
    h2 {
      font-weight: normal;
    }
    ul {
      list-style-type: none;
      padding: 0;
    }
    li {
      display: inline-block;
      margin: 0 10px;
    }
    a {
      color: #42b983;
    }
    #canvasBox {
      display: flex;
      flex-direction: column;
      height: 100%;
    }
    canvas {
      flex: 1;
      cursor: crosshair;
      background-color: #f2f2f2;
    }
    .signature {
      height: 100%;
       100%;
      background-color: #ffffff;
      position: relative;
      .signature__header {
         100%;
        height: 46px;
        position: fixed;
        top: 0;
        left: 0;
      }
      .signature__zang {
         100%;
        height: 46px;
      }
      .signature__button {
        height: 50px;
        display: flex;
        flex-direction: row;
        justify-content: space-around;
        align-items: center;
      }
    }
    #keyword-box {
      margin: 10px 0;
    }
    </style>
    

      2.合成

    <template>
      <div id="identity" class="identity">
        <div class="identity__header">
          <van-nav-bar
            title="签订合同"
            @click-left="onClickLeft"
          >
            <div slot="left">
              <van-icon name="arrow-left" size="25px" color="#b6b6b6" />
            </div>
          </van-nav-bar>
        </div>
        <div class="identity__zang"></div>
        <div class="identity__content" :style="{ height: tabListHeight }">
          <div class="identity__content-item">
            <div class="identity-bnt van-hairline--top">
             <!-- <div class="upphoto"> 上传交款凭证</div> -->
              <!-- 上传图片 -->
                <!-- <div class="pushphoto">
                  <img class="pushphoto-add"
                      v-for="(item,index) of photo"
                      :key="index"
                      :src="item"
                      @click="showimg(item)">
                  <van-uploader class="pushphoto-add"
                                :after-read="onRead"
                                v-if="falses">
                    <img class="pushphoto-add"
                        src="../../assets/img/addphoto.png">
                  </van-uploader>
                </div> -->
    
           <!-- <div class="upphoto"> 上传身份证</div>
          <div class="pushphoto">
            <img class="pushphoto-add"
                 v-for="(item,index) of photo1"
                 :key="index"
                 :src="item"
                 @click="showimg1(item)">
            <van-uploader class="pushphoto-add"
                          :after-read="onRead1"
                          v-if="falses1">
              <img class="pushphoto-add"
                   src="../../assets/img/addphoto.png">
            </van-uploader>
          </div> -->
          <div class="info-conter"
             ref="infoconter">
    //这里是你的合同 <img src="../../assets/img/hetong.png" id="imgCover" ref="imgCover">
    //这里是你的签名 <img v-show="zou" :src="ba64" id="imgUploadX"> <canvas v-show="yincang" id="can"></canvas> </div> <!-- <van-button type="primary" @click="pull">签订合同</van-button> --> </div> </div> </div> </div> </template> <script> export default { mounted () { this.$nextTick(() => { this.ba64 = sessionStorage.getItem('imgs'); //this.pull(); this.$toast.loading({ mask: true, message: '合同签名中,请等待...' });
    //渲染需要一个过程,需要用到定时器,不然手机合成的签名合同是一片黑 setTimeout(()=>{ // console.log(Timer); this.pull(); },4000); this.screenWidth = document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth this.screenHeight = document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight }) }, computed: { tabListHeight () { return this.screenHeight / (this.screenWidth / 10) - 2 - 1.226667 + 'rem' } }, data () { return { ba64: '', zou: false, yincang: false, enen: false, frist: '', second: '', files: '', three: '', dataurls: '', threeimg: '', secondimg: '', fristimg: '', text1: true, text2: true, text3: true, imgs1: false, imgs2: false, imgs3: false, screenWidth: 0, screenHeight: 0, falses: true, falses1:true, photo: [], photo1: [], photolist: [], photolist1: [], } }, methods: { // onRead (i) { // this.photo.push(i.content); // //console.log(this.photo); // this.photolist.push(i.file) // if (this.photo.length >= 3) { // this.falses = false // } // console.log(this.photo) // }, // onRead1 (i) { // this.photo1.push(i.content) // this.photolist1.push(i.file) // if (this.photo1.length >= 3) { // this.falses1 = false // } // console.log(this.photo1) // }, // showimg (item) { // this.show = true // this.file = item // }, // showimg1 (item) { // this.show = true // this.file1 = item // }, // 合成图片 pull () { console.log(this.photolist); //console.log(this.photolist1); this.compound(); // setTimeout(()=>{ this.$router.push({ path: '/newesignature' }) // },5000); },
    //这里是签名与合同的渲染合成 compound () { this.yincang = true let eleImgUploadX = document.getElementById('imgUploadX') let eleImgCover = document.getElementById('imgCover') let can = document.getElementById('can') let context = can.getContext('2d') let width = this.$refs.infoconter.offsetWidth let heigth = this.$refs.infoconter.offsetHeight let heigths = this.$refs.imgCover.offsetHeight let hei = this.$refs.imgCover.offsetHeight can.width = width can.height = heigths var devicePixelRatio = window.devicePixelRatio || 1, backingStoreRatio = context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1, ratio = devicePixelRatio / backingStoreRatio var oldWidth = can.width; var oldHeight = can.height; can.width = oldWidth * ratio can.height = oldHeight * ratio can.style.width = oldWidth + 'px' can.style.height = oldHeight + 'px' context.scale(ratio, ratio) console.log(width) context.drawImage(eleImgCover, 0, 0, width, heigth) context.drawImage(eleImgUploadX, width * 0.65, hei * 0.8, 95, 80) console.log(can.toDataURL('image/png')) let dataurls = can.toDataURL('image/jpeg') this.dataurls = can.toDataURL('image/jpeg') this.enen = true // 转文件flie let filename = 'canvas.jpg' let feli = dataURLtoFile(dataurls, filename) function dataURLtoFile (dataurl, filename) {//将base64转换为文件 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); } return new File([u8arr], filename, { type: mime }) } this.files = feli console.log(this.files) sessionStorage.setItem('files', this.dataurls) }, onClickLeft () { this.$router.push({ name: 'openvip' }) } } } </script> <style lang="less" scoped> .identity { 100%; // height: 100%; overflow: hidden; position: relative; img { 100%; height: 100%; } .identity__header { 100%; height: 46px; position: fixed; top: 0; left: 0; z-index: 999; } .identity__zang { 100%; height: 46px; } .info-conter { 100%; // height: 100%; // background-color: white; // overflow: hidden; overflow-x: auto; overflow-y: auto; position: absolute; right: 0; // bottom: -100%; } #imgCover { opacity: 0; } .info-conter img { 100%; } .identity__content{ 100%; background-color: #ffffff; overflow: scroll; -webkit-overflow-scrolling: touch; .identity__content-item { // height: 100%; 100%; .identity-frist { 100%; height: 180px; background-color: #f2f2f2; margin-top: 10px; margin-bottom: 10px; text-align: center; line-height: 180px; font-size: 18px; .van-uploader { 100%; height: 100%; } } } } .pushphoto { 100%; height: 100px; padding-left: 16px; padding-bottom: 16px; // margin-bottom: 20px; box-sizing: border-box; display: flex; .pushphoto-add { 25%; height: 100%; margin-right: 10px; img { 100%; } } } .identity-bottom { 100%; height: 118px; } .identity-bnt { 100%; // position: fixed; // bottom: 0px; // z-index: 99999; padding: 20px 20px; background-color: #ffffff; box-sizing: border-box; // height: 118px; .identity-reset { margin-bottom: 10px; } .van-button { 100%; } } } </style>

      效果:

     

  • 相关阅读:
    [20190401]跟踪dbms_lock.sleep调用.txt
    [20190401]隐含参数_mutex_spin_count.txt
    [20190401]关于semtimedop函数调用.txt
    [20190401]那个更快的疑问.txt
    [20190329]探究sql语句相关mutexes补充2.txt
    [20190328]简单探究sql语句相关mutexes.txt
    [20190324]奇怪的GV$FILESPACE_USAGE视图.txt
    [20190322]测试相同语句遇到导致cursor pin S的疑问.txt
    linux命令(8):cp 命令
    linux命令(7):mv命令
  • 原文地址:https://www.cnblogs.com/guangzhou11/p/10653830.html
Copyright © 2020-2023  润新知