前端如何实现一键截图功能?
精彩回顾
如何实现H5可视化编辑器的实时预览和真机扫码预览功能 在线IDE开发入门之从零实现一个在线代码编辑器 基于React+Koa实现一个h5页面可视化编辑器-Dooring TS核心知识点总结及项目实战案例分析
前言
网页截图功能目前也是非常常见的需求, 尤其是在在线教育领域. 我们朋友圈的微信海报, 活动海报等, 一般都是运营/市场人员通过设计工具设计而成, 但是如何更好的映射到自己的服务体系里面, 比如H5页面中, 植入更多信息收集, 交互能力. 这一块的应用探索, 页面截图是一个非常好的解决方案.
接下来笔者就来复盘一下如何基于网页, 一键生成页面海报的功能, 并将此能力, 集成到笔者的开源项目H5-Dooring中为编辑器赋能.
正文
从演示中我们可以看出, 我们最终目标是实现在PC端生成H5页面的截图, 所以可能会涉及到以下几个问题:
如何实现将页面转化为图片 如何实现H5效果模拟并截取实际的H5页面
如何实现将页面转化为图片
在亲自调研了html2canvas库并使用的过程中, 笔者发现了很多问题, 比如如果样式中出现%单位, 或者有一些图片背景的问题, 导致html2canvas并没有很好的work, 而且渲染还原度和清晰度都有问题, 所以笔者暂时没有深入研究(不过这些问题可以通过修改库本身解决), 后面笔者直接用了dom-to-image, 发现使用起来很简单, 而且几乎不会出现上面说的这些问题, 所以笔者果断采用了dom-to-image, 后面看了该库的源码, 感觉写的也很优雅易懂, 后期做二次开发应该问题不是很大. 我们可以看看其官网的基本使用:
import domtoimage from 'dom-to-image';
// 生成图片
domtoimage.toPng(node)
.then(function (dataUrl) {
var img = new Image();
img.src = dataUrl;
document.body.appendChild(img);
})
.catch(function (error) {
console.error('oops, something went wrong!', error);
});
第一个问题就这么解决了, 不过在使用过程中发现图片模糊的问题, 这块网上也有很多解决方案. 比如先放大dom, 在处理成canvas最后生成图片的时候在缩小等, 这块笔者就不一一举例了.
如何实现H5效果模拟并截取实际的H5页面
因为我们设计的H5页面都在pc端完成的, 所以要想生成H5预览图, 无非是本地模拟尺寸, 进行渲染, 具体方案如下:
采用iframe作为H5页面容器去生成截图 直接限制宽度在当前页面生成截图 采用服务端爬虫一键模拟手机访问生成截图
上面说的方案都可以尝试, 第三种方案笔者之前也开源过爬虫应用来解决这个问题, 感兴趣的可以研究了解一下, 我们很明显会选择第一种方案来实现, 就如演示中的, 我们看到的弹窗中的H5其实是在iframe中渲染的:
// 定义截图子页面句柄函数
window.getFaceUrl = (url) => {
setFaceUrl(url)
setShowModalIframe(false)
}
// iframe页面, 也就是预览页面
const generateImg = (cb:any) => {
domtoimage.toBlob(refImgDom.current,
{
width,
height,
}
)
.then(function (blob:Blob) {
const formData = new FormData();
formData.append('file', blob, 'tpl.jpg');
req.post('/files/upload/free', formData).then((res:any) => {
cb && cb(res.url)
})
})
.catch(function (error:any) {
console.error('oops, something went wrong!', error);
});
}
// 触发父页面的方法,将图片传给父页面
generateImg((url:string) => {
parent.window.getFaceUrl(url);
})