- 官网:https://zumerlab.github.io/snapdom/
- Github:https://github.com/zumerlab/snapdom
- 在线演示:https://zumerlab.github.io/snapdom/
在前端开发中,网页截图是个常用功能。从前,html2canvas
是大家的常客,但随着网页越来越复杂,它的性能问题也逐渐暴露,速度慢、占资源,用户体验不尽如人意
好在,现在有了 SnapDOM,一款性能超棒、还原度超高的截图新秀,能完美替代 html2canvas
,让截图不再是麻烦事
什么是 SnapDOM
SnapDOM 就是一个专门用来给网页元素截图的工具。它能把 HTML 元素快速又准确地存成各种图片格式,像 SVG
、PNG
、JPG
、WebP
等,还支持导出为 Canvas
元素
它最厉害的地方在于,能把网页上的各种复杂元素,比如 CSS 样式、伪元素、Shadow DOM
、内嵌字体、背景图片,甚至是动态效果的当前状态,都原原本本地截下来,跟直接看网页没啥两样
SnapDOM 优势
快得飞起
测试数据显示,在不同场景下,SnapDOM
都把 html2canvas
和 dom-to-image
这俩老前辈远远甩在身后:
尤其在超大元素(4000×2000)截图时,速度是 html2canvas
的 93.31 倍,比 dom-to-image
快了 133.12 倍。这速度,简直就像坐火箭
还原度超高
SnapDOM 截图出来的效果,跟在网页上看到的一模一样。
各种复杂的 CSS
样式、伪元素、Shadow DOM
、内嵌字体、背景图片,还有动态效果的当前状态,都能精准还原
格式任你选
不管是想要矢量图 SVG
,还是常用的 PNG
、JPG
,或者现代化的 WebP
,又或者是需要进一步处理的 Canvas
元素,SnapDOM 都能满足
怎么用 SnapDOM
安装
用 NPM
:
npm i @zumer/snapdom
用 CDN
:
<script src="https://unpkg.com/@zumer/snapdom@latest/dist/snapdom.min.js"></script>
基础用法示例
一键截图
import { snapdom } from '@zumer/snapdom'
const card = document.querySelector('.user-card');
const image = await snapdom.toPng(card);
document.body.appendChild(image);
高级配置
const element = document.querySelector('.chart-container');
const capture = await snapdom(element, {
scale: 2,
backgroundColor: '#fff',
embedFonts: true,
compress: true
});
const png = await capture.toPng();
const jpg = await capture.toJpg({ quality: 0.9 });
await capture.download({
format: 'png',
filename: 'chart-report-2024'
});
这儿可以对截图进行各种配置。比如 scale
能调整清晰度,backgroundColor
能设置背景色,embedFonts
可以内嵌字体,compress
能压缩优化。配置好后,还能把截图存成不同格式,或者直接下载到本地
和其他库对比
和 html2canvas
、dom-to-image
比起来,SnapDOM
的优势很明显:
特性 | SnapDOM | html2canvas | dom-to-image |
---|---|---|---|
性能 | ⭐⭐⭐⭐⭐ | ⭐⭐ | ⭐ |
准确度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐ |
文件大小 | 极小 | 较大 | 中等 |
依赖 | 无 | 无 | 无 |
SVG 支持 | ✅ | ❌ | ✅ |
Shadow DOM 支持 | ✅ | ❌ | ❌ |
维护状态 | 活跃 | 活跃 | 停滞 |
用的时候注意点
用 SnapDOM
时,有几点得注意:
跨域资源
要是截图里有外部图片等跨域资源,得确保这些资源支持 CORS
,不然截不出来
iframe 限制
SnapDOM 不能截 iframe
内容,这是浏览器的安全限制,没办法
Safari 浏览器兼容性
在 Safari 里用 WebP
格式时,会自动变成 PNG。
大型页面截图
截超大页面时,建议分块截,不然可能会内存溢出
常见使用场景
社交分享
async function shareAchievement() {
const card = document.querySelector('.achievement-card');
const image = await snapdom.toPng(card, { scale: 2 });
navigator.share({
files: [new File([await snapdom.toBlob(card)], 'achievement.png')],
title: '我获得了新成就!'
});
}
报表导出
async function exportReport() {
const reportSection = document.querySelector('.report-section');
await preCache(reportSection);
await snapdom.download(reportSection, {
format: 'png',
scale: 2,
filename: `report-${new Date().toISOString().split('T')[0]}`
});
}
海报导出
async function generatePoster(productData) {
document.querySelector('.poster-title').textContent = productData.name;
document.querySelector('.poster-price').textContent = `¥${productData.price}`;
document.querySelector('.poster-image').src = productData.image;
await new Promise((resolve) => setTimeout(resolve, 100));
const poster = document.querySelector('.poster-container');
const blob = await snapdom.toBlob(poster, { scale: 3 });
return blob;
}