一、背景
最近,工作项目中需要用到指定区域截图的功能,我们常见的方式有HtmlToCanvas这种方式,但是在实现的过程中,发现由于HtmlToCanvas这种第三方库对于一些样式的支持还不够友好,因此带来了一些新的问题,且这些问题并不很好解决。于是,我决定盘点下截图的所有流行方式。并做下对比,从中选出效果最好的方案来。Come on!
二、解决方案对比
1、HtmlToCanvas
众所周知,HtmlToCanvas这种方案也是属于很常见的方式,目前Git上已经迭代至1.6版本了。但是对于由Element-UI库的组件去截图,会有一些棘手的问题。
(1)在新的生成截图的效果中,类型为textarea的Input控件,会出现不支持折行,多行数据只显示一行的问题,超出区域的数据不能被显示的问题。
(2)在新的生成截图的效果中,Select控件,会出现数据偏移,行高显示异常问题。
(3)在新的生成截图的效果中,Data-Picker控件,会出现数据偏移,行高显示异常问题。
(4)在新的生成截图的效果中,类型为Number的Input控件,会出现数据偏移,行高显示异常问题。
2、DomToImage
3、Puppeteer
4、调用浏览器/系统自带的截图方法
三、具体实现方案细节
1、HtmlToCanvas的实现
/*
* @Description: Html生成Img工具
* @Date: 2022-05-24 17:08:18
* @FilePath: src/utils/htmlToImg.js
*/
import html2Canvas from 'html2canvas';
/**
* @description base64转图片文件
* @param {String} dataurl 图片数据(base64格式)
* @param {String} type 文件类型
* @return {File} File 图片二进制流
*/
const base64ImgtoFile = function(dataurl, type) {
let binary = atob(dataurl.split(',')[1]);
let array = [];
for (let i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], { type: type });
}
/**
* @description 根据Dom区域生成图片
* @param {String} ref Dom区域ref
* @param {String} name 图片名称
* @return {File} File 图片文件
*/
export default {
install(Vue) {
Vue.prototype.createImg = async function (dom) {
return await html2Canvas(dom, {
useCORS: true,
allowTaint: false,
logging: false,
letterRendering: true
}).then(canvas => {
this.posterImg = canvas.toDataURL('image/png');
return base64ImgtoFile(this.posterImg, 'image/jpeg');
})
}
}
}
2、DomToImage的实现
/*
* @Description: Html生成Img工具
* @Date: 2022-08-01 17:24:38
* @FilePath: src/utils/domToImg.js
*/
import domToImage from 'dom-to-image';
/**
* @description base64转图片文件
* @param {String} dataurl 图片数据(base64格式)
* @param {String} type 文件类型
* @return {File} File 图片二进制流
*/
const base64ImgtoFile = function(dataurl, type) {
let binary = atob(dataurl.split(',')[1]);
let array = [];
for (let i = 0; i < binary.length; i++) {
array.push(binary.charCodeAt(i));
}
return new Blob([new Uint8Array(array)], { type: type });
}
/**
* @description 根据Dom区域生成图片
* @return {File} File 图片文件
*/
export default {
install(Vue) {
Vue.prototype.screenShot = async function (dom) {
return await domToImage
.toPng(dom, {bgcolor: '#fff'})
.then((dataUrl) => {
//输出图片的Base64, dataUrl
return base64ImgtoFile(dataUrl, 'image/png');
})
.catch(function (error) {
console.error('oops, something went wrong!', error)
})
}
}
}
Comments | NOTHING