名称: snapdom 描述: snapDOM 是一款快速、准确的 DOM 到图像捕获工具,可将 HTML 元素转换为可缩放的 SVG 图像。用于捕获 HTML 元素,将 DOM 转换为图像(SVG、PNG、JPG、WebP),并保留样式、字体和伪元素。
SnapDOM 技能
快速、无依赖的 DOM 到图像捕获库,用于将 HTML 元素转换为可缩放的 SVG 或栅格图像格式。
何时使用此技能
当您需要时,请使用 SnapDOM:
- 将 HTML 元素转换为图像(SVG、PNG、JPG、WebP)
- 捕获带有伪元素和阴影的样式化 DOM
- 导出带有嵌入字体和图标的元素
- 使用自定义尺寸或缩放创建屏幕截图
- 使用代理回退处理 CORS 阻止的资源
- 使用插件实现自定义渲染管道
- 优化大型或复杂元素的性能
主要特性
通用导出选项
- SVG - 可缩放矢量格式,嵌入所有样式
- PNG、JPG、WebP - 可配置质量的栅格格式
- Canvas - 获取原始 Canvas 元素以供进一步处理
- Blob - 用于自定义处理的原始二进制数据
性能
- 超快速捕获(小元素 1.6 毫秒,4000×2000 约 171 毫秒)
- 无依赖 - 仅使用标准 Web API
- 在复杂元素上性能比 html2canvas 快 10-40 倍
样式支持
- 嵌入字体(包括图标字体)
- CSS 伪元素(::before、::after)
- CSS 计数器
- CSS 行截断
- 变换和阴影效果
- Shadow DOM 内容
高级功能
- 同源 iframe 支持
- 用于阻止资源的 CORS 代理回退
- 用于自定义转换的插件系统
- 拉直变换(移除旋转/平移)
- 选择性元素排除
- 紧密边界框计算
安装
NPM/Yarn
npm install @zumer/snapdom
# 或
yarn add @zumer/snapdom
CDN (ES 模块)
<script type="module">
import { snapdom } from "https://unpkg.com/@zumer/snapdom/dist/snapdom.mjs";
</script>
CDN (UMD)
<script src="https://unpkg.com/@zumer/snapdom/dist/snapdom.umd.js"></script>
快速入门示例
基本可重用捕获
// 创建可重用的捕获对象
const result = await snapdom(document.querySelector('#target'));
// 导出为不同格式
const png = await result.toPng();
const jpg = await result.toJpg();
const svg = await result.toSvg();
const canvas = await result.toCanvas();
const blob = await result.toBlob();
// 使用结果
document.body.appendChild(png);
一步导出
// 直接导出,无需中间对象
const png = await snapdom.toPng(document.querySelector('#target'));
const svg = await snapdom.toSvg(element);
下载元素
// 自动下载为文件
await snapdom.download(element, 'screenshot.png');
await snapdom.download(element, 'image.svg');
使用选项
const result = await snapdom(element, {
scale: 2, // 2 倍分辨率
width: 800, // 自定义宽度
height: 600, // 自定义高度
embedFonts: true, // 包含 @font-face
exclude: '.no-capture', // 隐藏元素
useProxy: true, // 启用 CORS 代理
straighten: true, // 移除变换
noShadows: false // 保留阴影
});
const png = await result.toPng({ quality: 0.95 });
基本选项参考
| 选项 | 类型 | 用途 |
|---|---|---|
scale |
数字 | 缩放输出(例如,2 表示 2 倍分辨率) |
width |
数字 | 自定义输出宽度(像素) |
height |
数字 | 自定义输出高度(像素) |
embedFonts |
布尔值 | 包含非图标 @font-face 规则 |
useProxy |
字符串|布尔值 | 启用 CORS 代理(URL 或 true 表示使用默认) |
exclude |
字符串 | 要隐藏元素的 CSS 选择器 |
straighten |
布尔值 | 移除平移/旋转变换 |
noShadows |
布尔值 | 去除阴影效果 |
常见模式
响应式屏幕截图
// 在不同缩放级别下捕获
const mobile = await snapdom.toPng(element, { scale: 1 });
const tablet = await snapdom.toPng(element, { scale: 1.5 });
const desktop = await snapdom.toPng(element, { scale: 2 });
排除元素
// 从捕获中隐藏特定元素
const png = await snapdom.toPng(element, {
exclude: '.controls, .watermark, [data-no-capture]'
});
固定尺寸
// 以特定尺寸捕获
const result = await snapdom(element, {
width: 1200,
height: 630 // 标准社交媒体尺寸
});
CORS 处理
// 对 CORS 阻止资源的回退
const png = await snapdom.toPng(element, {
useProxy: 'https://cors.example.com/?' // 自定义代理
});
插件系统(测试版)
// 使用自定义导出器扩展
snapdom.plugins([pluginFactory, { colorOverlay: true }]);
// 挂钩到生命周期
defineExports(context) {
return {
pdf: async (ctx, opts) => { /* 生成 PDF */ }
};
}
// 可用的生命周期钩子:
// beforeSnap → beforeClone → afterClone →
// beforeRender → beforeExport → afterExport
性能对比
SnapDOM 显著优于 html2canvas:
| 场景 | SnapDOM | html2canvas | 提升 |
|---|---|---|---|
| 小 (200×100) | 1.6ms | 68ms | 快 42 倍 |
| 中 (800×600) | 12ms | 280ms | 快 23 倍 |
| 大 (4000×2000) | 171ms | 1,800ms | 快 10 倍 |
开发
设置
git clone https://github.com/zumerlab/snapdom.git
cd snapdom
npm install
构建
npm run compile
测试
npm test
浏览器支持
- Chrome/Edge 90+
- Firefox 88+
- Safari 14+
- 移动浏览器(iOS Safari 14+、Chrome Mobile)
资源
文档
- 官方网站: https://snapdom.dev/
- GitHub 仓库: https://github.com/zumerlab/snapdom
- NPM 包: https://www.npmjs.com/package/@zumer/snapdom
- 许可证: MIT
scripts/
在此处添加自动化辅助脚本,例如:
batch-screenshot.js- 捕获多个元素pdf-export.js- 将快照转换为 PDFcompare-outputs.js- 比较 SVG 与 PNG 质量
assets/
添加模板和示例:
- 用于常见捕获场景的 HTML 模板
- 预配置 snapdom 的 CSS 框架
- 集成 snapdom 的样板项目
相关工具
- html2canvas - 替代的 DOM 捕获工具(速度较慢但兼容性更好)
- Orbit CSS Toolkit - Zumerlab 的配套工具包 (https://github.com/zumerlab/orbit)
技巧与最佳实践
- 性能:使用
scale而非width/height以获得更好性能 - 字体:设置
embedFonts: true以确保自定义字体正确显示 - CORS 问题:如果图像加载失败,请使用
useProxy: true - 大型元素:将复杂页面拆分为较小的块
- 质量:对于 PNG/JPG,使用
quality: 0.95以获得最佳质量 - SVG 矢量:对于图表和图形,优先选择 SVG 导出
故障排除
元素未渲染
- 检查元素是否具有足够的高度/宽度
- 在捕获前验证 CSS 是否已完全加载
- 如果变换导致问题,请尝试
straighten: false
缺少字体
- 设置
embedFonts: true - 确保在调用 snapdom 之前字体已加载
- 检查浏览器控制台是否有字体加载错误
CORS 问题
- 启用
useProxy: true - 如果默认代理失败,请使用自定义代理 URL
- 检查资源是否来自同一来源
性能问题
- 降低
scale值 - 使用
noShadows: true跳过阴影渲染 - 考虑将大型捕获拆分为较小的部分