做这个功能都是半个月之前的事情了,没想到一直耽误却一直都没有写下总结,尴尬。。。。。来来来,说正事
在手机端截屏完全不需要前端动什么脑子,但是在网页上截屏就很头疼了,我这里介绍两种情形,针对普遍和某一特殊功能需求
1、js截屏插件html2canvas.js
这个插件真的很好用,而且GitHub上的小星星也特别多,html2canvas官网 也给了详细的例子,最简单的就这样引用一个库文件,调用就可以将页面中的元素截图下来了。
但是这个插件原理是,将需要截图页面里面的元素一层一层遍历,然后在canvas中进行重绘,再将canvas转换成图片的过程。
注意事项:
- 不支持iframe
- 不支持跨域图片(可以先将线上图片转换成base64,然后用base64作为图片路径)
- 不支持flash
- 不支持transform、transition过渡、animation动画(备注:transform初始布局是可以的,但是不能参与动画类的操作)
html:
<div id="capture" style="padding: 10px; background: #f5da55">
<h4 style="color: #000; ">Hello world!</h4>
</div>
js:
html2canvas(document.querySelector("#capture")).then(canvas => {
document.body.appendChild(canvas)
});
2、js原生代码截屏
如果你只是要截取canvas里面的内容,那就很简单了。因为canvas原生的有toDataURL方法,可直接将选中的canvas转变为base64编码。因为我是用在three.js这个3d项目的场景里面,所以没用过这个库的朋友可能没遇到过bug。那就是截屏出来的图片是空白的,场景scene后期渲染的比如灯光,加载的模型都没有截图截下来。有两种方法
第一种是在渲染器开启preserveDrawingBuffer :true,即缓冲区保护-是否保存在缓冲区手动清除或覆盖,这个默认是false。开启之后,缓冲区的图像就不会被更新清除,就可以截取下来想要的图案。但问题也很明显,那就是在有动画或者后期渲染内容增加的时候,你的画面会变得很乱,内容被不断的叠加,因此我是建议大家使用第二种方法,这个方法说出来,只是为了让大家更加了解一下。
renderer = new WebGLRenderer({
antialias: true,
alpha: true,
preserveDrawingBuffer :true
})
第二种方法就是在截图之前先渲染一下场景和相机,就不会实时刷新屏幕,导致我们截屏下来的是空白了
let canvas=rederer.domElement
rederer.render(scene, camera)
var imgUri = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); // 获取生成的图片的url
window.kk= imgUri // 下载图片