记录一篇html2canvas截图的踩坑之旅

7,259 阅读1分钟

准备过年之际来活了,生成的效果图是这样的,相片在外相册之下,相片支持拖动和缩放

生成海报以后是这样的

1.html2canvas的截图功能不全问题

           window.pageYoffset = 0;
           document.documentElement.scrollTop = 0;
           document.body.scrollTop = 0;
           var scaleBy = window.devicePixelRatio;
                html2canvas(
                   document.getElementById('photo'),
                   {   
                       width:this.clientWidth, // canvas宽度
                       height:this.clientWidth*2.16,
                       backgroundColor:null,//画出来的图片有白色的边框,不要可设置背景为透明色(null)
                       useCORS: true,//支持图片跨域
                       scale:scaleBy,//设置放大的倍数
                       dpi: 300, // 处理模糊问题
                       x: 0, //x坐标

                       y: 0, //y坐标
                   //    height: document.getElementById('photo').scrollHeight,
                   //     windowHeight: document.getElementById('photo').scrollHeight
                   }
               ).then(canvas => {
                   //截图用img元素承装,显示在页面的上
                   let img = new Image();
                   let res = canvas.toDataURL('image/jpeg',1.0);// toDataURL :图片格base64
                   this.url=res;
                  
               })

1.如果页面存在滚动条,滚动在最顶部截取图片没有什么问题,一但不再底部就会造成截取不全,滚动条滚动的位置之上时黑色的,解决办法就是让滚动条置顶:

 window.pageYoffset = 0;
 document.documentElement.scrollTop = 0;
 document.body.scrollTop = 0;

2.我也找了别的方法,在html2canvas中配置参数,发现没生效,不知道是不是我写法的问题

height: document.getElementById('photo').scrollHeight,
windowHeight: document.getElementById('photo').scrollHeight

2.html2canvas的截图模糊问题

1.首先这个显示的图片要等比缩放,宽缩放到窗口的宽度的0.62倍,这个根据你么的需求,高除了缩放0.62还要乘以海截图海报的 height/width的比值

  let clientWidth=document.documentElement.clientWidth,//窗口的宽度
<img :src="url" alt="" ref='createImg' :style="{width: clientWidth*0.62+'px',height: clientWidth*2.16*0.62+'px'}">

2.除此之外要设置html2canvas中配置参数的scale,设置dpi根本没效果,这个scale的值window.devicePixelRatio,截图模糊问题完美解决

3.上传图片获取实际宽度问题

       getFile(e){
            this.$toast.loading({
            message: '上传中...',
            forbidClick: true,
            loadingType: 'spinner',
            });
              let _this=this;
              lrz(e.target.files[0], {
                     width : 1000
              //quality: 0.8    //自定义使用压缩方式
            })  
            .then(function(res) {
                _this.$toast.clear();
                     _this.photoUrl=res.base64;
                     _this.userPic=res.base64;
                    let imgSrc = res.base64;
                    let img = new Image();
                    img.src = imgSrc;
                    img.onload = function () {
                        if(img.width<=img.height){
                            _this.$refs['dragImg'].style.height = 				                                        360*img.height/img.width+'px';
                            _this.$refs['dragImg'].style.width = 360+'px';
                            }
                            else{
                            _this.$refs['dragImg'].style.height =img.height+'px';
                            _this.$refs['dragImg'].style.width = img.width+'px';          
                        }
                        
                    }

                //成功时执行
            }).catch(function(error) {
                //失败时执行
            }).always(function() {
                //不管成功或失败,都会执行
            })
            
        },

1.获取图片的宽高,要在图片的onload的事件中获取,然后根据需求等比缩放 2.在上传之前一定一定要压缩图片的大小,你上传一个10几兆的图片直接能托死微信的浏览器,我要关机从启才可以,用lrz 压缩,非常好用,返回的是base64格式,可以直接显示在页面上,不用再去转file文件的实际路径。

巧用vue的事件代理

其实我的相框是在图片之上的,相框浮动在在最上层,但是你要拖动图片就要用到事件代理,代理到父节点,甚至是兄弟节点上,这个问提酒可以解决了

 <section>
                <!-------------------------------- 相框背景图-------------- -->
                <div class="bg" id='bg'>
                    <img :src="imgSrc" id='defaultImg' alt="" :onerror='defaultImg'/>
                </div>
                <!-- ------------------------人体照片------- ------------------>
                <div class="person" id="person">
                    <img :src="photoUrl"  ref="dragImg" title='photo' id='dragImg' :style="styleObj"/>           
                </div>
            </section>

            <section class="test"  @touchstart="touchstartHandle('dragImg',$event)"
                 @touchmove="touchmoveHandle('dragImg',$event)">
            </section>