@mybricks/dom-to-figma-clipboard
v0.1.0
Published
将浏览器 DOM 直接转换为 Figma 剪贴板协议,粘贴即可生成设计稿
Readme
dom-to-figma
将浏览器 DOM 直接转换为 Figma 剪贴板协议,粘贴即可生成设计稿,无需 Figma 插件。
安装
npm install需要 Node.js ≥ 14 或现代浏览器(Chrome 90+)。
快速上手
方式一:npm require(webpack / Node.js 环境)
const { domToFigmaClipboard } = require('dom-to-figma');
// el 是目标 DOM 元素
const html = await domToFigmaClipboard(el, {
styleTagId: 'my-style-tag', // 可选,传入声明层 <style> id 可提升样式精度
fontCtx: fontCtx, // 可选,见「字体」章节
});
// 写入剪贴板后前往 Figma Cmd+V 粘贴
await writeHtmlToClipboard(html);方式二:浏览器 script 标签注入(控制台调试)
把 src/ 目录下的 JS 文件逐个以 <script> 注入页面(或在控制台 fetch 后 eval),最后注入 index.js:
// 注入顺序(浏览器 eval 模式)
// dom-helpers.js → css-parsers.js → style-builder.js → layout-utils.js
// → node-builder.js → image-inline.js → src/dom-to-json.js
// → src/ir-to-figma-clipboard.js(需提前加载 pako / kiwi-schema)
// → index.js
// 注入完成后直接调用:
const html = await window.domToFigmaClipboard(document.querySelector('#my-el'));API
domToFigmaClipboard(el, options?) → Promise<string>
| 参数 | 类型 | 说明 |
|------|------|------|
| el | Element | 目标 DOM 元素 |
| options.styleTagId | string? | 声明层 <style> 标签 id,有则传,没有也能工作 |
| options.fontCtx | object? | opentype 字体上下文(见下方「字体」章节) |
| options.componentLibraryEnabled | boolean? | 是否输出组件库节点,默认 false |
返回可直接写入剪贴板的 HTML 字符串。
domToFigmaJson(el, options?) → Promise<object>
只返回中间 IR JSON,不生成剪贴板协议,适合调试或二次加工。
字体
调用 domToFigmaClipboard 时字体会自动加载,无需手动传入任何参数。
加载来源优先级:
- 系统本地字体(Chrome 103+,调用时浏览器会弹出权限请求)
window.__PINGFANG_FONT_URL__(可提前设置为可访问的字体文件 URL,作为兜底)- 以上均失败 → 跳过字体加载,Figma 里文本需双击后才显示
// 方式一:什么都不用做,字体自动加载
const html = await domToFigmaClipboard(el);
// 方式二:提前设置字体 URL(推荐在生产环境中使用,避免依赖本地字体权限)
window.__PINGFANG_FONT_URL__ = 'https://your-cdn.com/fonts/PingFangSC-Regular.ttf';
const html = await domToFigmaClipboard(el);
// 方式三:提前预热字体(避免第一次导出时的等待),在页面初始化时调用
import { preloadFont } from 'dom-to-figma';
preloadFont(); // 后台加载,不需要 await
// 方式四:完全跳过字体(明确知道不需要文字立即显示时)
const html = await domToFigmaClipboard(el, { fontCtx: null });写入剪贴板
async function writeHtmlToClipboard(html) {
// 优先使用 Clipboard API
if (navigator.clipboard && window.ClipboardItem) {
await navigator.clipboard.write([
new ClipboardItem({
'text/html': new Blob([html], { type: 'text/html' }),
'text/plain': new Blob([html], { type: 'text/plain' }),
})
]);
return;
}
// 降级:execCommand
const listener = (e) => {
e.preventDefault();
e.clipboardData.setData('text/html', html);
e.clipboardData.setData('text/plain', html);
};
document.addEventListener('copy', listener);
document.execCommand('copy');
document.removeEventListener('copy', listener);
}文件结构
dom-to-figma/
├── index.js # 包入口,暴露公共 API
├── package.json
├── README.md
└── src/
├── dom-to-json.js # DOM → IR JSON(含图片内联)
├── dom-helpers.js # Shadow DOM / 坐标系工具
├── css-parsers.js # CSS 解析(渐变、阴影、SVG 路径…)
├── style-builder.js # 样式 JSON 构建
├── layout-utils.js # Flex / Grid 布局处理
├── node-builder.js # 节点构建(伪元素、形状…)
├── image-inline.js # 图片 URL → base64 内联
├── font-loader.js # 自动加载 PingFang SC 字体
├── ir-to-figma-clipboard.js # IR JSON → Figma 剪贴板二进制
├── figma-schema-data.js # Figma kiwi schema(预编译数据)
└── svg-pathdata-umd.js # SVG 路径处理工具注意事项
- 必须在浏览器中运行,依赖
getBoundingClientRect、getComputedStyle等 DOM API。 - 图片内联会发起跨域请求,确保服务端允许 CORS 或图片与页面同域。
- Figma 剪贴板协议基于逆向工程,Figma 更新版本后可能需要同步维护
figma-schema-data.js。
