拓冰建站拓冰建站
首页 / 资讯中心 / 正文

dom-to-image 完整使用指南:用 JavaScript 把任意 DOM 节点渲染成 SVG/PNG/JPEG 图片

前端【免费下载链接】dom-to-imageGenerates an image from a DOM node using HTML5 canvas项目地址https://gitcode.com/gh_mirrors/do/dom-to-image点击查看免费下载本指南以仓库根目录的 README.md 为主体结合 src/dom-to-image.js 源码与 spec/dom-to-image.spec.js 测试用例系统讲解 dom-to-image 的安装方式、五大顶层 API、全部渲染选项、底层工作原理与浏览器兼容性限制。读完本文你将掌握如何在自己的页面中把任意 DOM 节点导出为可下载的图片、如何精细化控制渲染结果过滤节点、设置背景色、注入样式、JPEG 压缩质量等并能理解其基于 SVGforeignObject的渲染管线在源码层面的实现细节。一、项目定位它解决什么问题dom-to-image 是一个纯 JavaScript 编写的库能够把任意 DOM 节点转换为矢量图SVG或位图PNG、JPEG。它脱胎于 Paul Bakaus 的 domvas 项目并被完全重写修复了部分 bug同时新增了对web 字体web font和图片的支持见 README.md。从 package.json 与 bower.json 的元数据可以看出项目当前版本为2.6.0描述为Generates an image from a DOM node using HTML5 canvas and SVG关键字覆盖dom、image、raster、render、html、canvas、svg。源码零运行时依赖dependencies为空所有依赖仅用于测试与构建。典型应用场景包括网页内容导出为图片分享、报表/图表卡片下载、截取特定区域生成缩略图、把表单或预览区保存为 PNG 等。二、安装与引入2.1 通过 NPM 安装npm install dom-to-image安装后按模块方式加载/* 在 ES6 环境中 */ import domtoimage from dom-to-image; /* 在 ES5 / CommonJS 环境中 */ var domtoimage require(dom-to-image);2.2 通过 Bower 安装bower install dom-to-imageBower 安装后页面中引入src/dom-to-image.js或dist/dom-to-image.min.js压缩版由 Grunt 的 uglify 任务生成见 Gruntfile.js脚本会把domtoimage变量挂载到全局作用域script srcpath/to/dom-to-image.min.js/script script domtoimage.toPng(node); // ... /script2.3 全局变量还是模块源码 src/dom-to-image.js 中的导出逻辑决定了两种使用方式可以共存if (typeof module ! undefined) module.exports domtoimage; else global.domtoimage domtoimage;即在存在moduleCommonJS/Node 环境时走模块导出否则挂到全局。ES6 的import语法经由打包器编译后同样能正常使用。三、API 概览五个顶层函数所有顶层函数都接受两个参数DOM 节点与渲染选项对象并返回一个Promise成功时以对应的data URLtoBlob例外返回 Blob兑现。函数清单与实现位置对应如下函数返回内容源码位置toSvg(node, options)SVG 图片的 data URLsrc/dom-to-image.jstoPng(node, options)PNG 图片的 data URLsrc/dom-to-image.jstoJpeg(node, options)JPEG 图片的 data URLsrc/dom-to-image.jstoBlob(node, options)PNG 图片的 Blobsrc/dom-to-image.jstoPixelData(node, options)RGBA 像素数据Uint8Arraysrc/dom-to-image.js从源码可以推断toPng、toJpeg、toBlob、toPixelData均通过内部draw()辅助函数src/dom-to-image.js先走toSvg渲染链路再把 SVG 加载为Image绘制到离屏 canvas 上最终差异化输出。以toJpeg为例src/dom-to-image.jsfunction toJpeg(node, options) { options options || {}; return draw(node, options) .then(function (canvas) { return canvas.toDataURL(image/jpeg, options.quality || 1.0); }); }JPEG 的quality参数在这里被透传给canvas.toDataURL()。3.1 获取 PNG data URL 并立即展示var node document.getElementById(my-node); domtoimage.toPng(node) .then(function (dataUrl) { var img new Image(); img.src dataUrl; document.body.appendChild(img); }) .catch(function (error) { console.error(oops, something went wrong!, error); });3.2 获取 PNG Blob 并触发下载配合 FileSaver.js 之类的工具保存文件domtoimage.toBlob(document.getElementById(my-node)) .then(function (blob) { window.saveAs(blob, my-node.png); });toBlob内部优先使用canvas.toBlob在不支持该 API 的浏览器中回退到atobUint8Array手工构造 Blob见 src/dom-to-image.js。3.3 生成压缩 JPEG 并下载domtoimage.toJpeg(document.getElementById(my-node), { quality: 0.95 }) .then(function (dataUrl) { var link document.createElement(a); link.download my-image-name.jpeg; link.href dataUrl; link.click(); });3.4 生成 SVG data URL 并过滤节点function filter(node) { return (node.tagName ! i); } domtoimage.toSvg(document.getElementById(my-node), {filter: filter}) .then(function (dataUrl) { /* do something */ });3.5 获取原始像素数据RGBAtoPixelData返回一个Uint8Array其中每 4 个数组元素代表一个像素的 RGBA 值var node document.getElementById(my-node); domtoimage.toPixelData(node) .then(function (pixels) { for (var y 0; y node.scrollHeight; y) { for (var x 0; x node.scrollWidth; x) { pixelAtXYOffset (4 * y * node.scrollHeight) (4 * x); /* pixelAtXY 是一个 Uint8Array[4]包含 (x, y) 处像素的 RGBA 值范围 0..255 */ pixelAtXY pixels.slice(pixelAtXYOffset, pixelAtXYOffset 4); } } });在 spec/dom-to-image.spec.js 的toPixelData测试中会逐像素断言 RGBA 通道的精确数值可作为理解像素布局的参考实现。toPixelData的源码实现src/dom-to-image.js通过canvas.getContext(2d).getImageData(...)读取指定尺寸范围内的数据。说明domtoimage.impl下的所有函数util、inliner、fontFaces、images等不是公开 API仅在源码中为单元测试暴露见 src/dom-to-image.js 与 README.md。测试文件确实直接调用了domtoimage.impl.inliner.impl.readUrls等内部方法见 spec/dom-to-image.spec.js。四、渲染选项详解结合源码所有顶层函数共享同一套渲染选项。下面逐项说明并对照源码给出实现细节。4.1 filter类型Function接收 DOM 节点作为参数语义返回true表示该节点应包含在输出中排除某节点意味着同时排除其所有子节点不会对根节点调用源码中cloneNode的入口src/dom-to-image.jsfunction cloneNode(node, filter, root) { if (!root filter !filter(node)) return Promise.resolve(); ... }测试用例spec/dom-to-image.spec.js分别验证了按 class 过滤掉.omit节点和即使 filter 对任何节点都返回 false根节点仍被渲染两种行为印证了不作用于根节点的语义。4.2 bgcolor类型String任意合法的 CSS 颜色值作用渲染前设置克隆节点的背景色它在两处生效src/dom-to-image.js 的applyOptions与 src/dom-to-image.js 的newCanvasif (options.bgcolor) clone.style.backgroundColor options.bgcolor; // ... if (options.bgcolor) { var ctx canvas.getContext(2d); ctx.fillStyle options.bgcolor; ctx.fillRect(0, 0, canvas.width, canvas.height); }即不仅 SVG 克隆节点会带背景色最终绘制 PNG/JPEG 的 canvas 也会先填充该颜色作为底。测试spec/dom-to-image.spec.js对toPng与toSvg均验证了bgcolor: #ff0000的输出。4.3 height、width类型Number单位像素作用渲染前应用到节点上的宽高if (options.width) clone.style.width options.width px; if (options.height) clone.style.height options.height px;同时toSvg会用它们作为 SVG 画布的尺寸src/dom-to-image.jsmakeSvgDataUri(clone, options.width || util.width(node), options.height || util.height(node) );util.width/util.height的默认计算会累加节点scrollWidth/scrollHeight与左右/上下边框宽度src/dom-to-image.js。测试 spec/dom-to-image.spec.js 验证了width: 200, height: 200的输出尺寸。4.4 style类型Object作用渲染前把对象属性逐个拷贝到克隆节点的 style 上CSS 属性需使用 JavaScript 命名如background-color写作backgroundColor或按示例中的字符串形式if (options.style) Object.keys(options.style).forEach(function (property) { clone.style[property] options.style[property]; });测试 spec/dom-to-image.spec.js 用style: { background-color: red, transform: scale(0.5) }验证了注入样式的效果并与width/height组合使用spec/dom-to-image.spec.js实现缩放导出。4.5 quality类型Number取值 01如0.92表示 92% 质量仅对 JPEG 有效默认1.0100%源码中直接透传canvas.toDataURL(image/jpeg, options.quality || 1.0)src/dom-to-image.js测试quality: 0.5会与低质量控制图对比spec/dom-to-image.spec.js4.6 cacheBust类型Boolean默认false作用设为true时在资源请求 URL 后追加当前时间戳查询串以绕过缓存源码实现在getAndEncodesrc/dom-to-image.jsif(domtoimage.impl.options.cacheBust) { // 追加时间戳避免因缓存产生 CORS 问题 url ((/\?/).test(url) ? : ?) (new Date()).getTime(); }4.7 imagePlaceholder类型String占位图的 data URL作用当某个图片资源获取失败时用该占位图替代默认undefined此时图片加载失败会直接报错fail fastcopyOptionssrc/dom-to-image.js会把这两个选项拷贝到domtoimage.impl.options供内部模块读取getAndEncode在请求失败或超时30 秒见 src/dom-to-image.js时根据是否有占位图决定 resolve 占位图内容还是打印错误并 resolve 空字符串src/dom-to-image.js。五、工作原理8 步渲染管线dom-to-image 的核心思路是利用 SVG 的foreignObject标签可以在其中嵌入任意 HTML 内容的特性。整体流程README.md如下均可与源码对应递归克隆原始 DOM 节点——cloneNodesrc/dom-to-image.js按子节点顺序串行克隆并追加到克隆父节点上计算并拷贝样式—— 对每个节点用window.getComputedStyle(original)取计算样式通过cssTextChrome 支持或逐属性拷贝Firefox 回退路径写入克隆节点src/dom-to-image.js重建伪元素pseudo-elements——::before、::after不会被克隆因此为每个有content的伪元素生成一个随机 class注入一个内联style块src/dom-to-image.js嵌入 web 字体——embedFontssrc/dom-to-image.js配合newFontFacessrc/dom-to-image.js遍历document.styleSheets读取所有CSSRule.FONT_FACE_RULE规则解析src中的url()下载字体文件并 base64 内联为data:URL最后把处理后的全部 CSS 规则拼接进一个style元素挂到克隆节点上嵌入图片——inlineImagessrc/dom-to-image.js配合newImagessrc/dom-to-image.js把img元素的src与 CSSbackground属性中的图片 URL 全部内联为 data URL已经是data:URL 的跳过序列化克隆节点为 XML——new XMLSerializer().serializeToString(node)src/dom-to-image.js包装进foreignObject与svg并生成 data URL——makeSvgDataUrisrc/dom-to-image.js构造data:image/svgxml;charsetutf-8,...期间通过escapeXhtml把#转义为%23、换行转义为%0A对应 README 提到的#字符处理测试见 spec/dom-to-image.spec.js可选绘制到离屏 canvas——drawsrc/dom-to-image.js用util.makeImage加载 SVG经util.delay(100)等待 100ms 后绘制到新创建的 canvas 上再导出 PNG/JPEG/Blob/像素数据其中util.getAndEncodesrc/dom-to-image.js是资源获取的核心用XMLHttpRequestresponseType: blob拉取字体与图片再经FileReader.readAsDataURL转成 base64最终由dataAsUrl拼出data:mime;base64,contentsrc/dom-to-image.jsMIME 类型通过 URL 扩展名映射表推断src/dom-to-image.js。inlinersrc/dom-to-image.js负责用url(...)正则定位并逐个替换 CSS 中的资源引用相对 URL 会先用util.resolveUrl基于样式表所在 base URL 解析为绝对地址。六、浏览器支持与依赖6.1 浏览器兼容性在撰写 README 时项目在**最新版 Chrome 和 Firefox分别为 49 与 45**上测试通过Chrome 在处理大型 DOM 树时性能明显更好可能得益于其更高效的 SVG 支持以及对CSSStyleDeclaration.cssText属性的支持README.md不支持 Internet Explorer且未来也不会支持因为它不支持 SVGforeignObject标签Safari 不支持因其对foreignObject标签采用更严格的安全模型README 建议的替代方案是使用toSvg并在服务端完成渲染README.md6.2 依赖要求运行时源码仅依赖浏览器标准能力需确保浏览器支持PromiseREADME.mdSVGforeignObject标签测试环境则依赖以下组件README.mdjs-imagediff对比渲染结果与控制图如spec中imagediff.equal(...)的用法ocrad.js在因浏览器渲染差异无法直接对比图片时用 OCR 校验文本是否被正确渲染assertTextRendered借助 Tesseract见 spec/dom-to-image.spec.js七、注意事项与已知问题若待渲染节点包含已绘制内容的canvas元素一般可以正常处理但如果 canvas 被跨域图片tainted污染渲染大概率失败README.md。源码中makeNodeCopy对HTMLCanvasElement会先toDataURL()再转成图片src/dom-to-image.js被污染的 canvas 调用toDataURL会直接抛 SecurityError撰写 README 时Firefox 对部分外部样式表存在问题issue #13此时错误会被捕获并记录日志不会中断渲染对应源码getCssRules中的 try/catch见 src/dom-to-image.js测试 spec/dom-to-image.spec.js 验证了外部样式表加载出错时不应崩溃表单控件的用户输入不会被 DOM 克隆天然携带因此源码用copyUserInput显式同步textarea与input的值src/dom-to-image.js测试见 spec/dom-to-image.spec.js内嵌 SVG 需要补xmlns命名空间SVGrect的宽高属性需要转写为样式属性fixSvgsrc/dom-to-image.js对应测试见 spec/dom-to-image.spec.js八、运行测试与构建项目使用Grunt Karma Mocha/Chai作为测试与构建工具链Gruntfile.js 定义了三个任务jshint静态检查Gruntfile.js、src/**/*.js、spec/**/*.js、karma单次运行单元测试、uglify把 src/dom-to-image.js 压缩为dist/dom-to-image.min.jsgrunt test只跑测试gruntdefault依次执行 jshint、test、uglifykarma.conf.js 配置了测试框架mocha chai、浏览器Chrome 与 Firefox并发数为 1、静态资源服务spec/resources/**、fontawesome 字体与样式以及测试用脚本jquery、js-imagediff、tesseract、src/dom-to-image.js、spec/dom-to-image.spec.jspackage.json 中npm test等价于执行grunt test测试资源spec/resources/下的 html/css/控制图由 karma 静态伺服浏览器端测试通过loadTestPage加载后执行回归断言覆盖了 SVG/PNG/JPEG/Blob 渲染、边框、滚动节点、文本节点、伪元素、filter、外部样式表、web 字体、图片与背景图、textarea/input 用户输入、canvas 内容、bgcolor、像素数据、尺寸与样式组合等场景。九、作者与许可证dom-to-image 由Anatolii Saienko编写原始创意来自 Paul Bakausdomvas。项目以MIT许可证开源见 LICENSE 与 README.md。# 克隆仓库进行源码阅读与本地测试 git clone https://gitcode.com/gh_mirrors/do/dom-to-image.git克隆后进入仓库根目录依次执行npm install、bower install安装依赖即可通过npm test或grunt运行测试与构建深入验证本文所述的行为。赞分享前端【免费下载链接】dom-to-imageGenerates an image from a DOM node using HTML5 canvas项目地址https://gitcode.com/gh_mirrors/do/dom-to-image点击查看免费下载相关推荐完整指南使用dom-to-image轻松实现DOM转图片功能完整指南使用dom to image轻松实现DOM转图片功能 dom to image是一个强大的JavaScript库专门用于将网页中的DOM节点转换为高前端Google Research Language核心功能详解从BERT到REALM的自然语言处理革命Google Research Language核心功能详解从BERT到REALM的自然语言处理革命 Google Research Language项目是G深度学习NLP大模型人工智能Saber手写笔记应用跨平台数字笔记的终极解决方案Saber手写笔记应用跨平台数字笔记的终极解决方案 在数字化时代你是否还在寻找一款真正尊重手写体验的笔记应用Saber作为一款专为手写优化的跨平台开源应用移动开发桌面应用跨平台创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门