html2canvas踩坑记

前端程序员墓志铭:永远不要使用Alpha版的插件

最近写一个活动项目需要将一个HTML页面转为图片,之前一直是后台采用拼接的方式完成,然而现在遇到一个问题,Java拼接的HTML在生成图片时由于里面的文字太长没法自动换行,想使用css的强制换行

#wrap{word-break:break-all; width:200px;}
或者
#wrap{word-wrap:break-word; width:200px;}
<div id="wrap">abcdefghijklmnabcdefghijklmnabcdefghijklmn111111111</div>

均没有实现想要的换行效果,不知道有没有哪位朋友遇到过类似的情况,欢迎分享一下.
总之我使用css是没有走通,于是选择使用html2canvas.js这个插件在前端生成图片.
在介绍这个插件前先科普一下软件的版本号.

Alpha:是内部测试版,一般不向外部发布,会有很多Bug.一般只有测试人员使用。
Beta:也是测试版,这个阶段的版本会一直加入新的功能。在Alpha版之后推出。
α、β、λ常用来表示软件测试过程中的三个阶段,α是第一阶段,一般只供内部测试使用;β是第二个阶段,已经消除了软件中大部分的不完善之处,但仍有可能还存在缺陷和漏洞,一般只提供给特定的用户群来测试使用;λ是第三个阶段,此时产品已经相当成熟,只需在个别地方再做进一步的优化处理即可上市发行。 

这款插件最坑的地方就是将Alpha版放了出来,而我刚好就选择了最新的版本

踩坑版本

以后使用插件就应该看官网demo引入哪个版本的插件我们就使用哪个,要不这坑进去了真的很难出来.

行了,废话不多说了,直接进入正题

使用哪种语法

首先我们整体了解一下html2canvas.js这个插件,大家可以到官网上查阅文档
http://html2canvas.hertzen.com/documentation.html
或者参阅这篇文章
http://www.jianshu.com/p/6a07e974a7e8

引入html2canvas.js文件,我这里使用的是0.4.1版本(从1.0版降下来的),
上面两个链接分别对应两种语法格式

html2canvas(document.getElementById('id'))
.then(function(canvas) {document.body.appendChild(canvas);});

但是我在使用这种语法报错,然后参考官网的文档写法

html2canvas(document.getElementById("target"), {
  allowTaint: true, //允许污染
  taintTest: true, //在渲染前测试图片(没整明白有啥用)
  useCORS: true, //使用跨域(当allowTaint为true时这段代码没什么用,下面解释)
  background: "#fff",
  onrendered: function (canvas) {
    imgBlob = canvas.toDataURL('image/jpeg', 1.0); //将图片转为base64
    imgBlob = imgBlob.toString().substring(imgBlob.indexOf(",") + 1);//截取base64以便上传
  }
});

有关允许canvas污染的问题可以参考此文
https://developer.mozilla.org/zh-CN/docs/Web/HTML/CORS_enabled_image

其实这里的代码很好理解,传参数进去,剩下的就交给插件去完成,我们只要拿到base64流就可以了.
上文中说useCORS没有起作用我们看看源码就明白为什么没起作用了

...
} else if ( isSameOrigin( src ) || options.allowTaint ===  true ) {
  ...
} else if ( supportCORS && !options.allowTaint && options.useCORS ) {
  ...
};
 ...

这里我们看到这两个判断是互相矛盾的options.allowTaint为true那么!options.allowTaint永远为false

allowTaint该设置成true还是false

allowTaint

点击查看

因为allowTaint表示是否允许被污染,而被污染的canvas是没法使用toDataURL()base64流的,但是我们这需要base64,所有allowTaint需要被设置为false
当设置为true时,会报这样的错误

Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
    at Object.onrendered (http://127.0.0.1:8080/:142:32)
    at Object.options.complete (http://127.0.0.1:8080/js/html2canvas.js:2711:15)
    at start (http://127.0.0.1:8080/js/html2canvas.js:2215:17)
    at Image.img.onload (http://127.0.0.1:8080/js/html2canvas.js:2352:7)

useCORS是干嘛的

useCORSfalse时我们发现

看到了希望

这是什么鬼?图片去哪了?不过已经有突破了,图片出来了,现在我们需要找到图片不加载的问题
我们把useCORS设置成true时是什么效果呢?
然鹅效果还是和上图一样,但是这次控制台出现了错误

Access to Image at 'http://web.rrzuzu.com/WebStatic/rry-activity/target/images/bj.jpg' from origin 'http://127.0.0.1:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8080' is therefore not allowed access.
...

由于公司里面将图片资源放在OSS里,这里涉及到跨域的问题造成图片没法加载,好了,找到问题的所在我们就能很快的解决了,将资源放到同一域名下(OSS设置允许跨域不知道能不能解决,后期会再次尝试一下)
再来看看解决后的效果


这里写图片描述

哈哈,大功告成!
哦,对了,关于布局的坑我还得提议下

布局

布局一开始想到的是使用display: none让元素隐藏,当使用这种方法后发现生成的什么也没有.
没办法,使用position: absolute让元素跑到视野之外总行了吧top: -9999px;

image.png

纳尼,一片漆黑,查了些资料发现生成视野内图片,那么top: 9999px行不行?事实证明是可以的,这样设置总感觉心理不踏实,万一body的高度为100000px怎么办?接着有尝试使用left和right,均没什么卵用,这时想到使用图层高度,OK,那就试试吧,top: 0px; z-index: -1;完美解决
等等,我们现在只是在模拟器里面测试,还没有在真机上测试,当在真机上看到的效果时我的内心是崩溃的,手机不支持overflow: hidden;属性WTF,还得想办法此时查到了一些资料:

禁止蒙层底部页面跟随滚动http://mp.weixin.qq.com/s/704rUV3U0BwQuVea1Iwe4Q

最简单的方法时使用position: fixed;这方法很好,解决了下层页面没被隐藏和软键盘弹出后页面的问题,然而生成的图片没法显示,依旧是一片漆黑,总之试了很多次,只要在body使用fixed就别想生成图片,最后发现只用css是没法实现的了,于是结合js一起操作
最后使用fixed操作同级的container让其在软件盘弹出或消失的时候始终将元素保持bottom: 0;,再让页面没法滚动

$('.container')[0].addEventListener('touchmove', e => {
    e.preventDefault()
}, false)

总结一句需要生成的元素得在fixed的上层,并且不能让页面滚动
至此,功能算是完成了,改踩的坑也踩得差不多了,以后遇到问题再继续更新

小插曲

当时我在生成图片的时候获取了返回的图片地址,但是有时候服务器并没有返回图片地址,而我需要将图片地址传递到另外的一个页面,所以需要判断一下,在有地址的时候再执行ajax传递并跳转

success: function (res) {
  imgUrl = res;
  //提交表单
  if (imgUrl) {
    $(".form").ajaxSubmit({
      ...
      success: function (data) {
        if (data.code == 12000) {
          debugger;
          window.location.href = "http://wx.pingpingapp.com/activitymanage/pic#" + imgUrl;
        }
      }
    });
  }
 }

如果有朋友对html2canvas.js有兴趣,想查看我的项目源码的可以到github上拉取,如果大家对此插件有更深刻的理解欢迎留言

最后再多说一句:人人摇是个啥?扫码你就知道啦

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,597评论 18 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,457评论 25 707
  • 点击查看原文 Web SDK 开发手册 SDK 概述 网易云信 SDK 为 Web 应用提供一个完善的 IM 系统...
    layjoy阅读 13,662评论 0 15
  • 问题:关于财富方面的匮乏意识引发的恐惧怎么办? 温雅解答:刚才有咨询我的家人问到。我以文字发在群里方便大家看:匮乏...
    温雅老师阅读 666评论 0 1
  • 文/七毛是我 <一> 小四爷是我爸的亲弟弟,老家那边叫“爷”不叫“叔”,他排行老四,又是最小的儿子,所以我们都叫他...
    七毛是我阅读 3,313评论 34 84