html图⽚的功能,[学习笔记]使⽤HTML实现截图
HTML截图-html2canvas使⽤记录
前⾔
最近项⽬需求总是有HTML页⾯⽣成图⽚功能,所以就想记录⼀下⾃⼰在过程中遇到的问题,并加深印象,⽇后如果忘了也可以回顾。我们项⽬使⽤的是html2canvas插件,还有其他插件,例如dom-to-image、rasterizehtml,可以根据需求使⽤。
html2canvas使⽤问题汇总
项⽬中引⼊的是0.5.0-beta4版本的cdn链接,直接调⽤⽅法html2canvas(dom,options);第⼀个参数是你要绘制的dom对象,第⼆个参数是⼀些绘制的配置参数,个别参数我尝试了也没搞清楚具体什么作⽤可以⾃⾏看html2canvas⽂档,对于我⽤到的直接上代码:
// ⽣成图⽚
function generateImg() {
var shareContent = document.body;// 需要绘制的部分的 (原⽣)dom 对象 ,注意容器的宽度不要使⽤百分⽐,使⽤固定宽度,避免缩放问题
var width = shareContent.offsetWidth; // 获取(原⽣)dom 宽度
var height = shareContent.offsetHeight;
var offsetTop = shareContent.offsetTop; //元素距离顶部的偏移量
// var rect = BoundingClientRect();
var canvas = ateElement('canvas'); //创建canvas 对象
var context = Context('2d');
var scaleBy = 3; //像素密度 (也可以采⽤⾃定义缩放⽐例)
canvas.width = width * scaleBy; //这⾥ 由于绘制的dom 为固定宽度,居中,所以没有偏移
canvas.height = (height + offsetTop) * scaleBy; // 注意⾼度问题,由于顶部有个距离所以要加上顶部的距离,解决图像⾼度偏移问题
canvas.height = height * scaleBy;
// anslate(0, -offsetTop); // 画布偏移
context.scale(scaleBy, scaleBy);
html2canvas(shareContent, {
logging: true, // 是否打印⽇志,默认false
taintTest: true, //检测每张图⽚都已经加载完成
scale: scaleBy, // 添加的scale 参数
canvas: canvas, //⾃定义 canvas
青春记忆width: width, //dom 原始宽度
height: height, //dom 原始⾼度
春节调休2021安排
useCORS: true, //允许跨域
onrendered: function(canvas) { // 页⾯绘制成功后的回调
var url = DataURL("image/png");
// ⽣成图⽚后的操作
}
});
}
复制代码
图⽚模糊解决
由于像素⽐(DPR = 设备像素/CSS像素)的问题,电脑上截图看着还⾏,到⼿机上就会⾮常模糊。绘制图⽚时可以根据像素⽐把图⽚放⼤,使⽤时在定义图⽚的宽度,也可以⾃定义缩放⽐。缩放⽐也不是越⼤越好,太⼤了也可能会出问题。计算像素⽐的代码:
function getPixelRatio(context){
var backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
return (window.devicePixelRatio || 1) / backingStore;
}
复制代码绘图时尽量不要使⽤背景图⽚,直接使⽤img这样会更清晰
图⽚跨域问题
纯黑图有次页⾯中使⽤了头像,设置了useCORS: true不能显⽰头像,设置allowTaint:true直接报错不能使⽤toDataURL可能⽆法导出受污染的画布;最后只有百度了
修改Nginx配置⽂件,由于我们项⽬其他地⽅也⽤到了,所以不便修改,可以修改的参考:
location ^~ /wechat_image/ {
add_header 'Access-Control-Allow-Origin' "$http_origin" always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always;
对号
add_header 'Access-Control-Allow-Headers' 'Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Requested-With' always;
}
复制代码把图⽚转换成base64格式并设置CrossOrigin="anonymous",尝试后有缓存的情况下还是不能正常⽣成图⽚,需要在后⾯拼接⼀个随机参数解决缓存问题,Android可以了,但ios上还是不⾏。
后来发现直接在头像的img标签上设置CrossOrigin="anonymous"即,头像的请求头来就有access-control-allow-origin: *,Android和ios上都可以了,如果你之前尝试过其他⽅法,可能需要清下缓存,不然Android会误导你不能正常显⽰。
最近⼜发现⼀个html2canvas的options⾥配置proxy为跨域的url。
⽣成图⽚替换页⾯时闪现问题
前⾯⼏次⽣成图⽚,都没有出现这个问题,最近⼀次出现了替换时页⾯⼀闪,以为是不是图⽚太⼤了,我将两个活动的图⽚保存对⽐并不是,具体我还是没搞清楚,不过通过先在dom中写⼀个空的img标签然后⽣成的src替换给img,判断图⽚加载完成后再将绘制的dom隐藏掉解决了这个问题。
css样式超出显⽰省略号消失
html2canvas不⽀持css样式⽣成省略号,百度到了解决⽅法,通过js判断超过⽗盒⼦⾼度时⽤省略号替换
$(".info_text_box").each(function () {
var divH = $(this).height();
var $p = $("p", $(this)).eq(0);
while ($p.outerHeight() > divH) {
$p.html($p.html().replace(/(\s)*([a-zA-Z0-9]+|\W)(\.\.\.)?$/, "..."));
};
});
复制代码
引⼊web字体时字体还没有显⽰就⽣成图⽚
window.οnlοad=function(){}是等页⾯资源加载完毕再执⾏,但是在ios中并不⽀持,后来发现当字体⼤⼩⼤于300px时不同字体的宽度差别很⼤,就通过定时器判断字体⼤⼩来判断字体是否加载成功,但最总因为字体⽂件加载太慢,就放弃了使⽤特殊字体
// 通过判断字体内容宽度判断字体加载完成
function fn_fontWatch(fontFamily, cb) {
function fn_gen_span_with_font(font) {
var ateElement('span');
span.style.cssText = "display:block;position:absolute;top:-9999px;left:-9999px;font-size:300px;width:auto;height:auto;line-height:normal;margin:0;padding:0;font-variant:normal;white-space:nowrap;font-family:" + font;
span.innerHTML = 'BESbswy';
document.body.append(span);
return span;
};
var span_default = fn_gen_span_with_font('serif');
var span_default_width = span_default.offsetWidth;
veChild(span_default);放荡的欲望
var span_font = fn_gen_span_with_font(fontFamily + ',serif');
var fn_check_loop = function() {
if(span_default_width !== span_font.offsetWidth){
veChild(span_font);
cb();
} else {
window.setTimeout(fn_check_loop,500);
}
};
fn_check_loop();
};
复制代码
其他问题
澳门语言
⼀次活动需要判断进⼊页⾯次序,html2canvas是通过遍历dom绘制图⽚的,当⽣成图⽚时除了js都会重新执⾏⼀次,导致类似刷新页⾯记录次序,最后次序通过ajax请求获取解决了问题;
html2canvas只会截取页⾯中可见的内容,设置了display: none、visibility:hidden的元素是截取不到的
⽣成图⽚时⽂字有些许变化,⽐如安卓的数字1就变化特别明显,⽽且⽂字的位置有点下移,原因我没到,影响不⼤,⽬前我也没解决;
最后
这些就是我在使⽤中遇到的问题以及解决⽅法,新⼿⼀枚,有错误请多多指教。