本次作h5 活动,遇到一个需求,点击button 把html 生成图片,长按保存功能 因为html的结构比较复杂,使用canvas 直接画相对来讲增长了不小工做量,因此使用html2canvas ,html2canvas的使用比较简单,可是坑也不少css
谈到跨域问题,应该只要入了canvas toDataURL 转成图片的坑就应该遇到过这个问题,若是不进行跨域处理生成图片不能跨域的图片会空白处理 这个没有好的解决方案, 图片服务器须要配置Access-Control-Allow-Origin 因为公司的开发build 与 js 是两个团队在作,build 团队的图片地址都是不可跨域的,并且页面因此的图片设置都是background image 的形式,针对这个问题我作了以下处理html
固然这样尚未结束,配置html2canvasvue
html2canvas(dom, {
backgroundColor: null,
canvas,
//allowTaint: true,
useCORS: true
})
复制代码
useCORS 设置容许跨域,特别提醒 allowTaint 也是容许跨域,可是这个容许跨域只是容许你跨域生成canvas ,可是仍是不能把canvas转化成图片,要想解决toDataURL 的跨域问题,还须要使用useCORS。可是这两个属性不能共生web
把scale 设置成二倍直接上代码算法
* 根据window.devicePixelRatio获取像素比
*/
function DPR() {
if (window.devicePixelRatio && window.devicePixelRatio > 1) {
return window.devicePixelRatio;
}
return 1;
}
.....
// DOM 节点计算后宽高
const width = parseValue(box.width);
const height = parseValue(box.height);
// 获取像素比
const scaleBy = DPR()*2;
// 建立自定义 canvas 元素
var canvas = document.createElement('canvas');
// 设定 canvas 元素属性宽高为 DOM 节点宽高 * 像素比
canvas.width = width * scaleBy;
canvas.height = height * scaleBy;
// 设定 canvas css宽高为 DOM 节点宽高
canvas.style.width = `${width}px`;
canvas.style.height = `${height}px`;
// 获取画笔
const context = canvas.getContext('2d');
// 将全部绘制内容放大像素比倍
context.scale(scaleBy, scaleBy);
// imageSmoothingEnabled Canvas 2D API 用来设置图片是否平滑的属性,true表示图片平滑(默认值),false表示图片不平滑,默认的改变大小的算法会形成图片模糊而且破坏图片原有的像素。 若是那样的话,设置属性值为false。
context.mozImageSmoothingEnabled = false;
context.webkitImageSmoothingEnabled = false;
context.msImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
.....
html2canvas(dom, {
backgroundColor: null,
canvas,
width: width, // 设置width
height: height, // 设置height
scale: scaleBy,// 设置scaleBy
useCORS: true
})
复制代码
过程当中使用的雪碧图最容易出现模糊的状况,因此图片须要使用2倍图canvas
可能这个题目不是很好的描述问题。我先描述一下问题所在,因为html2canvas 生成图片所在的html 必须是真实存在的,不然生成canvas为空白。也就是须要生成html不能设置 disabled: none; visibility: hidden; 等属性。 所以代表在调用html2canvas 生成canvas 过程当中必须dom 节点渲染完成。所以这就会致使在生成canvas 会出现原有html 的闪现 这个问题其实也比较好解决,用了一个小技巧,使用top 属性,把html 移除视野 top:100%
固然这个解决方案比较多,目前我用的是这个跨域
这个问题,自己须要生成的html 中有一部分是轮播图,这样html dom 会动态渲染, 解决方案很简单,取消轮播图,直接用 v-if(注:工程使用vue 开发)断定进行html 渲染,取消轮播bash
这个问题我也没找到缘由,结果就是虽然设置了background-repeat: no-repeat; 可是图片底部会出现大约1像素的重复。 因为没有找到根本缘由,使用了最直接的的方案解决,直接把图片高度增长2像素,成功避免了这个问题。(哈哈哈哈,我真是一个投机取巧的鬼才)服务器
因为代码中有段文字须要多行末尾省略号,因此出现以下cssdom
display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
复制代码
在html2canvas中,会将css中的display中的值映射成一个数字,而在下图的映射表中,只要找到了flex的映射值,并无--webkit-flex的映射值,因此-webkit-flex被映射成了DISPLAY.NONE,从而致使了isVisible的计算值返回了false,最终致使了没法生成想要的canvas
解决方案不使用flex布局,js 实现文字溢出,此方案仅限于文字个数具体的状况下,因此比较局限,你们有好的方案欢迎补充 css
height:2倍的line-height; /*根据实际需求更改*/
display:inline-block;
复制代码
js
contentText(num){
const ellipsis = oldContentText.length > num?'...':''
return oldContentText.slice(0,num) + ellipsis
}
复制代码