一、场景
读书郎实验项目中,自定义完实验,有一个保存功能,在点击保存的时候,需要截取当前实验界面作为该实验的封面,这里截取屏幕的方案可以直接使用 canvas 的 toDataUrl 方法去实现。
但是该方法的局限性在于截取范围不好控制,我们要截取的内容不一定是 canvas,还可能是其他内容,比如 dom,这里可能就需要我们把 dom 另外画到 canvas 上,再去截取了。
为了快速实现该功能,降低成本,我们选择了页面截屏神器 html2canvas。
效果图:
二、使用姿势
1、上手
关于使用姿势,官网给出的例子是这样的:
npm install html2canvas
import html2canvas from 'html2canvas';
html2canvas(document.body).then(function(canvas) {
document.body.appendChild(canvas);
});
通过运行以上 demo,我们可以拿到截取视口的 canvas:
<canvas width="2880" height="1578" style="width: 1440px; height: 789px;">
2、canvas 生成 base64 图片
但是我们要的是一张图而不是一个 dom,上面提到过 canvas 有一个 toDataUrl 方法,可以把 canvas 转成 base64 格式,代码可以修改为:
import html2canvas from 'html2canvas';
html2canvas(document.body).then(function(canvas) {
const dataUrl = canvas.toDataURL();
});
3、定制 canvas 宽高
现在我们拿到了一张截屏图,下一个问题是,我们的截屏需要定制大小,比如我们的封面是 1280 * 800 的,查看一下官方文档,可以发现 html2canvas 可以配置宽高,也就是生成 canvas 的宽高,再修改一下代码:
async save() {
const dom = document.querySelector('canvas');
let dataUrl = '';
const canvas = await html2canvas(dom, {
width: 1280,
height: 800,
});
dataUrl = canvas.toDataURL();
}
4、解决图片跨域问题
我们的实验中,会大量的用到图片,所以 canvas 里画一些必要的器件,这里会遇到图片跨域的问题,研究一下官网的配置介绍,看到有一个配置属性可以解决这个问题,再次修改下代码:
async save() {
const dom = document.querySelector('canvas');
let dataUrl = '';
const canvas = await html2canvas(dom, {
width: 1280,
height: 800,
useCORS: true
});
dataUrl = canvas.toDataURL();
}
5、截图背景色配置
生成的封面,我们往往会有一个固定的颜色,毕竟五花八门的颜色,看起来杂乱无章,影响体验,所以这里再稍微加一个颜色配置:
async save() {
const dom = document.querySelector('canvas');
let dataUrl = '';
const canvas = await html2canvas(dom, {
width: 1280,
height: 800,
backgroundColor: '#353840',
useCORS: true
});
dataUrl = canvas.toDataURL();
}
至此,截取实验封面就用 html2canvas 完美解决了。
三、结论
无论是用已有的轮子还是自己造轮子,截图功能的基本思路都是把 dom 画到 canvas 上,通过 canvas 的 toDataUrl 方法把 canvas 转为 base64 格式,从而拿到图。遇到的问题大体是宽高定制、背景色定制以及图片跨域等,所以要实现截屏轮子,最基础的就是要解决以上几个问题。
想做更多有趣的实验?正在愁上课实验资源没处找?读书郎仿真实验了解下。
作者: Canace