最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue+canvas實(shí)現(xiàn)移動(dòng)端手寫(xiě)簽名

 更新時(shí)間:2020年05月21日 16:01:54   作者:XingFang666  
這篇文章主要為大家詳細(xì)介紹了vue+canvas實(shí)現(xiàn)移動(dòng)端手寫(xiě)簽名,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了vue+canvas實(shí)現(xiàn)移動(dòng)端手寫(xiě)簽名的具體代碼,供大家參考,具體內(nèi)容如下

<template>
 <div class="sign">
  <div class="header">
    <i class="el-icon-arrow-left backImg" @click="goBack"></i>
    <span class="title">個(gè)人簽名</span>
  </div>
  <section class="signature">
    <div class="signatureBox">
      <div class="canvasBox" ref="canvasHW">
        <canvas ref="canvasF" class="canvasStyle" @touchstart='touchStart' @touchmove='touchMove' @touchend='touchEnd' @mousedown="mouseDown" @mousemove="mouseMove" @mouseup="mouseUp"></canvas>
      </div>
    </div>
  </section>
  <div class="btnBox">
    <div @click="overwrite" class="btn1">重置</div>
    <div @click="commit" class="btn1">確定</div>
  </div>
  <div class="imglist-box" :style="imgUrlList.length>0 ? 'border: 1px solid #d9d9d9;' : ''">
   <img v-for="i in imgUrlList" class="imgCanvas" :src="i">
   <img v-show="imgUrlList.length>0" src="../../assets/img/signdelete.png" class="resign" @click="deleteAll">
  </div>
  <div class="tijiao-box">
   <button @click="commitAll" class="tijiao">提 交</button>
  </div>
 </div>
</template>
<script>
import { Bus } from '@/utils'
export default {
 name:'personsign',
 data() {
   return {
    stageInfo:'',
    imgUrl:'',
    imgUrlList:[],
    client: {},
    points: [],
    canvasTxt: null,
    startX: 0,
    startY: 0,
    moveY: 0,
    moveX: 0,
    endY: 0,
    endX: 0,
    w: null,
    h: null,
    isDown: false,
    isViewAutograph: this.$route.query.isViews > 0,
    contractSuccess: this.$route.query.contractSuccess,
   }
  },
  mounted() {
   let canvas = this.$refs.canvasF
   canvas.height = this.$refs.canvasHW.offsetHeight -0
   canvas.width = this.$refs.canvasHW.offsetWidth - 0
   this.canvasTxt = canvas.getContext('2d')
   this.canvasTxt.lineWidth = 4
   this.stageInfo = canvas.getBoundingClientRect()
  },
  methods: {
   goBack(){
    this.$router.go(-1)
    // session.clear()
   },
   //mobile
   touchStart(ev) {
    ev = ev || event
    ev.preventDefault()
    if (ev.touches.length == 1) {
     let obj = {
      x: ev.targetTouches[0].clienX,
      y: ev.targetTouches[0].clientY,
     }
     this.startX = obj.x
     this.startY = obj.y
     this.canvasTxt.beginPath()
     this.canvasTxt.moveTo(this.startX, this.startY)
     this.canvasTxt.lineTo(obj.x, obj.y)
     this.canvasTxt.stroke()
     this.canvasTxt.closePath()
     this.points.push(obj)
    }
   },
   touchMove(ev) {
    ev = ev || event
    ev.preventDefault()
    if (ev.touches.length == 1) {
     let obj = {
      x: ev.targetTouches[0].clientX - this.stageInfo.left,
      y: ev.targetTouches[0].clientY - this.stageInfo.top
     }
     this.moveY = obj.y
     this.moveX = obj.x
     this.canvasTxt.beginPath()
     this.canvasTxt.moveTo(this.startX, this.startY)
     this.canvasTxt.lineTo(obj.x, obj.y)
     this.canvasTxt.stroke()
     this.canvasTxt.closePath()
     this.startY = obj.y
     this.startX = obj.x
     this.points.push(obj)
    }
   },
   touchEnd(ev) {
    ev = ev || event
    ev.preventDefault()
    if (ev.touches.length == 1) {
     let obj = {
      x: ev.targetTouches[0].clientX - this.stageInfo.left,
      y: ev.targetTouches[0].clientY - this.stageInfo.top
     }
     this.canvasTxt.beginPath()
     this.canvasTxt.moveTo(this.startX, this.startY)
     this.canvasTxt.lineTo(obj.x, obj.y)
     this.canvasTxt.stroke()
     this.canvasTxt.closePath()
     this.points.push(obj)
    }
   },
   //pc
   mouseDown(ev) {
    ev = ev || event
    ev.preventDefault()
    if (1) {
     let obj = {
      x: ev.offsetX,
      y: ev.offsetY
     }
     this.startX = obj.x
     this.startY = obj.y
     this.canvasTxt.beginPath()
     this.canvasTxt.moveTo(this.startX, this.startY)
     this.canvasTxt.lineTo(obj.x, obj.y)
     this.canvasTxt.stroke()
 
     // this.canvasTxt.strokeRect(20,20,80,100);
     this.canvasTxt.closePath()
     this.points.push(obj)
     this.isDown = true
    }
   },
   mouseMove(ev) {
    ev = ev || event
    ev.preventDefault()
    if (this.isDown) {
     let obj = {
      x: ev.offsetX,
      y: ev.offsetY
     }
     this.moveY = obj.y
     this.moveX = obj.x
     this.canvasTxt.beginPath()
     this.canvasTxt.moveTo(this.startX, this.startY)
     this.canvasTxt.lineTo(obj.x, obj.y)
     this.canvasTxt.stroke()
     this.canvasTxt.closePath()
     this.startY = obj.y
     this.startX = obj.x
     this.points.push(obj)
    }
   },
   mouseUp(ev) {
    ev = ev || event
    ev.preventDefault()
    if (1) {
     let obj = {
      x: ev.offsetX,
      y: ev.offsetY
     }
     this.canvasTxt.beginPath()
     this.canvasTxt.moveTo(this.startX, this.startY)
     this.canvasTxt.lineTo(obj.x, obj.y)
     this.canvasTxt.stroke()
     this.canvasTxt.closePath()
     this.points.push(obj)
     this.points.push({x: -1, y: -1})
     this.isDown = false
    }
   },
   //重寫(xiě)
   overwrite() {
    this.canvasTxt.clearRect(0, 0, this.$refs.canvasF.width, this.$refs.canvasF.height)
    this.points = []
   },
   //確定簽名
   commit() {
    this.imgUrl=this.$refs.canvasF.toDataURL();
    this.imgUrlList.push(this.imgUrl)
    if(this.imgUrlList.length>0){
     this.canvasTxt.clearRect(0, 0, this.$refs.canvasF.width, this.$refs.canvasF.height)
     this.points = []
    }
   },
   deleteAll(){
    this.imgUrlList = []
   },
   // 提交簽名給前一頁(yè)
   commitAll(){
    // 用canvas合并多張圖片的base64為一張圖的base64
    var canvas = document.createElement("canvas");
    canvas.width = 75*this.imgUrlList.length;
    canvas.height = 100;
    var context = canvas.getContext("2d");
 
    context.rect(0 , 0 , canvas.width , canvas.height);
    context.fillStyle = "#fff";
    context.fill();
 
    var myImage = new Image();
    myImage.crossOrigin = 'Anonymous';
    // 當(dāng)簽名列表有值時(shí)
    if(this.imgUrlList.length>0){
     for(let i = 0;i<this.imgUrlList.length;i++){
      myImage.src = this.imgUrlList[i]
      // 多張圖片繪制成一張圖片
      context.drawImage(myImage , 50*i , 0 , 75 , 75); //context.drawImage(img,x,y,width,height);
      // context.font = "60px Courier New";
      // context.fillText("我是文字",350,450);
     }
     var base64 = canvas.toDataURL("image/jpg"); //"image/jpg" 這里注意一下
     this.$router.go(-1) //要在bus之前寫(xiě)不然值傳不回去
     setTimeout(() => {
      Bus.$emit('signImage',base64) //簽名base64傳給前一頁(yè)
     }, 300)
    }
   }
  },
  beforeDestroy(){
   // 銷(xiāo)毀bus
   Bus.$off()
  }
}
</script>
<style scoped lang="scss">
// 簽名樣式很重要,會(huì)影響觸點(diǎn)位置
.sign{
  width: 100%;
  min-height: 100vh;
  position: relative;
  .header{
   margin-bottom: 20px;
  }
  .tijiao-box{
    width: 100%;
    text-align: center;
  }
  .tijiao{
    width: 90%;
    height: 84px;
    color: #fff;
    border-radius: 2px;
    background: #fa4b31;
    box-shadow: 0 0 0px 1px #fa4b31;
    font-size: 30px;
 
   }
}
.signature{
 width: 100%;
 height: 50vh;
}
.imglist-box{
 width: 90%;
 margin: 0 auto;
 margin-bottom: 20px;
 position: relative;
}
.imgCanvas{
 width: 150px;
 height: 150px;
}
.resign{
 width: 14%;
 position: absolute;
 top: 0;
 right: 0;
}
 .signatureBox {
  width: 90%;
  margin: 0 auto;
  height: calc(100% - 50px);
  box-sizing: border-box;
  overflow: hidden;
  background: #fff;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
 }
 .canvasBox {
  width: 100%;
  align-items: center;
  box-sizing: border-box;
  flex: 1;
 }
 canvas {
  background-image: url('../../assets/img/signbg.png');
  background-position: center center;
  background-repeat: no-repeat;
  background-origin: border-box;
  background-size: 100% 100%;
 }
 .btnBox{
  width: 90%;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
  .btn1{
   width: 46%;
   height: 84px;
   line-height: 84px;
   color: #fa4b31;
   border-radius: 2px;
   background: #fff;
   border: 1px solid #fa4b31;
   box-shadow: 0 0 0px 1px #fa4b31;
   font-size: 30px;
   text-align: center;
  }
}
 .btnBox button:first-of-type {
  background: transparent;
  border-radius: 4px;
  height: 40px;
  width: 80px;
  font-size: 14px;
 }
 .btnBox button:last-of-type {
  background: #71b900;
  color: #fff;
  border-radius: 4px;
  height: 40px;
  width: 80px;
  font-size: 14px;
 }
</style>

重置就是清除田字格當(dāng)前字,確定就將字保存為一張圖片base64排列在列表。

重簽就是刪除列表所有圖片,提交就是將多張圖合并為一張且傳給前一頁(yè)顯示。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue-Router的使用方法

    Vue-Router的使用方法

    這篇文章主要介紹了Vue-Router的使用方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • vue使用html2canvas和jspdf將html轉(zhuǎn)成pdf

    vue使用html2canvas和jspdf將html轉(zhuǎn)成pdf

    在前端開(kāi)發(fā)中, html轉(zhuǎn)pdf是最常見(jiàn)的需求,下面這篇文章主要給大家介紹了關(guān)于vue如何使用html2canvas和jspdf將html轉(zhuǎn)成pdf的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-03-03
  • el-menu修改item顏色的實(shí)現(xiàn)

    el-menu修改item顏色的實(shí)現(xiàn)

    本文主要介紹了el-menu修改item顏色的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Vue開(kāi)發(fā)環(huán)境的搭建全過(guò)程

    Vue開(kāi)發(fā)環(huán)境的搭建全過(guò)程

    文章介紹了在網(wǎng)頁(yè)中使用Vue.js的四種方式:基本方式、腳手架方式(Vue2.0)、使用WebStorm集成環(huán)境創(chuàng)建vue-cli項(xiàng)目(Vue3.0)以及Vue項(xiàng)目的目錄結(jié)構(gòu),每種方式都有詳細(xì)的步驟和示例,幫助讀者快速上手Vue.js開(kāi)發(fā)
    2024-11-11
  • Vue2過(guò)渡標(biāo)簽transition使用動(dòng)畫(huà)方式

    Vue2過(guò)渡標(biāo)簽transition使用動(dòng)畫(huà)方式

    這篇文章主要介紹了Vue2過(guò)渡標(biāo)簽transition使用動(dòng)畫(huà)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • vuex管理狀態(tài) 刷新頁(yè)面保持不被清空的解決方案

    vuex管理狀態(tài) 刷新頁(yè)面保持不被清空的解決方案

    今天小編就為大家分享一篇vuex管理狀態(tài) 刷新頁(yè)面保持不被清空的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-11-11
  • 解決vue項(xiàng)目運(yùn)行提示W(wǎng)arnings while compiling.警告的問(wèn)題

    解決vue項(xiàng)目運(yùn)行提示W(wǎng)arnings while compiling.警告的問(wèn)題

    這篇文章主要介紹了解決vue項(xiàng)目運(yùn)行提示W(wǎng)arnings while compiling.警告的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-09-09
  • VUE生命周期全面系統(tǒng)詳解

    VUE生命周期全面系統(tǒng)詳解

    Vue的生命周期就是vue實(shí)例從創(chuàng)建到銷(xiāo)毀的全過(guò)程,也就是new?Vue()?開(kāi)始就是vue生命周期的開(kāi)始。Vue?實(shí)例有?個(gè)完整的?命周期,也就是從開(kāi)始創(chuàng)建、初始化數(shù)據(jù)、編譯模版、掛載Dom?->?渲染、更新?->?渲染、卸載?等?系列過(guò)程,稱(chēng)這是Vue的?命周期
    2022-07-07
  • Vue結(jié)合Element-Plus封裝遞歸組件實(shí)現(xiàn)目錄示例

    Vue結(jié)合Element-Plus封裝遞歸組件實(shí)現(xiàn)目錄示例

    本文主要介紹了Vue結(jié)合Element-Plus封裝遞歸組件實(shí)現(xiàn)目錄示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Vue實(shí)現(xiàn)控制商品數(shù)量組件封裝及使用

    Vue實(shí)現(xiàn)控制商品數(shù)量組件封裝及使用

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)控制商品數(shù)量組件的封裝及使用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09

最新評(píng)論

阜宁县| 新蔡县| 泗阳县| 金阳县| 乌鲁木齐县| 三台县| 天全县| 垣曲县| 贵港市| 中卫市| 大连市| 南昌县| 凤凰县| 自贡市| 广宁县| 百色市| 乌海市| 蒲城县| 息烽县| 全椒县| 崇明县| 永年县| 漯河市| 汽车| 德钦县| 信阳市| 武城县| 大石桥市| 定兴县| 九江市| 商南县| 双流县| 安多县| 米脂县| 龙口市| 名山县| 灵台县| 格尔木市| 娄底市| 万州区| 琼结县|