最近在项目中用到了html2canvas插件,遇到的一些坑写下来,与大家共勉。

html2canvas  官方网站http://html2canvas.hertzen.com/index.html

这是一个js截屏插件,在前台利用h5的canvas  将html的内容显示在canvas上,再利用 js 将canvas转化为图片

1.vue 文件中引入 html2canvas.js

  <remote-script src="../html2canvas.js"></remote-script> 

说明:src中的路径是html2canvas.js在项目中的路径

remoteScript 标签是上篇博客定义的标签,详情见:http://www.cnblogs.com/zhuchenglin/p/7455203.html

2.在vue中使用该插件,在methods中定义一个方法,内容为:

 setTimeout(function () {
  html2canvas(dom,{
     onrendered:function (canvas) {
   var image = new Image();
   image.src = canvas.toDataURL();
   document.getElementById('content_img').appendChild(image)
   dom.style.display='none'
     },
  });
},0)
这样就可以了

说明:
在方法中如果不加 setTimeout函数的话,虽然使用console输出的dom内容正常,但是如果在vue中定义的变量中的内容在canvas中显示不出来,可能与vue的声明周期有关,这个暂时不清楚,加上setTimeout函数之后,会将此函数中的操作加到处理队列末尾 在拿到canvas后,转化为图片,直接就可以使用了。

3.关于html2canvas截出来的图片模糊的问题,我查了好多资料,试了好多方法,最终找到一篇非常有用的文章 https://segmentfault.com/a/1190000007707209

方法如下:

(1.修改插件的源码

<1.代码第999行renderWindow的方法中修改判断条件,增加一个options.scale存在的条件:

将       

 if (options.type === "view") {
canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});
} else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) {
canvas = renderer.canvas;
} else {
canvas = crop(renderer.canvas, {width: options.width != null ? options.width : bounds.width, height: options.height != null ? options.height : bounds.height, top: bounds.top, left: bounds.left, x: 0, y: 0}); }

修改为     

 if (options.type === "view") {
canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});
} else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement) {
canvas = renderer.canvas;
}else if(options.scale && options.canvas !=null){
log("放大canvas",options.canvas);
var scale = options.scale || 1;
canvas = crop(renderer.canvas, {width: bounds.width * scale, height:bounds.height * scale, top: bounds.top *scale, left: bounds.left *scale, x: 0, y: 0});
}
else {
canvas = crop(renderer.canvas, {width: options.width != null ? options.width : bounds.width, height: options.height != null ? options.height : bounds.height, top: bounds.top, left: bounds.left, x: 0, y: 0});
}

2.代码第 943 行 html2canvas 的方法中 修改width,height:

 return renderDocument(node.ownerDocument, options, node.ownerDocument.defaultView.innerWidth, node.ownerDocument.defaultView.innerHeight, index).then(function(canvas) {
if (typeof(options.onrendered) === "function") {
log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
options.onrendered(canvas);
}
return canvas;
});

改为:

 width = options.width != null ? options.width : node.ownerDocument.defaultView.innerWidth;
height = options.height != null ? options.height : node.ownerDocument.defaultView.innerHeight;
return renderDocument(node.ownerDocument, options, width, height, index).then(function(canvas) {
if (typeof(options.onrendered) === "function") {
log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
options.onrendered(canvas);
}
return canvas;
});

然后就可以使用了,将原来的使用放式稍微还一下就可以了,使用实例如下:

在vue的方法中添加一个获取设备像素密度的方法 

  getPixelRatio(context){
var backingStore = context.backingStorePixelRatio ||
context.webkitBackingStorePixelRatio ||
context.mozBackingStorePixelRatio ||
context.msBackingStorePixelRatio ||
context.oBackingStorePixelRatio ||
context.backingStorePixelRatio || 1;
return (window.devicePixelRatio || 1) / backingStore;
},

然后将最上面的使用示例改为:

   get_img(){
let self = this;
setTimeout(function () {
var content_html = document.getElementById('content_html');    //要转化的div
let width = content_html.offsetWidth;
let height = content_html.offsetHeight;
let offsetTop = content_html.offsetTop;
let canvas = document.createElement("canvas");
let context = canvas.getContext('2d');
let scaleBy = self.getPixelRatio(context);
canvas.width = width*scaleBy;
canvas.height = (height+offsetTop)*scaleBy;
context.scale(scaleBy,scaleBy);
var opts = {
  allowTaint:true,//允许加载跨域的图片
  tainttest:true, //检测每张图片都已经加载完成
scale:scaleBy, // 添加的scale 参数
canvas:canvas, //自定义 canvas
logging: true, //日志开关,发布的时候记得改成false
width:width, //dom 原始宽度
height:height //dom 原始高度
};
html2canvas(content_html,opts).then(function (canvas) {
  canvas.style.width = width+"px";
canvas.style.height = height+"px";
var image = new Image();
image.src = canvas.toDataURL();
document.getElementById('content_img').appendChild(image);      //将转化好的图片插入到防止图片转换的div中
content_html.style.display='none'
});
}

然后在html2canvas插件加载成功后调用get_img()方法即可将比较清晰的图片插入到指定位置

注:如需转载请注明出处:http://www.cnblogs.com/zhuchenglin/p/7455336.html

vue中使用html2canvas及解决html2canvas截屏图片模糊问题的更多相关文章

  1. 完美解决scrollView 截屏图片模糊

    UIGraphicsBeginImageContext   首先说明一下UIGraphicsBeginImageContextWithOptions 和UIGraphicsBeginImageCont ...

  2. 【Android实战】Bitmap图片的截屏、模糊处理、传递、使用

    项目中遇到了这样一个需求: 当某个条件满足时就截取当前屏幕.并跳转到另外一个页面,同一时候将这个截屏图片作为下一个页面的背景图片,同一时候背景图片须要模糊处理 接下来就一步一步解决这个问题: 1.截取 ...

  3. IOS第17天(2,Quartz2D图片剪裁变圆行图,和截屏图片)

    **** #import "HMViewController.h" #import "UIImage+Tool.h" @interface HMViewCont ...

  4. pytest框架优化——将异常截屏图片加入到allure报告中

    痛点分析: 在做allure定制化的时候,关于附件添加这一块,我们在代码里可以添加我们准备好的附件,这里用图片,通过下面的方法就能实现 allure.attach(file, '图片描述', allu ...

  5. Selenium截屏 图片未加载的问题解决--【懒加载】

    需求: 截屏后转PDF. 问题: selenium截屏后,图片未加载 如下图: 原因: 网站使用了懒加载技术:只有在浏览器中纵向滚动条滚动到指定的位置时,页面的元素才会被动态加载. 什么是图片懒加载? ...

  6. [Egret]长按截屏分享、分享截屏图片、本地存储

    egret 分享有API可以把一个显示对象树渲染成一个位图纹理,我把它赋值给 HTML 的 Image 元素,就实现了图片的显示,在微信中,通过长按图片可以分享出去.当然在其他浏览器可以保存在本地. ...

  7. 获取camera截屏图片

    Camera camera; SpriteRenderer sprRender; Texture2D t2d = New Texture2D(1300, 760, TextureFormat.RGB2 ...

  8. cocos2dx之保存截屏图片

    http://blog.csdn.net/ganpengjin1/article/details/19088921 我们要保存当前的运行的scene的截图的话,我用到CCRenderTexture,看 ...

  9. iOS 中捕获截屏操作

    转自:iOS知识小集 在iOS 7后,苹果提供了UIApplicationUserDidTakeScreenshotNotification通知来告诉App用户做了截屏操作.苹果的描述如下: // T ...

随机推荐

  1. [Web 前端] mobx教程(五)-Mobx常见问题及解决方案(1)Mobx使用严格模式

    copy from : https://blog.csdn.net/smk108/article/details/83185745 mobx在严格模式下,不允许在 action 外更改任何状态.但是不 ...

  2. ABAP表抛FTP通用程序

    主要功能: 1.支持R3所有表(标准.自建)下传,下传方式为FTP 2.支持输出字段选择及顺序调整 3.支持动态条件,不同的表会有不同的选择条件,根据不同的条件选择需要下传的数据 4.支持单表.多表. ...

  3. Centos7 设置、查看、添加、删除服务的开机启动项

    查看开机启动项 systemctl list-unit-files |   grep enable 为服务添加开机启动项 systemctl enable zabbix-server.service ...

  4. CentOS7.2网络配置

    修改hostname vi /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain ...

  5. java生成32的md5签名串

    import java.security.MessageDigest; import lombok.extern.slf4j.Slf4j; /** * 签名帮助类 * * @author yangzl ...

  6. android学习十二(android的Content Provider(内容提供器)的使用)

    文件存储和SharePreference存储以及数据存储一般为了安全,最好用于当前应用程序中訪问和存储数据.内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能 ...

  7. [转]Ubuntu18.04搜狗拼音输入法候选栏乱码解决方法

    经常碰到安装完搜狗拼音输入法后候选栏是乱码的情况,解决方法如下: 输入如下命令: cd ~/.config sudo rm -rf SogouPY* sogou* 1 2 之后重启即可. 安装过程可参 ...

  8. SNF软件开发机器人-子系统-功能-【列表】自由排序-如何配置?

    [列表]自由排序 1.效果展示: 2.使用说明: 打开显示页面,点击开发者选项的简单配置按钮.在功能表信息中选择自由排序复选框后保存.

  9. IPv6地址分类及表示方法

    对于IPv4地址,我们知道分为A类.B类.C类.组播地址和留用地址,几大类,ABC类地址中还会有不同功能的如广播地址.私有地址等类型.那么IPv6的地址是怎么分类的呢?本文就带大家初步了解一下. 先说 ...

  10. Android设备真实DPI与系统标示DPI——ldpi/mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi

    1.设备真实DPI与系统标示DPI 2.drawable允许的标示DPI值         drawable文件的合法名称如下: 3.如何验证         Demo如下,建立不同dpi的drawa ...