html2canvas踩坑日记

近日要开发一个能将生成的二维码另存为图片的功能(该图片呢,肯定不止一个二维码,还包括背景、文字等其他元素),首先呢,就想到了html2canvas,随便一百度就是各种踩坑日志,我也随一下大流,记录本人在开发过程中遇到的坑。

1.基本用法:

在html2canvas上找到了它的基本用法以及压缩包

<div id="capture" style="padding: 10px; background: #f5da55">
    <h4 style="color: #000; ">Hello world!</h4>
</div>

html2canvas(document.querySelector("#capture")).then(canvas => {
    document.body.appendChild(canvas)
});

还搜索到了另外一种用法:http://caibaojian.com/html2canvas.html

html2canvas(document.body, {
  onrendered: function(canvas) {
    var url = canvas.toDataURL();//图片地址
    document.body.appendChild(canvas);
  },
  width: 300,
  height: 300
});

坑1:

由于项目要兼容到ie8,前者还用到了promise,我想在ie里面不能完全兼容啊,所以当即就用后者来测试了一下,奇怪的是我的onrendered方法为什么不执行,看了一下html结构,好么,画的canvas闪现了一下就没了,没了,什么情况,我有点懵,是不是因为我的压缩包用得不对,然后我就去找另外版本的js,在这个网址终于找到了我想要的版本https://www.bootcdn.cn/html2canvas/(之前用的官网的1.0.0-rc.5,换了0.5.0-beta4的版本),改了压缩包之后,我的图片愉快的被生成了。

坑2:

但是在ie10下还是出现了问题,说是promise未定义,那就想办法让它支持该语法呗,然后就搜到了引用bluebird.js可以使ie支持promise的语法,把该js用上之后终于不报错了。

2.下载

html2canvas(document.getElementById(‘buildImg‘), {
    onrendered: function(canvas) {
        var url = canvas.toDataURL();
        if (window.navigator && window.navigator.msSaveOrOpenBlob) {
             var bstr = atob(url.split(‘,‘)[1]) //atob与blob都是支持ie10+
             var n = bstr.length
             var u8arr = new Uint8Array(n)
             while (n--) {
                 u8arr[n] = bstr.charCodeAt(n)
             }
             var blob = new Blob([u8arr])
             window.navigator.msSaveOrOpenBlob(blob, ‘图片下载.png‘);
                  return;
         }var a = document.createElement("a");
         a.href = url;
         a.download = "图片下载";
         document.body.appendChild(a);
         a.click();
         document.body.removeChild(a);
    }
});

上面的代码在谷歌与ie10都可以下载,但是ie9怎么办呢,花了大半天时间也没有想到解决办法。然后业务又说想把下载做成可以选择磁盘保存的方式,即模拟右键另存为。后面试了一下,在ie下是可以的(谷歌不行),但是需要图片url,而生成的图片是base64啊,并没有链接,如果想转成url链接应该还需要后端支持。想来想去太麻烦了,又与业务商量了下,要不先把图片生成放在那里吧,然后自己手动去右键另存为,上面再给点提示,业务同意了,这里的坑算是过了,上面的方法舍弃。

//假装外面有个请求:if (data.type == "SUCCESS") {
    var url = ‘data:image/png;base64,‘+data.data.qrCode;
    $(‘#img‘).attr(‘src‘,url);
    $(‘.js-dialog‘).show();
    html2canvas(document.getElementById(‘buildImg‘), {
        onrendered: function(canvas) {        var url = canvas.toDataURL("image/png", 1.0);         $(‘#buildImg‘).html(‘<img src="‘+url+‘" width="100%;"/>‘)        }
    })
}

3.图片模糊

随后又发现在谷歌上生成的图片有点糊,看了网上一水的方法都是自定义canvas,那我就试试?

if (data.type == "SUCCESS") {
    var url = ‘data:image/png;base64,‘+data.data.qrCode;
    $(‘#img‘).attr(‘src‘,url);
    $(‘#copyLink‘).attr(‘data-clipboard-text‘,data.data.link);
    var canvas = document.createElement("canvas");
    var context = canvas.getContext("2d");
    var scale = 1;
    canvas.width = 320 * scale;
    canvas.height = 480 * scale;
    canvas.getContext("2d").scale(scale, scale);
    $(‘.js-dialog‘).show();
    html2canvas(document.getElementById(‘buildImg‘), {
        canvas: canvas, //自定义 canvas
        scale: scale,
        width:320,
        height:480,
        useCORS: true,     onrendered: function(canvas) {        var url = canvas.toDataURL("image/png", 1.0);         $(‘#buildImg‘).html(‘<img src="‘+url+‘" width="100%;"/>‘)        }
     })
}

随后我就发现生成的图片一片空白,我画的图去哪儿了?是不是onrendered又不生效了,之后我又用了promise语法

if (data.type == "SUCCESS") {
    var url = ‘data:image/png;base64,‘+data.data.qrCode;
    $(‘#img‘).attr(‘src‘,url);
    $(‘#copyLink‘).attr(‘data-clipboard-text‘,data.data.link);
    var canvas = document.createElement("canvas");
    var context = canvas.getContext("2d");
    var scale = 1;
    canvas.width = 320 * scale;
    canvas.height = 480 * scale;
    canvas.getContext("2d").scale(scale, scale);
    $(‘.js-dialog‘).show();
    html2canvas(document.getElementById(‘buildImg‘), {
        canvas: canvas, //自定义 canvas
        scale: scale,
        width:320,
        height:480,
        useCORS: true,
     }).then(function(canvas){
         var url = canvas.toDataURL("image/png", 1.0);
         $(‘#buildImg‘).html(‘<img src="‘+url+‘" width="100%;"/>‘)
     });
}

额额,还是不对,是不是我的压缩包没用对,然后又换成了官网上copy的版本1.0.0-rc.5。咦,好像可以了,图片也清晰了。转了一圈还是用了最开始的办法,真想甩自己两大巴子。

4.图片偏移

虽然图片清晰了,但是会有10-20px的横向偏移,ie下不但横向偏移还会纵向偏移,下面是解决办法:

if (data.type == "SUCCESS") {
    var url = ‘data:image/png;base64,‘+data.data.qrCode;
    $(‘#img‘).attr(‘src‘,url);
    $(‘#copyLink‘).attr(‘data-clipboard-text‘,data.data.link);
    var canvas = document.createElement("canvas");
    var context = canvas.getContext("2d");
    var scale = 1;
    canvas.width = 320 * scale;
    canvas.height = 480 * scale;
    canvas.getContext("2d").scale(scale, scale);
    if ((window.navigator && window.navigator.msSaveOrOpenBlob) || isIe){
       context.translate(-10,-20);
    }else{
       context.translate(-10,0);
    }
    $(‘.js-dialog‘).show();
    html2canvas(document.getElementById(‘buildImg‘), {
        canvas: canvas, //自定义 canvas
        scale: scale,
        width:320,
        height:480,
        useCORS: true,
     }).then(function(canvas){
         var url = canvas.toDataURL("image/png", 1.0);
         $(‘#buildImg‘).html(‘<img src="‘+url+‘" width="100%;"/>‘)
     });
}

以上就是本人在开发过程中遇到的坑,已经能完美兼容ie9+。

happy ending~~~

原文地址:https://www.cnblogs.com/myyouzi/p/12103326.html

时间: 2024-08-02 23:43:52

html2canvas踩坑日记的相关文章

SpringBoot踩坑日记-定时任务不定时了?

问题描述br/>springboot定时任务用起来大家应该都会用,加两注解,加点配置就可以运行.但是如果仅仅处在应用层面的话,有很多内在的问题开发中可能难以察觉.话不多说,我先用一种极度夸张的手法,描述一下遇到的一个问题.@Componentpublic class ScheduleTest {@Scheduled(initialDelay = 1000,fixedRate = 2*1000)public void test_a(){System.out.println("123"

米忽悠踩坑日记-1

米忽悠踩坑日记-1            --知不足,而后进 进入米哈游差不多一个半月了,就以刚刚上线的某个任务作为节点写一篇踩坑日记吧. 1.安全意识,尽量考虑到玩家各种奇奇怪怪的操作以及有可能想刷道具的行为. 2.日志方面,记录玩家的每一步操作,成功或者失败,需要记录清楚,uid,region以及其他的信息,如奖励的ID,更新一次游戏玩家数据也记录 3.在写代码时候不要总想着先实现逻辑再来优化结构,因为一个小任务的代码量不一定少,而且任务排的很紧,如果不从一开始就保持良好的结构自己看起来简直

vue 组件传值踩坑日记 1

今天在用平时很少用到的传值方式,是V2.4以后新加入属性$attrs $listener 以及inheritAttrs. 总结:这样形式的代码适合套娃模式的组件传递,却不适合兄弟组件的传值,那样的传值方式,需要创建一个事件总线,说白了就是新new一个空的vue,详见,我的第二篇日志<vue 组件传值踩坑日记 2> 废话不多说,直接上代码,大家可以边看注释边测试一下效果吧 <!DOCTYPE html> <html lang="en"> <hea

AI相关 TensorFlow -卷积神经网络 踩坑日记之一

上次写完粗浅的BP算法 介绍 本来应该继续把 卷积神经网络算法写一下的 但是最近一直在踩 TensorFlow的坑.所以就先跳过算法介绍直接来应用场景,原谅我吧. TensorFlow 介绍 TF是google开源出来的人工智能库,由python语言写的 官网地址:http://www.tensorflow.org/   请用科学上网访问 中文地址:http://www.tensorfly.cn/ 当然还有其他AI库,不过大多数都是由python 写的 .net 的AI库叫 Accord.net

人工智能(AI)库TensorFlow 踩坑日记之二

上次 踩坑日志之一 遗留的问题终于解决了,所以作者(也就是我)终于有脸出来写第二篇了. 首先还是贴上 卷积算法的示例代码地址 :https://github.com/tensorflow/models   这个库里面主要是一些常用的模型用tensorflow实现之后的代码.其中我用的是 models/tree/master/tutorials/image/cifar10 这个示例,上一篇也大致讲过了. 关于上次遇到问题是: 虽然训练了很多次,但是每次实际去用时都是相同的结果.这个问题主要原因是

quick-cocos2d-x 踩坑日记(一)------ NodeEx 与 shortcodes

今天在模仿一个demo,想自己去完善一些功能,自己写的时候就遇见了一个坑...先看代码: local label = cc.ui.UILabel.new({     UILabelType = 1,     text = "Max Score 10",     font = "fonts/font-issue1343.fnt",     x = boardSize.width / 2,     y = boardSize.height * 0.4,     }):a

cocos2dx 3.3rc0 踩坑日记(一)------ 弱联网 Curl

这两天看了视频学习了下弱联网技术,用的是Curl,具体使用方法我就多说了,可以参考官方样例和下面的文章,解释的很清楚. [Curl (libcurl) 开发 之一]Cocos2dx之libcurl(curl_easy)的编程教程(帮助手册)! CURL使用2 我要说的我又踩到一个坑...为什么是又呢...天生就是来踩坑的... 先说下使用之前需要加入curl.h的路径$(EngineRoot)external\curl\include\win32和链接库libcurl_imp.lib 如图所示:

cocos creator踩坑日记(持续更新中...)

踩坑一 问题:项目在构建成Web Mobile后运行在浏览器和微信中,点击页面任何地方都会导致自动全屏 解决:在构建之后的main.js中,去掉 cc.view.enableAutoFullScreen(true) 踩坑二 问题:精灵使用move to后路径上会留下一些线条 原因:脏矩形出问题了 解决: Canvas模式下才有脏矩形,使用这个方法之前要判断 if (cc._renderType === cc.game.RENDER_TYPE_CANVAS) { cc.renderer.enabl

quick cocos2dx 3.3rc1 踩坑日记(二)------ 声音引擎

昨天在群里有人说setSoundsVolume和setMusicVolume设置声音大小无效...我记得cocos2dx是没实现内容的,就贸贸然回答说,是这你的没用,但群里有人说是有用的,我就去虚心请教,大神人很好,回答了我很多问题,告诉我说实现了,而且是针对不同的平台.实现的文件位置,如下图: 我先测试setMusicVolume,在win32下setMusicVolume是无效的,在Android上是可以的. 但在测试setSoundsVolume时,就遇见问题了,当调用audio.play