vue3+ts 签名插件 移动端、pc端

 

功能

兼容 PC 和 Mobile;
画布自适应屏幕大小变化(窗口缩放、屏幕旋转时画布无需重置,自动校正坐标);
自定义画布尺寸(导出图尺寸),画笔粗细、颜色,画布背景色;
支持裁剪 (针对需求:有的签字需要裁剪掉四周空白)。
导出图片格式为 base64;

 npm及官方教程地址:https://www.npmjs.com/package/vue3-esign

 以下是我使用的例子

注意:使用了 varlet UI 框架

1.安装

> npm i vue3-esign

 2.局部引入

import { Vue3Esign } from 'vue3-esign'

 components: { Vue3Esign },

3.HTML中调用插件

我是在弹框中写的,一样。

  <var-button @click.stop="openSign" class="my-sign" type="primary" text>签字</var-button>
<!--点击签字按钮,弹出如下弹框-->
<var-popup position="bottom" v-model:show="signPopup" >
      <div class="popup-wrap">
        <div class="popup-title">
          签字
        </div>
        <div class="popup-content">
          <div style="width: 100%;">
        <!--调用插件-->
            <Vue3Esign ref="vueEsignRef" 
           :height="clientHeight" 
           :width="clientWidth" 
           :bgColor="vueEsignBgColor" 
           :is-clear-bg-color="false"
           :is-crop="isCrop" 
           :line-width="lineWidth" 
           :line-color="lineColor" />
          </div>
        </div>
        <div class="popup-buttom">
          <var-button @click.stop="clearCanves" type="default" size="small">清除</var-button>
          <var-button  @click.stop="saveCanves"  type="primary" size="small" style="margin-left:70px">提交</var-button>
        </div>
      </div>
    </var-popup>

 注意:如果画布的宽度比容器的宽度大,那么画笔和线条会不同步的,就会出现画笔在右侧画,线条却在左边显示。所以画布的大小还是和容器一样吧。

4.script标签中

<script lang="ts">

import { computed, defineComponent, PropType, reactive, ref,nextTick,onMounted  } from "vue";
import { useRouter } from "vue-router";
import { Vue3Esign } from 'vue3-esign'
import { Snackbar } from '@varlet/ui'

export default defineComponent({
  components: { Vue3Esign },
  setup(props) {
    const router = useRouter();

    const vueEsignRef = ref<any>(null)
    const vueEsignBgColor = ref<string>('#f7f7f7')
    const lineWidth = ref(6)
    const lineColor = ref('#000000')
    const isCrop = ref(false)
    const img = ref('')

    const clientWidth = ref(400)
    const clientHeight = ref(250)
//打开弹框
    const openSign = async ()=> {
      signPopup.value = true;
      await nextTick();
    }
//清空
    function clearCanves():void{
      vueEsignRef.value.reset()
    }
//保存
    const saveCanves = async () => {
      try {
        const base64Data = await vueEsignRef.value.generate()
        console.log('res', base64Data)
        img.value = base64Data
        const blob = dataURLtoBlob(base64Data);

        const file = blobToFile(blob, "业主签字.png");

        const formData = new FormData();
        formData.append("file", file);

      }
      catch (error) {
        Snackbar({
          content: "请先签字",
          position: 'top',
          duration:1000
        })
        img.value = ''
      }
    }
    //将base64转换为blob
    function dataURLtoBlob(dataurl:string) {
      const arr = dataurl.split(',');
        const  mime = arr[0].match(/:(.*?);/)[1];

      const  bstr = atob(arr[1]);
      let  n = bstr.length;
      const  u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new Blob([u8arr], {type: mime});
    }

    //将blob转换为file
    function blobToFile(theBlob:any, fileName:string) {
      const file = new File([theBlob], fileName)
      return file;
    }
    onMounted(()=>{
      // 因为我的签字在弹框中,所以整体高度减去了弹框顶部和底部
      clientHeight.value = document.body.clientHeight*0.5-40-40;  
      clientWidth.value = document.body.clientWidth
      console.log(  clientWidth.value,clientHeight.value,"==========");
    })
    return {
      
      signPopup,
      clientWidth,
      clientHeight,
      vueEsignRef,
      vueEsignBgColor,
      lineWidth ,
      lineColor ,
      isCrop  ,
      
      openSign,
      clearCanves,
      saveCanves,
      dataURLtoBlob,
      blobToFile
    };
  }
});
</script>


/* 签字按钮样式 */
.my-sign {
  position: absolute;
  right: 0px;
  top:0;
}
.my-sign>>>.var-button__content {
  color:var(--md-blue-700);
}

/* 签字弹框样式 */
.popup-wrap {
  display: flex;
  flex-direction: column;
  height: 50vh;
  padding-bottom: 10px;
  box-sizing: border-box;
}
.popup-title {
  height: 40px;
  font-size: 16px;
  font-family: Source Han Sans SC;
  font-weight: 700;
  color: #333333;
  line-height: 40px;
  padding-left: 10px;
  border-bottom: 1px solid #ccc;
}
.popup-buttom {
  height: 40px;
  line-height: 40px;
  text-align: center;
}
.popup-content {
  flex:1px;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值