JSPM

  • Created
  • Published
  • Downloads 82929
  • Score
    100M100P100Q177417F
  • License MIT

snapDOM captures DOM elements as images with exceptional speed and minimal overhead. Designed to avoid bottlenecks and long tasks.

Package Exports

  • @zumer/snapdom

Readme

snapDOM

snapDOM is a fast and accurate DOM capture tool to images developed for Zumly, a WIP framework that enables 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
  • ⚑ Ultra fast, no dependencies
  • πŸ“¦ 100% based on standard Web APIs

Installation

You can use snapDOM via NPM, CDN, script tag, or by importing as a module.

NPM / Yarn

npm i @zumer/snapdom
yarn add @zumer/snapdom

CDN

<script src="https://unpkg.com/@zumer/snapdom@latest/dist/snapdom.min.js"></script>

Script tag (local)

<script src="snapdom.js"></script>

The global object snapdom will be available.

ES Module

import { snapdom } from './snapdom.mjs';

Script Tag (Type Module)

<script type="module">
  import { snapdom } from 'https://unpkg.com/@zumer/snapdom@latest/dist/snapdom.mjs';
</script>

Now you can call snapdom(el), snapdom.toPng(el), etc., directly in your JavaScript.

Basic usage

// Capture an element as <img> tag
const el = document.querySelector("#myElement")
const img = await snapdom.toImg(el);

document.body.appendChild(img);

API

Note: API may evolve until v1.0.0!

The main API is exposed as snapdom and offers multiple capture methods:

Method Description
snapdom(el, options?) Captures as SVG Data URL
snapdom.toImg(el, options?) Captures as HTMLImageElement (SVG)
snapdom.toCanvas(el, options?) Captures as HTMLCanvasElement
snapdom.toPng(el, options?) Captures as PNG image (Image)
snapdom.toJpg(el, options?) Captures as JPG image (Image)
snapdom.toWebp(el, options?) Captures as WebP image (Image)
snapdom.toBlob(el, options?) Captures as SVG Blob
preCache(root?, options?) Preload resources for faster and more accurate captures

Options

You can pass an options object to control the behavior of all capture methods:

Option Type Default Description
compress boolean true Removes default styles to reduce size and deduplicate CSS where possible.
fast boolean true Skips requestIdleCallback delays and executes preparation immediately.
embedFonts boolean false Inlines external fonts as Data URLs (except icon fonts, which are always embedded).
scale number 1 Multiplies the output resolution without affecting layout size.
backgroundColor string "#fff" Used when exporting to JPG or WebP formats (which don't support transparency).
quality number 1 Compression quality for JPG/WebP, between 0 and 1.

preCache() – Optional helper

The preCache() function can be used to load external resources (like images and fonts) in advance.

import { preCache } from '@zumer/snapdom';

await preCache(document.body, {
  embedFonts: true,
  preWarm: true
});
import { snapdom, preCache } from './snapdom.mjs';
    window.addEventListener('load', async () => {
    await preCache();
  console.log('πŸ“¦ Resources preloaded');
    });

Options for preCache():

  • embedFonts (boolean, default: true) β€” Inlines non-icon fonts during preload.
  • reset (boolean, default: false) β€” Clears all existing internal caches.
  • preWarm (boolean, default: true) β€” Runs a fake capture in memory to warm up styles, fonts and layout detection.

Special features

  • 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 requiring external font files.

  • Icon fonts: Captures icon fonts like Font Awesome and Material Icons.

  • Placeholder and Exclusion:

    • data-capture="exclude": Skips an element while preserving layout space.
    • data-capture="placeholder" + data-placeholder-text="Text": Replaces an element with placeholder text.

Now with improved fidelity and even faster performance.

Full example

<div id="captureMe">
  <h1 style="color: tomato;">Hello World!</h1>
  <p>This content will be captured.</p>
</div>

<button id="captureBtn">Capture as img</button>

<script type="module">
  import { snapdom } from './snapdom.mjs';

  const button = document.getElementById('captureBtn');
  button.addEventListener('click', async () => {
    const target = document.getElementById('captureMe');
    const img = await snapdom.toJpg(target, { quality: 0.5});
    document.body.appendChild(img);
  });
</script>

Limitations

  • External images must be CORS-accessible.
  • Iframes are not captured.

Please if you find a bug open an issue.

Benchmarks

snapDOM is not only highly accurate β€” it’s extremely fast.

Latest benchmarks show significant performance improvements against other libraries:

Scenario vs. modern-screenshot vs. html2canvas
Small element (200Γ—100) 6.46Γ— faster 32.27Γ— faster
Modal size (400Γ—300) 7.28Γ— faster 32.66Γ— faster
Page view (1200Γ—800) 13.17Γ— faster 35.29Γ— faster
Large scroll area (2000Γ—1500) 38.23Γ— faster 68.85Γ— faster
Very large element (4000Γ—2000) 93.31Γ— faster 133.12Γ— faster
Complex small element (200Γ—100) 3.97Γ— faster 15.23Γ— faster
Complex modal (400Γ—300) 2.32Γ— faster 5.33Γ— faster
Complex page (1200Γ—800) 1.62Γ— faster 1.65Γ— faster
Complex large scroll (2000Γ—1500) 1.66Γ— faster 1.24Γ— faster
Complex very large (4000Γ—2000) 1.52Γ— faster 1.28Γ— faster

Run the benchmarks

To run these benchmarks yourself:

git clone https://github.com/zumerlab/snapdom.git
cd snapdom
npm install
npm run test:benchmark

They execute in headless Chromium using real DOM nodes.

License

MIT Β© Zumerlab