您的位置:

从多个方面详解html2canvas.js下载

一、html2canvas截图下载

html2canvas是一个能够实现将HTML界面转化为Canvas图像并导出的JavaScript库,使得前端开发人员能够很方便地把所见即所得的界面进行保存或导出、出图。我们可以通过以下代码引入html2canvas:

<script src="https://cdn.bootcdn.net/ajax/libs/html2canvas/1.0.0/html2canvas.min.js"></script>

在使用html2canvas进行截图之前,我们需要首先规划好需要截图的界面元素及导出方式。以下代码展示如何对页面进行截图并下载成PNG或JPEG格式:

html2canvas(document.body).then(function(canvas) {
    //将html2canvas生成的Canvas对象转化为图片url,传入浏览器默认下载函数即可实现下载图片的功能
    download(canvas.toDataURL(), 'canvas.png'); //下载为PNG格式
    // download(canvas.toDataURL('image/jpeg'), 'canvas.jpg'); //下载为JPEG格式
});

//浏览器默认下载函数
function download(url, name) {
    var link = document.createElement('a');
    link.download = name;
    link.href = url;
    link.click();
}

代码执行后,我们即可获得一张下载下来的截图。

二、html2canvas官网

html2canvas的官方网站为https://html2canvas.hertzen.com/。通过访问该网站,我们可以找到html2canvas的相关文档和资源。以下是几个值得一提的资源:

1、html2canvas GitHub主页:https://github.com/niklasvh/html2canvas

html2canvas的GitHub代码仓库,包含了html2canvas的源码及其相关资源。

2、html2canvas在线示例:https://html2canvas.hertzen.com/examples

html2canvas提供了多个在线示例,可以通过这些示例了解html2canvas的具体应用。

3、html2canvas文档:https://html2canvas.hertzen.com/documentation

html2canvas的官方文档,包含了html2canvas的安装、基本使用、高级使用以及API等相关内容。

三、html2canvas源码解析

1、核心代码解析

以下为html2canvas的主要代码逻辑:

html2canvas(document.querySelector("#capture")).then(canvas => {
    document.body.appendChild(canvas);
});

function html2canvas(node) {
  //初始化画布并返回一个Promise对象
  return new Promise(resolve => {
    //创建一个canvas元素并赋予初始属性
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
  
    //将传入的节点进行转化为Canvas
    renderNode(node, ctx).then(() => {
      resolve(canvas);
    });
  });
}

function renderNode(node, ctx) {
  //创建包含当前节点的Promise对象
  return new Promise(resolve => {
    //使用window.getComputedStyle()获取节点在渲染后的实际样式
    const style = window.getComputedStyle(node);
    //获取节点的实际宽高
    const width = parseInt(style.getPropertyValue("width"));
    const height = parseInt(style.getPropertyValue("height"));
  
    //将当前节点绘制到Canvas上
    ctx.drawImage(node, 0, 0, width, height);
  
    //创建一个嵌套的Promise对象,来处理当前节点的子元素
    Promise.all(
      [...node.childNodes].map(node => renderNode(node, ctx))
    ).then(() => {
      resolve();
    });
  });
}

html2canvas的核心逻辑在于将需要截图的节点转化为Canvas对象,经过多次Promise嵌套处理,最终返回一个包含有Canvas对象的Promise对象。通过resolve()可以实现异步代码的同步等待。

2、核心算法解析

html2canvas的核心算法在于Canvas的绘制过程,具体包括以下几个步骤:

1、计算绘制的实际宽高

首先通过window.getComputedStyle()获取节点在渲染后实际的样式,然后获取节点的实际宽高,为后续的绘制做准备。

2、绘制节点的背景及边框

通过绘制一个填充为节点背景色的矩形,实现对节点背景的绘制;

通过绘制多个边框,实现对节点边框的绘制。

3、绘制节点的子元素

通过嵌套的Promise对象逐个处理子元素的绘制,最终实现对节点及其所有子元素的绘制。

3、html2canvas常见问题

1、跨域问题

默认情况下,html2canvas会受到同源策略的限制,导致无法截图跨域的页面。我们可以通过配置proxy属性实现对跨域网页的截图。例如:

html2canvas(document.body, { 
  proxy: "https://html2canvas-proxy.xxxxx.com/proxy.php?url="
}).then(canvas => {
  document.body.appendChild(canvas);
});

proxy属性需要对应一个接口来转发图片。具体实现方式可以参考html2canvas-proxy项目的源码。

2、低版本浏览器兼容问题

html2canvas可能存在与IE浏览器及低版本浏览器之间的不兼容问题。为此,我们可以通过引入html2canvas的一些插件以及设置一些CSS属性来实现浏览器兼容,方法如下:

1)引入一些兼容HTML5的polyfills,比如html5shiv.min.js、respond.min.js。

<!--[if lt IE 9]>
  <script src="//cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
  <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->

2)设置html和body元素的高度及宽度为100%,禁止滚动

html,body{
  width:100%;
  height:100%;
  overflow:hidden;
}

3)增加SVG规则

svg {
  overflow: hidden;
  margin: 0;
  padding: 0;
  width: 1em;
  height: 1em;
}

4)设置一些样式,如opacity属性等

四、HTML页面截图实战应用

html2canvas的使用并不仅止于获取某个节点或整个页面的静态截图,其还可以在实际应用场景中发挥其大作用。以下是几个应用场景:

1、生成二维码

我们可以通过html2canvas的截图功能对生成的二维码进行截图保存,代码如下:

html2canvas(document.querySelector("#qr-code")).then(canvas => {
    document.body.appendChild(canvas);
    //将html2canvas生成的Canvas对象转化为图片url,传入浏览器默认下载函数即可实现下载图片的功能
    download(canvas.toDataURL(), 'qr-code.png'); //下载为PNG格式
});

2、图片合成

通过html2canvas生成多张图片并进行合成,实现多帧动态效果的生成,代码如下:

const canvas_1 = document.createElement("canvas");
const canvas_2 = document.createElement("canvas");

html2canvas(document.querySelector(".block-1")).then(canvas => {
    canvas_1.width = canvas.width;
    canvas_1.height = canvas.height;
    
    const ctx = canvas_1.getContext("2d");
    //将第一张图片绘制到画布上
    ctx.drawImage(canvas, 0, 0);
}).then(() => {
    html2canvas(document.querySelector(".block-2")).then(canvas => {
        canvas_2.width = canvas.width;
        canvas_2.height = canvas.height;
    
        const ctx = canvas_2.getContext("2d");
        //将第二张图片绘制到画布上
        ctx.drawImage(canvas, 0, 0);
    });
}).then(() => {
    //将两张画布合并成一张
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");
    
    canvas.width = canvas_1.width + canvas_2.width;
    canvas.height = canvas_1.height;

    ctx.drawImage(canvas_1, 0, 0);
    ctx.drawImage(canvas_2, canvas_1.width, 0);

    //将html2canvas生成的Canvas对象转化为图片url,传入浏览器默认下载函数即可实现下载图片的功能
    download(canvas.toDataURL(), 'merged.png'); //下载为PNG格式
});

//浏览器默认下载函数
function download(url, name) {
    var link = document.createElement('a');
    link.download = name;
    link.href = url;
    link.click();
}

通过以上实现方法,我们可以将多张静态图片合成成一张带有动态效果的图片。