snapDOM is a high-fidelity DOM capture tool, developed as part of the animation engine for Zumly — a framework for creating smooth zoom-based view transitions.
It converts any HTML element into a scalable SVG image, preserving styles, fonts, backgrounds, shadow DOM content, pseudo-elements, and more.
- 📸 Full DOM capture
- 🎨 Embedded styles, pseudo-elements, and fonts
- 🖼️ Export to SVG, PNG, JPG, WebP, or
canvas
- ⚡ Lightweight, no dependencies
- 📦 100% based on standard Web APIs
You can use snapDOM by including it via CDN, script tag, or by importing it as a module.
<script src="https://unpkg.com/@zumer/snapdom@latest/snapdom.min.js"></script>
<script src="snapdom.js"></script>
The global object snapdom
will be available.
import { snapdom } from './snapdom.mjs';
<script type="module">
import { snapdom } from 'https://unpkg.com/@zumer/snapdom@latest/snapdom.mjs';
</script>
Now you can call snapdom(el)
, snapdom.toPng(el)
, etc., directly in your JavaScript.
// Capture an element as SVG Data URL
const svgDataUrl = await snapdom(document.querySelector("#myElement"));
// Insert the captured image into the page
const img = new Image();
img.src = svgDataUrl;
document.body.appendChild(img);
The main API is exposed as snapdom
and offers multiple capture methods:
Method | Description | Returns |
---|---|---|
snapdom(el, scale?) |
Captures as SVG Data URL | Promise<string> |
snapdom.toImg(el, scale?) |
Captures as HTMLImageElement (SVG) |
Promise<HTMLImageElement> |
snapdom.toCanvas(el, scale?) |
Captures as HTMLCanvasElement
|
Promise<HTMLCanvasElement> |
snapdom.toPng(el, scale?) |
Captures as PNG image (Image ) |
Promise<HTMLImageElement> |
snapdom.toJpg(el, scale?, quality?) |
Captures as JPG image (Image ) |
Promise<HTMLImageElement> |
snapdom.toWebp(el, scale?, quality?) |
Captures as WebP image (Image ) |
Promise<HTMLImageElement> |
snapdom.toBlob(el, scale?) |
Captures as SVG Blob
|
Promise<Blob> |
Parameters:
-
el
: DOM element to capture. -
scale
: Scale factor (default is1
). -
quality
: Compression quality for JPG/WebP (range0
–1
).
-
Shadow DOM: Captures content inside Web Components and
shadowRoot
. -
Pseudo-elements: Captures
::before
and::after
, including background images. - Backgrounds and images: Inlines external images as Data URLs.
- Fonts: Replicates applied font families without needing external font files.
-
Placeholder and Exclusion:
-
data-capture="exclude"
: Skips an element while preserving layout space. -
data-capture="placeholder"
+data-placeholder-text="Text"
: Replaces an element with decorative placeholder text.
-
<div id="captureMe">
<h1 style="color: tomato;">Hello World!</h1>
<p>This content will be captured.</p>
</div>
<script type="module">
import { snapdom } from './snapdom.esm.js';
const button = document.createElement('button');
button.textContent = "Capture";
button.onclick = async () => {
const img = await snapdom.toPng(document.getElementById('captureMe'), 2);
document.body.appendChild(img);
};
document.body.appendChild(button);
</script>
- External images must be CORS-accessible.
- Fonts must be fully loaded before capturing (
document.fonts.ready
is automatically awaited). - Iframes are not captured.
snapDOM
is not only highly accurate — it's also extremely fast at capturing large or complex DOM structures.
In benchmark tests against popular libraries:
Element Size | Winner | Compared to modern-screenshot
|
Compared to html2canvas
|
---|---|---|---|
200×100 (Small) | modern-screenshot |
1.18× faster | 4.46× faster |
400×300 (Modal) | snapDOM |
1.04× faster | 4.07× faster |
1200×800 (Page view) | snapDOM |
2.43× faster | 5.74× faster |
2000×1500 (Large scroll area) | snapDOM |
5.02× faster | 9.35× faster |
4000×2000 (Very large) | snapDOM |
11.35× faster | 15.98× faster |
✅ Key insight:
While modern-screenshot
is yet slightly faster for very small elements, snapDOM dramatically outperforms all others as the DOM size grows.
✅ Perfect for:
- Capturing full-page views
- Capturing modal windows
- Complex layouts with custom fonts, backgrounds, or shadow DOM
MIT © Juan Martín Muda - Zumerlab