npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

dom-snap-x

v1.0.4

Published

Out-of-the-box web screenshot library: pixel-perfect page reproduction with maps, charts and other complex content fully supported

Readme

Dom Snap X 网页截图库

English | 中文

开箱即用的网页截图方案。像素级还原页面真实效果,地图、图表等复杂内容照常出现在截图里。

安装

npm install dom-snap-x

CDN(用于快速试用):

<script src="dom-snap-x/lib/dom-snap-x.umd.js"></script>
<script>
  const canvas = await DomSnapX.captureViewport()
</script>

引入本包对 SSR 安全——引入阶段不会触碰任何浏览器 API;截图本身在浏览器中运行。

基础截图

import { captureViewport } from 'dom-snap-x'

const canvas = await captureViewport()

高清输出

放大输出可让文字更清晰,地图页面建议使用 scale: 2。

const canvas = await captureViewport({ scale: 2 })

剔除部分元素

传入不想出现在截图里的元素选择器(悬浮按钮、提示条等),页面本身不受影响。

const canvas = await captureViewport({
  hideSelectors: '.float-btn, .toast'
})

这些选择器在同源 iframe 内部同样生效。

含地图的页面

当页面包含由 canvas 绘制的地图时,同时传入地图元素与已捕获的地图画面,地图即可完整出现在结果里。

const canvas = await captureViewport({
  scale: 2,
  mapCanvas: document.querySelector('#map canvas'),
  mapImageUrl: mapImageDataUrl  // 单独捕获的地图画面 dataURL
})

地图位于同源 iframe 内部时,使用与 iframeImages 相同的分层写法——{ 0: ... } 指向页面中的第 1 个 iframe:

const canvas = await captureViewport({
  mapCanvas: { 0: iframe0.contentDocument.querySelector('#map canvas') },
  mapImageUrl: { 0: iframe0MapImageDataUrl }
})

截取页面中的某个元素

如果不想截整个视口,只想截某个卡片、表格或弹窗,直接传入该元素即可。

import { captureElement, captureElementSvg } from 'dom-snap-x'

// 输出 canvas,尺寸自动跟随元素外框
const canvas = await captureElement(document.querySelector('.report-card'), {
  scale: 2,
  background: '#fff'   // 元素自身透明时的衬底颜色
})

// 输出可无损缩放的 SVG(矢量)
const svg = await captureElementSvg(document.querySelector('.report-card'))

元素是隔离渲染:元素自身的样式、伪元素、主题变量、图片、图标、canvas、同源 iframe 均与视口截图同等保真;只有落在被截子树之外的祖先相关规则无法还原(如祖先在外的 .parent .child,或由 flex 父容器分配来的宽高)。

注意:元素内的 vw / vh 按真实浏览器视口换算,而不是元素自身的盒子,因此使用 2.5vw 这类流式尺寸的卡片会保持它在页面上的比例。

iframe

同源 iframe 无需任何配置——会以与页面相同的分辨率截取并精确回填。

跨域 iframe 受浏览器同源策略限制无法读取其 DOM,任何纯前端方案都无法绕过。用 iframeImages 按序号传入它们的画面:

const canvas = await captureViewport({
  iframeImages: {
    0: 'data:image/png;base64,...',            // 页面中的第 1 个 iframe
    1: { url: 'data:image/png;base64,...' }    // 第 2 个(可带 width / height 指定尺寸)
  }
})

iframe 内再嵌 iframe 时往下多写一层——例如页面中第 1 个 iframe 内部的第 2 个 iframe:

const canvas = await captureViewport({
  iframeImages: { 0: { 1: 'data:image/png;base64,...' } }
})

跨域资源(图片 / 字体 / 样式表)

跨域且无 CORS 的图片、字体、样式表无法被浏览器读取,默认会被替换为占位图或跳过。可用 resourceInterceptor 接管这些资源:

const canvas = await captureViewport({
  resourceInterceptor: async (url, type) => {
    // type: 'image' | 'css-image' | 'stylesheet'
    if (type === 'stylesheet') return (await myProxy.text(url))  // 返回 CSS 文本
    return await myProxy.dataUrl(url)                            // 返回 dataURL(Blob 也可以)
  }
})

返回非空即采用;返回 null / undefined 表示不接管该资源,抛错同样视为「不接管」。

自定义尺寸

const canvas = await captureViewport({
  width: 1920,   // 宽
  height: 1080   // 高
})

输出格式

所有入口共用同一套输出格式,通过 format 选择,默认 canvas:

| format | 返回 | 说明 | | --- | --- | --- | | canvas(默认) | HTMLCanvasElement | 自行转成任意格式 | | svg | string | SVG dataURL,矢量输出,可无损缩放 | | png | string | PNG dataURL(无损) | | jpeg | string | JPEG dataURL(有损,支持 quality) | | webp | string | WebP dataURL(有损,支持 quality) | | blob | Blob | PNG 格式 Blob,便于直接上传 |

const png = await captureViewport({ format: 'png', scale: 2 })
const jpg = await captureElement(el, { format: 'jpeg', quality: 0.85 })
const svg = await captureElement(el, { format: 'svg' })  // 或使用 captureElementSvg(el)
const blob = await captureViewport({ format: 'blob' })

quality(0-1)仅对 jpeg / webp 生效,不传则使用浏览器默认值;传入未知格式会抛错。

svg 下 scale 只影响结果中图标的清晰度(矢量内容本身无损放大)。

导出图片

拿到 canvas(默认格式)后,自行导出:

// PNG(无损)
const png = canvas.toDataURL('image/png')

// JPEG(更小,可控制质量)
const jpg = canvas.toDataURL('image/jpeg', 0.85)

// 下载
const a = document.createElement('a')
a.href = png
a.download = 'screenshot.png'
a.click()

能力探测与回退

正式使用前先探测环境,不支持时切换到自己的回退方案。

import { canCapture, captureViewport } from 'dom-snap-x'

if (await canCapture()) {
  const canvas = await captureViewport({ scale: 2 })
} else {
  // 你自己的回退截图方案
}

错误与告警

错误——会抛出,且提示写明要改什么:

| 情形 | 行为 | | --- | --- | | format 不是支持的取值 | 抛出 | | hideSelectors 选择器语法无效 | 抛出 | | captureElement 收到非元素,或 <html>(截整页请用 captureViewport) | 抛出 | | 目标元素不可见(如 display: none) | 抛出 | | 请求的输出尺寸无法产出(罕见) | 抛出 |

告警——截图仍返回可用结果,同时在控制台打印一条警告:

| 情形 | 行为 | | --- | --- | | 请求的 scale 超出浏览器可分配的最大尺寸 | 自动收敛到可用的最大值;导出仍然成功,只是比请求的更小 | | 某个 iframe 无法自动截取,且未通过 iframeImages 提供画面(跨域,或嵌套层数超过支持上限) | 该区域以空白呈现 | | 页面的某一部分无法导出 | 仍返回可用截图,该部分缺失,并打印一条告警 |

把告警理解为「图可用,但有一部分降级了」。

API 参考

Dom Snap X —— 开箱即用的网页截图库。像素级还原页面真实效果;地图、图表等复杂内容照常出现在截图里;无弹窗、无扩展、无第三方服务;内网 http 环境直接可用;完全本地运行、零依赖。

按需选择入口:captureViewport 截取当前视口(推荐入口,支持完整参数);captureElement / captureElementSvg 截取任意元素(canvas / 矢量 SVG);canCapture 是可选的环境探测(供需要回退方案的调用方使用)。TypeScript 类型声明随包提供。

| API | 说明 | | --- | --- | | captureViewport | 截取当前视口(推荐入口,支持完整参数) | | captureElement | 截取任意 DOM 子树(元素本身) | | captureElementSvg | 截取任意 DOM 子树并输出 SVG dataURL(矢量,语法糖) | | canCapture | 能力探测:当前浏览器环境是否可用于截图 |

输出格式(format)统一为 canvas / svg / png / jpeg / webp / blob;返回类型随之不同,默认 canvas。

captureViewport

captureViewport(opts)

截取当前视口(推荐入口,支持完整参数)。返回类型由 opts.format 决定,默认 Promise<HTMLCanvasElement>。当前版本聚焦视口截图(不做整页长图),列表滚动内容按当前显示状态截取。

| 参数 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | opts | object | — | 选项对象 | | opts.scale | number | 1 | 放大倍数(2 = 两倍清晰度) | | opts.hideSelectors | string | string[] | 无 | 需要从截图中剔除的元素选择器(如全屏遮罩) | | opts.mapCanvas | HTMLCanvasElement | object | null | null | 页面中的地图 canvas 元素(画面由 mapImageUrl 提供);地图位于同源 iframe 内时用分层写法(与 iframeImages 同构) | | opts.mapImageUrl | string | object | null | null | 地图当前帧 dataURL(不传则地图区域为空);地图位于同源 iframe 内时用分层写法 | | opts.iframeImages | Array | Map | object | null | 跨域 iframe 的画面(下标/键 = iframe 在页面中的序号;嵌套层用嵌套写法);仅在自动截取失败时启用 | | opts.format | string | canvas | 输出格式:canvas / svg / png / jpeg / webp / blob | | opts.quality | number | 浏览器默认 | 编码质量(0-1),仅对 jpeg / webp 生效 | | opts.resourceInterceptor | Function | null | 外部资源钩子:接管跨域图片 / 字体 / 样式表 | | opts.width | number | 视口宽 | 输出宽度 | | opts.height | number | 视口高 | 输出高度 |

captureElement

captureElement(el, opts)

截取任意 DOM 子树(元素本身)。返回类型由 opts.format 决定,默认 Promise<HTMLCanvasElement>。输出尺寸自动跟随元素实测外框。元素是隔离渲染,因此依赖祖先的布局与选择器无法还原。

| 参数 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | el | Element | — | 目标元素(需已挂载在文档上) | | opts.scale | number | 1 | 放大倍数 | | opts.hideSelectors | string | string[] | 无 | 需要从截图中剔除的元素选择器 | | opts.background | string | transparent | 衬底背景色(元素自身透明时用) | | opts.mapCanvas | HTMLCanvasElement | object | null | null | 元素内的地图 canvas 元素(画面由 mapImageUrl 提供);地图位于同源 iframe 内时用分层写法(与 iframeImages 同构) | | opts.mapImageUrl | string | object | null | null | 地图当前帧 dataURL(不传则该区域可能为黑);地图位于同源 iframe 内时用分层写法 | | opts.iframeImages | Array | Map | object | null | 跨域 iframe 的画面(下标/键 = iframe 在元素内的序号;嵌套层用嵌套写法) | | opts.format | string | canvas | 输出格式:canvas / svg / png / jpeg / webp / blob | | opts.quality | number | 浏览器默认 | 编码质量(0-1),仅对 jpeg / webp 生效 | | opts.resourceInterceptor | Function | null | 外部资源钩子:接管跨域图片 / 字体 / 样式表 |

captureElementSvg

captureElementSvg(el, opts)

截取任意 DOM 子树并输出 SVG dataURL(矢量),返回 Promise<string>——等价于 captureElement(el, { ...opts, format: 'svg' }) 的语法糖;参数与 captureElement 相同,但 format 固定为 svg,quality 不适用。相比 canvas:矢量可无损缩放,且不受画布尺寸上限限制,导出一定成功;代价是外链资源在通过 <img> 加载的 SVG 里不会加载(同源资源已随产物一并打包,取不到的仍按占位图处理)。

canCapture

canCapture(timeoutMs)

能力探测:当前浏览器环境是否可用于截图。返回 Promise<boolean>——超时或失败返回 false,调用方据此回退到其它截图方案。

| 参数 | 类型 | 说明 | | --- | --- | --- | | timeoutMs | number | 探测超时(默认 45s) |

文档

  • 离线文档包:文档站首页的「下载文档包」按钮可下载 dom-snap-x-apis.zip(两份 README 全文,含中英文完整 API 参考);npm 包内随附两份 README

许可

MIT