zoukankan      html  css  js  c++  java
  • html2canvas以及domtoimage的使用踩坑总结

    前言

    首先做个自我介绍,我是成都某企业的一名刚刚入行约一年的前端,在之前的开发过程中,遇到了问题,也解决了问题,
    但是在下一次解决相同问题的时候,只对这个问题有一丝丝的印象,还需要从新去查找,于是,我注册了segmemtfault,
    便于搜集我的问题总结,以及将踩坑经验分享给每一个开发人员,好了,闲话不多说。

    需求

    需求:要求能够实现根据后端返回的数据生成一张image,便于用户将图片分享到朋友或者朋友圈,取得用户的关注。

    开始踩坑

    一.html2canvas对于跨域图片,转换的时候会将跨域图片识别为空白。
    问题分析:
    既然是由于跨域引起的问题,那我们让资源不跨域不就可以访问了吗?
    解决办法:
    将图片放置服务器,通过nginx进行代理资源,前端访问图片便不涉及到跨域问题。

    二.html2canvas动态加载内容,通过canvas转换出来的数据,图片为空
    问题分析:
    内容是动态加载进来的,转换肯定是在请求完毕之后再去转换,但是在请求完毕之后去转换,按理说所需要的所有数据都已经到达前端,应该可以转换,经过思考,发现图片内容从后台读取需要一定时间去解析,才能够完整的将图片资源展示出来,html2canvas是将页面上显示的dom元素,经过解析将dom画在canvas上在转换为image图片格式。
    解决办法:
    1.让html2canvas转换代码等待一定时间,在进行转换操作,可进行转换。代码如下图所示

    clipboard.png

    2.当全部的图片数据都加载完毕之后,在执行转换操作。(本人建议第二种,更保险)

    clipboard.png

    三.html2canvas转换的base64位图不能被ios8以上版本所识别。会呈现出整个截图页面空白
    问题分析:
    这个问题的起因,应该是html2canvas对高版本的ios不支持(自我感觉),这个问题我很是头疼,当时根本没有对ios进行测试。客户使用的时候发现了这个问题,没法。想办法解决。百度说是由于ios不能识别base64的前缀,于是我试过将图片的前缀去除,但发现没反应。还是无用。思来想去感觉html2canvas坑太多了。填都填不完。于是。
    解决办法:
    我采用了另一款插件,dom-to-image,弄上去没有问题了。

    clipboard.png

    四.dom-to-image运用上去,在ios上能够出现内容了,但发现存在一个问题,部分图片内容,第一次进行公众号网页加载,没有正确显示,要在次进入才会显示,此bug同样是ios8以上版本
    问题分析:
    这一个问题我没有找到问题所在,一脸懵,不过最终还是得到了解决。
    解决办法:
    运用dom-to-imagede toSvg方式完美解决问题。

    clipboard.png

    五.离成功只有一步之遥了,使用了svg之后安卓手机不能将图片分享给朋友。识别不了
    问题分析:
    安卓能识别jpeg但不能识别svg矢量图片
    解决办法:
    自己手写咯。判断手机为安卓还是ios。

    clipboard.png

    六.所有的问题都已解决,我兴奋的跑去借了个果5,拿来测试,发现网页的背景图片不见了。
    问题分析:
    我长按两秒左右又是正常显示了,故图片是已经完美转换成功,可能是因为图片在转换过程中,没有完美适配到4.0寸的屏幕,
    解决办法:
    模拟长按事件,解决bug,这个方式可能不太好,但也是一种解决方式。

    总结

    躺过的坑都是我的经验,分享的同时我又加固了一遍。解决实际问题的思路,在过了一遍,对我帮助很棒。

    代码参考

    //判断手机为安卓还是ios  安卓html2canvas方法  ios系统dom-to-image方法        
    $(".code").click(function() {
        var u = navigator.userAgent;
        var isiOS = !!u.match(/(i[^;]+;( U;)? CPU.+Mac OS X/);
        var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; //android终端
        if(isiOS) {
            window.location.href = "mycodeios.html"
        } else if(isAndroid) {
            window.location.href = "mycode.html"
        }
    })

    安卓html2canvas方法

    <!DOCTYPE html>
    <html lang="zh">
    
        <head>
            <meta charset="UTF-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <meta http-equiv="X-UA-Compatible" content="ie=edge" />
            <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
            <title>分享</title>
            <link rel="stylesheet" type="text/css" href="css/reset.css" />
            <style type="text/css">
                /*头部*/
                
                body {
                    background: #FFFFFF;
                    height: 0 !important;
                }
                
                .container {
                    max- 750px;
                    min- 32px;
                    margin: 0 auto;
                    background: #FFFFFF;
                }
                
                .zhe {
                    position: fixed;
                    max- 750px;
                    min- 32px;
                     100%;
                    height: 100%;
                    background: #45A196;
                    z-index: 9;
                }
                
                .imge {
                    position: absolute;
                    max- 750px;
                    min- 32px;
                     90%;
                    height: 100%;
                    margin: 0% 5%;
                    z-index: 99;
                    /*background: url(codeimg/code.jpg) no-repeat;*/
                    /*background-size: contain;*/
                }
                
                .left {
                    position: absolute;
                    left: 12%;
                    top: 70%;
                    color: #FFFFFF;
                    font-size: 26px;
                    letter-spacing: 5px;
                }
                
                .bottom {
                    position: absolute;
                    right: 38%;
                    top: 65%;
                }
                
                .codebotom {
                    position: absolute;
                    padding: 10px;
                    background: #FFFFFF;
                     90px;
                    height: 90px;
                }
                
                .butright_img {
                    position: absolute;
                     80px;
                    height: 80px;
                    margin: 5px;
                    top: 0px;
                    left: 0px;
                }
                
                .textbottom {
                    position: absolute;
                     40px;
                    letter-spacing: 5px;
                    color: #FFFFFF;
                    top: 20px;
                    left: -45px;
                }
                
                .butright {
                    position: absolute;
                    bottom: 50px;
                    right: 15%;
                    color: #4BA59B;
                    padding: 10px 20%;
                    border-radius: 3px;
                    z-index: 9999;
                    color: #ffffff;
                    text-align: center;
                }
                
                .image {
                    display: block;
                    max- 750px;
                    min- 32px;
                     100%;
                    position: absolute;
                    top: 0px;
                    left: 0px;
                    background: #FFFFFF;
                    z-index: 9999;
                }
            </style>
        </head>
    
        <body>
            <div class="container">
                <!--二维码-->
                <div class="zhe"></div>
                <div class="imge">
                    <div style="position: absolute; top: 0px; left: 0px;">
                        <img src="codeimg/code.jpg" />
                    </div>
                    <div style=" 100%;height: 100%; position: relative;">
                        <div class="left state"></div>
                        <div class="bottom">
                            <div class="textbottom">扫码立即注册</div>
                            <div class="codebotom">
                                <div id="qrcode" class="butright_img"></div>
                            </div>
                        </div>
                    </div>
                    <div>
                        <div class="butright">长按保存图片</div>
                    </div>
                </div>
                <div class="image" style="display: block;">
    
                </div>
    
            </div>
        </body>
        <script src="js/config.js"></script>
        <script src="js/jquery-2.1.4.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/fenxiang.js" type="text/javascript" charset="utf-8"></script>
        <script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
        <!--二维码-->
        <script src="js/jquery.qrcode.logo.min.js" type="text/javascript" charset="utf-8"></script>
        <!--html2canvas图片-->
        <script type="application/javascript" src="http://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
        <script type="text/javascript">
            //  倒计时  
            $(function() {
                var openid_list = eval(decodeURIComponent(localStorage.getItem("openid")))
                var openid = openid_list[1]
                var access_token = openid_list[0]
    
                window.history.pushState(null, null, "#");
                window.addEventListener('popstate', function(e) {
                    window.location.href = 'my.html'
                }, false);
    
                //创建二维码
                function createQRCode(id, url, width, height, src) {
                    $('#' + id).empty();
                    jQuery('#' + id).qrcode({
                        render: 'canvas',
                        text: url,
                         width, //二维码的宽度  
                        height: height, //二维码的高度  
                        imgWidth: width / 6, //图片宽
                        imgHeight: height / 6, //图片高
                        src: src //图片中央的二维码
                    });
                }
                var url = 'https://api.gzkny.com/h5/aa.html?openid=' + openid;
                createQRCode("qrcode", url, 80, 80, "image/follow.jpg");
    
                // 使用html2canvas 转换html为canvas 安卓html2canvas方法
                function downloadForJS() {   
                    html2canvas(document.body, {
                        useCORS: true,
                        logging: true
                    }).then(function(canvas) {
                        var imgUri = canvas.toDataURL().replace("image/png", "image/octet-stream"); // 获取生成的图片的url  
                        //    $('.zhe').hide()
                        //    $('.imge').hide()
                        $('.image').html('<img src="' + imgUri + '"/>')
                    });
                }
    
                // 获取数据
                $.ajax({
                    method: 'GET',
                    url: window.BASE_URL + 'api/v1/member/get',
                    contentType: 'application/x-www-form-urlencoded',
                    async: true,
                    dataType: "json",
                    data: {
                        access_token: access_token,
                    },
                    success: function(data) {
                        console.log(data)
                        if(data.error == 'success') {
                            $('.state').html(data.data.username)
                            downloadForJS()
                        }
                    }
                });
    
            })
        </script>
    
    </html>

    ios系统dom-to-image方法(css样式一定要自己写   避免图片失效)

    <!DOCTYPE html>
    <html lang="zh">
    
        <head>
            <meta charset="UTF-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <meta http-equiv="X-UA-Compatible" content="ie=edge" />
            <title>分享</title>
            <script src="js/jquery-2.1.4.min.js" type="text/javascript" charset="utf-8"></script>
            <script type="text/javascript" src="js/dom-to-image.js"></script>
            <script type="text/javascript" src="js/FileSaver.js"></script>
            <style type="text/css">
                /*头部*/
                * {
                    margin: 0px;
                    padding: 0px;
                }
                
                body {
                    background: #45A196;
                     100%;
                    height: 100%;
                }
                
                .container {
                    max- 750px;
                    min- 32px;
                    margin: 0 auto;
                    position: relative;
                }
                
                .imge {
                    position: relative;
                    max- 750px;
                    min- 32px;
                     100%;
                    height: 100%;
                    z-index: 99;
                }
                
                .left {
                    position: absolute;
                    left: 12%;
                    margin-top: 116%;
                    color: #FFFFFF;
                    font-size: 26px;
                    letter-spacing: 5px;
                }
                
                .bottom {
                    position: absolute;
                }
                
                .codebotom {
                    position: absolute;
                    background: #FFFFFF;
                     90px;
                    height: 90px;
                }
                
                .butright_img {
                    position: absolute;
                     80px;
                    height: 80px;
                    margin: 5px;
                    top: 0px;
                    left: 0px;
                }
                
                .textbottom {
                    position: absolute;
                     50px;
                    letter-spacing: 5px;
                    color: #FFFFFF;
                    top: 15px;
                    left: -45px;
                }
                
                .butright {
                    position: fixed;
                    bottom: 0px;
                    right: 40%;
                    z-index: 9999;
                    color: #ffffff;
                }
                
                .image {
                    display: block;
                    max- 750px;
                    min- 32px;
                     100%;
                    position: absolute;
                    top: 0px;
                    left: 0px;
                    background: #FFFFFF;
                    z-index: 9999;
                }
            </style>
        </head>
    
        <body>
            <div id="container">
                <div class="container">
                    <div class="imge">
                        <img style=" 100% ; position: absolute;" src="codeimg/code.jpg" />
                        <div class="left state"></div>
                        <div style=" position: absolute;right: 38%; margin-top: 110%;">
                            <div class="bottom">
                                <div class="textbottom">扫码立即注册</div>
                                <div class="codebotom">
                                    <div id="qrcode" class="butright_img"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="butright">长按保存图片</div>
            </div>
            <div class="bot" style="position: fixed; z-index: 9999999999999999; background: #4BA59B;"></div>
    
        </body>
        <!--二维码-->
        <script src="js/jquery.qrcode.logo.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/config.js"></script>
        <script type="text/javascript">
            $(function() {
                var openid_list = eval(decodeURIComponent(localStorage.getItem("openid")))
                var openid = openid_list[1]
                var access_token = openid_list[0]
    
                window.history.pushState(null, null, "#");
                window.addEventListener('popstate', function(e) {
                    window.location.href = 'my.html'
                }, false);
    
                //创建二维码
                function createQRCode(id, url, width, height, src) {
                    $('#' + id).empty();
                    jQuery('#' + id).qrcode({
                        render: 'canvas',
                        text: url,
                         width, //二维码的宽度  
                        height: height, //二维码的高度  
                        imgWidth: width / 6, //图片宽
                        imgHeight: height / 6, //图片高
                        src: src //图片中央的二维码
                    });
                }
                var url = 'https://api.gzkny.com/h5/aa.html?openid=' + openid;
                createQRCode("qrcode", url, 80, 80, "image/follow.jpg");
    
                //            ios系统dom-to-image方法    
                function downloadForJS() {
                    domtoimage.toSvg(document.getElementById('container'))
                        .then(function(dataUrl) {
                            /* do something */
                            var img = new Image();
                            img.src = dataUrl;
                            $('.container').hide()
                            //    console.log(dataUrl)
                            //    document.body.appendChild(img);
                            $('.bot').html(img)
                        });
                }
    
                //    禁止屏幕滑动
                function bodyScroll(event) {
                    event.preventDefault();
                }
                document.body.addEventListener('touchmove', bodyScroll, false);
                $('body').css({
                    'position': 'fixed',
                    "width": "100%"
                });
    
                //  获取数据
                $.ajax({
                    method: 'GET',
                    url: window.BASE_URL + 'api/v1/member/get',
                    contentType: 'application/x-www-form-urlencoded',
                    async: true,
                    dataType: "json",
                    data: {
                        access_token: access_token,
                    },
                    success: function(data) {
                        console.log(data)
                        if(data.error == 'success') {
                            $('.state').html(data.data.username)
                            downloadForJS()
                        }
                    }
                });
    
            })
        </script>
    
    </html>
  • 相关阅读:
    tornado中form表单验证详解
    关于tornado中session的总结
    Linux常用命令
    css3动画属性详解 与超酷例子
    keepalive高可用的健康检查
    keepalive的nginx防火墙问题
    安装配置hadoop
    tmux的简单快捷键
    部署使用elk
    k8s搭建部署
  • 原文地址:https://www.cnblogs.com/lipengze/p/11512039.html
Copyright © 2011-2022 走看看