一、前言
html2Canvas 是一个 JavaScript 库,用于将 HTML 元素渲染为图像。它可以在前端将网页的某个区域或整个页面转换为图像,从而实现快照留存的功能。
二、概念解读
html2Canvas 通过遍历指定的 HTML 元素,将其内容转换为 Canvas 元素,然后将 Canvas 元素转换为图像。这个图像可以被保存到本地或上传到服务器。
html2Canvas 支持复杂的 CSS 样式,包括背景图片、渐变、阴影等。
三、使用场景
-
页面截图:可以将整个页面或特定区域生成图像,用于生成预览图、分享到社交媒体等。
-
数据报告:将数据以图像形式展示,方便保存和分享。
-
幻灯片制作:将网页内容转换为图像,用于制作幻灯片或演示文稿。
四、注意事项
-
同源限制:由于安全策略,HTML2Canvas 不能直接截图跨域的内容。
-
样式兼容性:HTML2Canvas 虽然支持大多数 CSS 样式,但对某些 CSS 属性的解析可能存在差异。
-
图像导出:导出的图像可能比实际显示的样式稍有差异,可以通过调整分辨率或使用 CSS 修复样式问题。
五、举例说明
下面是一个封装了 html2Canvas 功能的 JavaScript 函数,并支持配置不同的选项:
function captureSnapshot(element, options) {
// 默认配置
const defaultOptions = {
uploadToServer: false,
saveLocally: false,
targetElement: null,
debounceDelay: 200,
throttleDelay: 300,
onClone: null,
};
// 合并选项
const config = Object.assign({}, defaultOptions, options);
// 元素变化防抖处理
const debounceUpdateSnapshot = debounce(() => {
html2canvas(element, {
onclone: (clone) => {
if (config.onClone) {
config.onClone(clone);
}
return fixStyles(clone);
},
}).then((canvas) => {
if (config.uploadToServer) {
// 将图像上传到服务器
uploadToServer(canvas.toDataURL());
}
if (config.saveLocally) {
// 保存图像到本地
saveLocally(canvas.toDataURL());
}
});
}, config.debounceDelay);
// 滚动监听截流处理
const throttleUpdateSnapshot = throttle(debounceUpdateSnapshot, config.throttleDelay);
// 初始化时生成快照
debounceUpdateSnapshot();
// 监听元素变化并生成快照
const targetElement = config.targetElement || element;
targetElement.addEventListener('scroll', throttleUpdateSnapshot);
targetElement.addEventListener('resize', throttleUpdateSnapshot);
// 修复样式问题
function fixStyles(clone) {
// 在这里对克隆元素的样式进行修复
// 可以根据具体情况进行样式的修改
return clone;
}
// 图像上传到服务器
function uploadToServer(dataUrl) {
// 在这里实现将图像上传到服务器的逻辑
console.log('Uploading to server:', dataUrl);
}
// 图像保存到本地
function saveLocally(dataUrl) {
// 在这里实现将图像保存到本地的逻辑
console.log('Saving locally:', dataUrl);
}
// 防抖函数
function debounce(func, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
// 节流函数
function throttle(func, delay) {
let timer;
let lastCall = 0;
return function (...args) {
const now = new Date().getTime();
if (now - lastCall < delay) {
clearTimeout(timer);
timer = setTimeout(() => {
lastCall = now;
func.apply(this, args);
}, delay);
} else {
lastCall = now;
func.apply(this, args);
}
};
}
}
在上述示例中,captureSnapshot 函数接受一个 HTML 元素和选项对象作为参数。你可以根据需求设置选项,例如是否上传到服务器、是否保存到本地、监听的目标元素、防抖和截流的延迟等。同时,你可以通过 onClone 回调函数来修复样式问题。
六、实战使用
@wenh/snapshot这个 npm 包提供了对前端用户的操作流程进行快照并上传到服务器中留存的封装使用,可以直接在 h5 应用中使用,暂时不支持小程序
安装依赖
npm install @wenh/snapshot
6.1页面入口引入
import snapshot from '@wenh/snapshot';
snapshot({ url: '' // 需要上传的服务地址 });
6.2 snapshot 函数 options 入参说明
| 入参 | 类型 | 是否必传 | 说明 | |
|---|---|---|---|---|
| url | String | 是 | 上传快照到服务器的地址 | |
| debug | Boolean | 否 | 是否开启调试,默认为 false,开启时不会上传快照到服务器,而是直接下载到本地 | |
| on | Function | Boolean | 否 | 异步或同步函数或 boolean 值,控制是否启用前端快照,返回 true 为启用,false-为不启用,默认值为 true |
| hack | Function | 否 | 样式 hack 处理函数,纠正截图样式问题,暴露的参数可以接受到 iframeDocument 元素 | |
| black | Object[] | 否 | 对象数组,通过黑名单列表直接配置设置对应的样式类 | |
| scrollElements | String[] | 否 | 需要监听的哪些元素滚动进行截屏, 如:‘demo-scroll’ 前面不需要带上点号 | |
| data | Object | 否 | 需要上传到服务器的请求附加属性值 |
black对象数组说明
| 入参 | 类型 | 是否必传 | 说明 |
|---|---|---|---|
| className | String | 是 | 需要处理的样式类,如:‘demo’ 前面不需要带上点号 |
| style | Object | 是 | 需要处理的样式,如:{ porision: 'absolute'}, 包含可以设置的属性值遵循元素的样式属性值 |
data请求默认自带的附加属性说明
| 入参 | 类型 | 是否必传 | 说明 |
|---|---|---|---|
| data | Object | 是 | 需要上传图片带的附加信息 |
| 图片文件名称 | Blob | 是 | 需要上传图片的二进制信息, 如:screenshot.screenshot_prod_1.0.0_index_iOS_1690855479677.jpeg: (binary) |
data对象数组说明
| 入参 | 类型 | 是否必传 | 说明 |
|---|---|---|---|
| environment | String | 否 | 环境,生产或测试 |
| clientType | String | 否 | 客户端类型 |
| screenshotTimeStamp | String | 否 | 截图时间戳 |
| moduleVersion | String | 否 | 页面模块版本 |
| module | String | 否 | 页面模块 |
| fileType | String | 否 | 图片类型 |
| routePath | String | 否 | 页面路由 |