vue中使用html2canvas及解決html2canvas截屏圖片模糊問題


最近在項目中用到了html2canvas插件,遇到的一些坑寫下來,與大家共勉。

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

這是一個js截屏插件,在前台利用h5的canvas  將html的內容顯示在canvas上,再利用 js 將canvas轉化為圖片

1.vue 文件中引入 html2canvas.js

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

說明:src中的路徑是html2canvas.js在項目中的路徑

remoteScript 標簽是上篇博客定義的標簽,詳情見:http://www.cnblogs.com/zhuchenglin/p/7455203.html

2.在vue中使用該插件,在methods中定義一個方法,內容為:

 1 setTimeout(function () {
 2   html2canvas(dom,{
 3         onrendered:function (canvas) {
 4           var image = new Image();
 5           image.src = canvas.toDataURL();
 6           document.getElementById('content_img').appendChild(image)
 7           dom.style.display='none'
 8        },
 9   });
10 },0)

這樣就可以了

說明:
在方法中如果不加 setTimeout函數的話,雖然使用console輸出的dom內容正常,但是如果在vue中定義的變量中的內容在canvas中顯示不出來,可能與vue的聲明周期有關,這個暫時不清楚,加上setTimeout函數之后,會將此函數中的操作加到處理隊列末尾

在拿到canvas后,轉化為圖片,直接就可以使用了。

 

 3.關於html2canvas截出來的圖片模糊的問題,我查了好多資料,試了好多方法,最終找到一篇非常有用的文章 https://segmentfault.com/a/1190000007707209

方法如下:

(1.修改插件的源碼

<1.代碼第999行renderWindow的方法中修改判斷條件,增加一個options.scale存在的條件:

將       

1 if (options.type === "view") {
2                 canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});
3             } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement || options.canvas != null) {
4                 canvas = renderer.canvas;
5             } else {
6                 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});
7 
8             }

修改為     

 1 if (options.type === "view") {
 2                 canvas = crop(renderer.canvas, {width: renderer.canvas.width, height: renderer.canvas.height, top: 0, left: 0, x: 0, y: 0});
 3             } else if (node === clonedWindow.document.body || node === clonedWindow.document.documentElement) {
 4                 canvas = renderer.canvas;
 5             }else if(options.scale && options.canvas !=null){
 6                 log("放大canvas",options.canvas);
 7                 var scale = options.scale || 1;
 8                 canvas = crop(renderer.canvas, {width: bounds.width * scale, height:bounds.height * scale, top: bounds.top *scale, left: bounds.left *scale, x: 0, y: 0});
 9             }
10             else {
11                 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});
12             }

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

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

改為:

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

然后就可以使用了,將原來的使用放式稍微還一下就可以了,使用實例如下:

在vue的方法中添加一個獲取設備像素密度的方法 

1  getPixelRatio(context){
2      var backingStore = context.backingStorePixelRatio ||
3              context.webkitBackingStorePixelRatio ||
4              context.mozBackingStorePixelRatio ||
5              context.msBackingStorePixelRatio ||
6              context.oBackingStorePixelRatio ||
7              context.backingStorePixelRatio || 1;
8        return (window.devicePixelRatio || 1) / backingStore;
9 },

然后將最上面的使用示例改為:

 1   get_img(){
 2       let self = this;
 3       setTimeout(function () {
 4       var content_html = document.getElementById('content_html');    //要轉化的div
 5       let width = content_html.offsetWidth;
 6       let height = content_html.offsetHeight;
 7       let offsetTop = content_html.offsetTop;
 8       let canvas = document.createElement("canvas");
 9       let context = canvas.getContext('2d');
10       let scaleBy = self.getPixelRatio(context);
11       canvas.width = width*scaleBy;
12       canvas.height = (height+offsetTop)*scaleBy;
13       context.scale(scaleBy,scaleBy);
14       var opts = {
15         allowTaint:true,//允許加載跨域的圖片
16         tainttest:true, //檢測每張圖片都已經加載完成
17          scale:scaleBy, // 添加的scale 參數
18          canvas:canvas, //自定義 canvas
19          logging: true, //日志開關,發布的時候記得改成false
20          width:width, //dom 原始寬度
21          height:height //dom 原始高度
22          };
23      html2canvas(content_html,opts).then(function (canvas) {
24        canvas.style.width = width+"px";
25         canvas.style.height = height+"px";
26         var image = new Image();
27         image.src = canvas.toDataURL();
28         document.getElementById('content_img').appendChild(image);      //將轉化好的圖片插入到防止圖片轉換的div中
29         content_html.style.display='none'
30      });
31 }

然后在html2canvas插件加載成功后調用get_img()方法即可將比較清晰的圖片插入到指定位置 

注:如需轉載請注明出處:http://www.cnblogs.com/zhuchenglin/p/7455336.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM