利用html2canvas实现网页区域截图

项目中遇到一个需求:将展示的二维码页面保存成图片。在网上找了很久找到了一款插件html2canvas,本以为用这个插件可以轻松实现网页区域截图呢,没想到出了幺蛾子,花了我一天的时间来解决。以下为利用html2canvas实现网页区域截图的整个过程。

【相关资料】

1、div_to_img:这是一个单html实现的网页转图片的demo。下载地址>>

2、div2img:Tp-admin及ThinkAdmin后端框架可以集成的插件代码。下载地址>>

在实现网页区域截屏功能的过程中,遇到了一个问题“网页通过script标签引入了html2canvas,但在使用时却仍然报错“Uncaught ReferenceError: html2canvas is not defined”。”为此波波还特意在SegmentFault社区向精通前端的大佬们求助了。问题链接:https://segmentfault.com/q/1010000039059307

html2canvas实现网页区域截图

以下是波波最终解决该问题的代码片段,供后期其他遇到同类问题的朋友们参考。

1、将“div2img”的压缩包下载后解压至Tp-admin的“/static/plugs/”目录下。

2、在“/static/admin/app.js”中RequireJS的配置中添加html2canvas模块。代码如下:

  1. paths: {
  2.         // 自定义插件(源码自创建或已修改源码)
  3.         'admin.plugs': ['plugs'],
  4.         'admin.listen': ['listen'],
  5.         'template': ['../plugs/template/template'],
  6.         'pcasunzips': ['../plugs/jquery/pcasunzips'],
  7.         // 开源插件(未修改源码)
  8.         'pace': ['../plugs/jquery/pace.min'],
  9.         'json': ['../plugs/jquery/json2.min'],
  10.         'layui': ['../plugs/layui/layui'],
  11.         'jquery': ['../plugs/jquery/jquery.min'],
  12.         'base64': ['../plugs/jquery/base64.min'],
  13.         'angular': ['../plugs/angular/angular.min'],
  14.         'ckeditor': ['../plugs/ckeditor/ckeditor'],
  15.         'websocket': ['../plugs/socket/websocket'],
  16.         'bootstrap': ['../plugs/bootstrap/js/bootstrap.min'],
  17.         'bootstrap.typeahead': ['../plugs/bootstrap/js/bootstrap3-typeahead.min'],
  18.         'jquery.ztree': ['../plugs/ztree/jquery.ztree.all.min'],
  19.         'jquery.masonry': ['../plugs/jquery/masonry.min'],
  20.         'jquery.cookies': ['../plugs/jquery/jquery.cookie'],
  21.         'dropdown': ['../plugs/dropdown/dropdown'],
  22.         'treetable': ['../plugs/treetable/treetable'],
  23.         'html2canvas':['../plugs/div2img/html2canvas.min'],
  24.         'bluebird':['../plugs/div2img/bluebird'],
  25.     },
  26.     shim: {
  27.         'layui': {deps: ['jquery']},
  28.         'ckeditor': {deps: ['jquery']},
  29.         'websocket': {deps: [_root + '../plugs/socket/swfobject.min.js']},
  30.         'pcasunzips': {deps: ['jquery']},
  31.         'admin.plugs': {deps: ['jquery', 'layui']},
  32.         'admin.listen': {deps: ['jquery', 'jquery.cookies', 'admin.plugs']},
  33.         'bootstrap': {deps: ['jquery']},
  34.         'bootstrap.typeahead': {deps: ['bootstrap']},
  35.         'jquery.ztree': {deps: ['jquery', 'css!' + _root + '../plugs/ztree/zTreeStyle/zTreeStyle.css']},
  36.         'jquery.cookies': {deps: ['jquery']},
  37.         'jquery.masonry': {deps: ['jquery']},
  38.         'html2canvas':{deps:['jquery','bluebird']},
  39.     },

其实主要看path的最后两行和shim的最后一行。其他人也可以参照用RequireJS。官方有文档。

3、网页部分代码。

  1. <script>
  2. var screenshot;
  3.     require(['html2canvas'],function (html2canvas){
  4.        this.screenshot = function(){
  5.             var getPixelRatio = function (context) { // 获取设备的PixelRatio
  6.                 var backingStore = context.backingStorePixelRatio ||
  7.                     context.webkitBackingStorePixelRatio ||
  8.                     context.mozBackingStorePixelRatio ||
  9.                     context.msBackingStorePixelRatio ||
  10.                     context.oBackingStorePixelRatio ||
  11.                     context.backingStorePixelRatio || 0.5;
  12.                 return (window.devicePixelRatio || 0.5) / backingStore;
  13.             };
  14.             //生成的图片名称
  15.             var imgName = (new Date()).valueOf()+".jpg";
  16.             var shareContent = document.getElementById("printarea");
  17.             var width = shareContent.offsetWidth;
  18.             var height = shareContent.offsetHeight;
  19.             var canvas = document.createElement("canvas");
  20.             var context = canvas.getContext('2d');
  21.             var scale = getPixelRatio(context); //将canvas的容器扩大PixelRatio倍,再将画布缩放,将图像放大PixelRatio倍。
  22.             canvas.width = width * scale;
  23.             canvas.height = height * scale;
  24.             canvas.style.width = width + 'px';
  25.             canvas.style.height = height + 'px';
  26.             context.scale(scale, scale);
  27.             var opts = {
  28.                 scale: scale,
  29.                 canvas: canvas,
  30.                 width: width,
  31.                 height: height,
  32.                 dpi: window.devicePixelRatio
  33.             };
  34.            html2canvas(shareContent, opts).then(function (canvas) {
  35.                 context.imageSmoothingEnabled = false;
  36.                 context.webkitImageSmoothingEnabled = false;
  37.                 context.msImageSmoothingEnabled = false;
  38.                 context.imageSmoothingEnabled = false;
  39.                 var dataUrl = canvas.toDataURL('image/jpeg', 1.0);
  40.                 dataURIToBlob(imgName, dataUrl, callback);
  41.             });
  42.         }
  43.     })
  44.     var dataURIToBlob =  function (imgName, dataURI, callback) {
  45.         var binStr = atob(dataURI.split(',')[1]),
  46.             len = binStr.length,
  47.             arr = new Uint8Array(len);
  48.         for (var i = 0; i < len; i++) {
  49.             arr[i] = binStr.charCodeAt(i);
  50.         }
  51.         callback(imgName, new Blob([arr]));
  52.     }
  53.     var callback = function (imgName, blob) {
  54.         var triggerDownload = $("<a>").attr("href", URL.createObjectURL(blob)).attr("download", imgName).appendTo("body").on("click"function () {
  55.             if (navigator.msSaveBlob) {
  56.                 return navigator.msSaveBlob(blob, imgName);
  57.             }
  58.         });
  59.         triggerDownload[0].click();
  60.         triggerDownload.remove();
  61.     };
  62. </script>

在HTML部分我们只需要写一个保存的按钮就可以了。

  1. <button class="layui-btn layui-btn-danger" type='button' onclick="screenshot();">保存图片</button>

【总结】

之前一直在写screenshot()函数,所出现的问题主要是当前对象访问不到。因此最后能得以解决就是在页面中先定义一个对象,然后require异步加载模块的时候,将新的函数对象赋值给全局对象。然后“Uncaught ReferenceError: html2canvas is not defined”的问题就解决了,保存图片的功能就实现了。

 

波波
你想把广告放到这里吗?

发表评论

您必须 登录 才能发表留言!