h5实现签名功能

html 复制代码
<el-dialog :visible.sync="signatureVisible" :close-on-click-modal="false" width="1337px" class="dialogSignature" :before-close="close">
    <div class="tLeft reminderT" slot="title"></div>
    <div style="width:1250px;height:465px;" class="pRelative canvasBox" v-loading="canvasLoading">
        <canvas id="canvas3" width="1245px" height="465px" class="pAbsolute"></canvas>
    </div>
    <div class="buttonBox">
        <!-- w:359 h:89 -->
        <el-button class="dConfirm" @click="commitOk">签好了</el-button>
        <el-button class="dCancel" @click="clearCanvas">清除重签</el-button>
    </div>
</el-dialog>
javascript 复制代码
methods:{
    dataURLtoBlob(dataurl) {
        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 Blob([u8arr], {
            type: mime,
        });
    },
    blobCl(data){
        return new Blob(data)
    },
    initCanvas(){
        this.$nextTick(()=>{
            var c = document.getElementById('canvas3');
            //获取canvs上下文
            var ctx = c.getContext("2d"); 
            ctx.fillStyle = '#FFFFFF'
            ctx.fillRect(0,0,1250,465)//设置canvas背景色
            ctx.fillStyle='#E3E3E3' //设置字体颜色
            ctx.textAlign='center';//水平居中
            ctx.textBaseline = "middle"; //字体设置垂直居中
            ctx.font = "139px Georgia"; //设置字体size 风格
            ctx.fillText('签字区',622.5,232.5)//填充字体,x,y
        })
    },
    async commitOk(){
        console.log('触发了');
        let canvas=document.getElementById('canvas3') 
        var dataURL = canvas.toDataURL('image/jpeg');   
        //转成的二进制文件流
        console.log(this.dataURLtoBlob(dataURL))
        this.canvasLoading=true;
        let res=await uploadxxx({multipartFile:this.dataURLtoBlob(dataURL) })
        this.canvasLoading=false;
        console.log('upload上传成功');
        console.log(res); 
    },
    //重置canvas画板
    clearCanvas(){
        this.initCanvas();
    },
    commonResize(dBox,yPy){ 
        let canvas=document.getElementById('canvas3')  
        //获取canvas上下文对象
        var ctx=canvas.getContext('2d')//2d:图象 
        ctx.lineWidth=3;//设置线宽
        // ctx.strokeStyle='purple'//设置线的颜色
        var flag=false;
        //监听鼠标按下的时候执行重新绘制
        canvas.onmousedown=function(e){ 
            flag=true;
            ctx.beginPath();
        }
        
        var bodyTag=document.querySelector('body')
        bodyTag.offsetTop-20
        var x,y;
        //鼠标移入绘图
        canvas.onmousemove=function(e){
            if(!flag)return;
            // x=e.clientX-offsetX*3
            console.log(yPy); 
            x=e.offsetX 
            // y=e.pageY-offsetY
            y=e.clientY-yPy
            // console.log('我是y');
            // console.log(y);
            ctx.lineTo(x,y)//画点 clientX,clientY获取鼠标所在位置的x,y轴坐标
            // ctx.lineTo(e.offsetX,e.offsetY)//画点 clientX,clientY获取鼠标所在位置的x,y轴坐标
            ctx.stroke();//绘制线条
        }
        //鼠标松开停止绘图
        canvas.onmouseup=function(e){
            flag=false; 
        }
    },
    beginDialog(){ 
        var dBox=document.querySelector('.dialogSignature .el-dialog')
        var dBody=document.querySelector('body')
        var dialogSignatureTag=document.querySelector('.dialogSignature')  
        this.initCanvas();
        //203是canvas距离顶部的距离
        this.commonResize(dBox,203);
        var _this=this; 
        document.querySelector('.dialogSignature').onscroll=function(e){    
             
            var jqYdY=203;//最终需要减去的移动x轴
                
            if(dialogSignatureTag.scrollTop>0){ 
                //为甚是减去scrollTop由于滚动条向下滚动,canvas顶部距离顶部会缩小
                jqYdY=203-dialogSignatureTag.scrollTop
            }else{

            }
            _this.commonResize(dBox,jqYdY);
        }
    },
    createCanvas(){

    },
    //关闭dialog弹窗,这个是传给父级的可以忽略,正常设置visibleDialog为false即可
    close(){
        this.$emit('update:signatureVisible')
    }   
},

关键代码:

计算弹窗中的canvas距离顶部的距离,顶部距离又会受到,浏览器滚动的影响需要监听滚动事件

javascript 复制代码
document.querySelector('.dialogSignature').onscroll=function(e){    
             
    var jqYdY=203;//最终需要减去的移动x轴
        
    if(dialogSignatureTag.scrollTop>0){ 
        jqYdY=203-dialogSignatureTag.scrollTop
    }else{

    }
    _this.commonResize(dBox,jqYdY);
}

x轴只需要获取鼠标移入点的位置offsetX的距离即可

相关推荐
wuhen_n4 分钟前
JavaScript内存管理与执行上下文
前端·javascript
Hi_kenyon25 分钟前
理解vue中的ref
前端·javascript·vue.js
jin1233221 小时前
基于React Native鸿蒙跨平台地址管理是许多电商、外卖、物流等应用的重要功能模块,实现了地址的添加、编辑、删除和设置默认等功能
javascript·react native·react.js·ecmascript·harmonyos
2501_920931702 小时前
React Native鸿蒙跨平台医疗健康类的血压记录,包括收缩压、舒张压、心率、日期、时间、备注和状态
javascript·react native·react.js·ecmascript·harmonyos
落霞的思绪2 小时前
配置React和React-dom为CDN引入
前端·react.js·前端框架
Hacker_Z&Q2 小时前
CSS 笔记2 (属性)
前端·css·笔记
Anastasiozzzz2 小时前
LeetCode Hot100 295. 数据流的中位数 MedianFinder
java·服务器·前端
橙露3 小时前
React Hooks 深度解析:从基础使用到自定义 Hooks 的封装技巧
javascript·react.js·ecmascript
Exquisite.3 小时前
Nginx
服务器·前端·nginx
2501_920931703 小时前
React Native鸿蒙跨平台使用useState管理健康记录和过滤状态,支持多种健康数据类型(血压、体重等)并实现按类型过滤功能
javascript·react native·react.js·ecmascript·harmonyos