图示
DiagramExportMenu 导出菜单
把图带走:PNG、JPEG、WebP、SVG,以及 1200×630 的分享卡。
来自@misoto22/design/diagrams
什么时候用它
示例
default
2 elements and 1 relationships.
- CloudFront (cloud) — CDN
- API (backend) — FastAPI
- CloudFront → API: HTTPS
说明
把图从页面上带走:五个文件,一个菜单。
为什么是菜单自己干活而不是抛回一个格式名:这些导出里的每一个都是同样的六步——找到 <svg>,用 getComputedStyle 遍历它、把自定义属性烘成真实颜色,序列化,栅格化,给文件命名,交给浏览器——它们之间只有最后两步不同。一个抛出 'png'、剩下的留给调用方的菜单,会变成一个每个使用者都要重写一遍、而且都写不对的菜单;而最难的那一半(序列化后的 SVG 里 var(--ink) 解析成空,图整个是隐形的)正是调用方不会知道要写的那一半。
onExport 仍然留着,给自带管线的页面用——服务端渲染、另一种画幅——传了它,下面的一切就都变成空转。
每种格式到底是什么,说清楚而不是暗示。
SVG 是颜色已解析的原始图形。它可编辑,也是唯一无损的一种,但它不带 Web 字体:一台没有这些字族的机器会用回退字体渲染,字形度量会不一样。
PNG、JPEG 和 WebP 是浏览器自己的栅格化器按 2 倍重画那份 SVG。不是截图——抗锯齿,以及页面样式表从 <svg> 外面施加的任何效果,都不在里面。JPEG 没有 alpha 通道,所以它会被压平到解析出来的纸色上,而不是压到黑色上——后者正是一张透明 PNG 被交给一个不支持透明的格式时会变成的样子。
分享卡是一个 1200 × 630 的画幅,标题印在上面,整张图以留边方式装进去——绝不裁切。一张为了填满画幅而裁切的卡片,是另一张图的照片。
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| targetRef必填 | RefObject<HTMLElement | SVGSVGElement | null> | 要导出的 `<svg>`,或者一个恰好包含一个 `<svg>` 的元素。 用 ref 而不是选择器,因为一个页面可能放着好几张图,而选择器会导出文档里最先撞上的那一张。 | |
| title必填 | string | 给文件命名,同时印在分享卡上。 | |
| className | string | — | |
| onExport | (format: ExportFormat) => void | Promise<void> | 代替内置导出运行——给自带管线的调用方用。 | |
| onResult | (result: ExportResult) => void | 把发生了什么告诉页面,好让它弹一条提示。 | |
| trigger | ReactNode | 替换触发器。 |
组成部分
Composed at the call site rather than configured through props, so a layout this component did not anticipate is still expressible.
exportFigure
一张图、一种格式、一个文件。
导出出来,是为了让页面能把一个快捷键或它自己的按钮接到菜单做的同一件事上,而不必把那六步重写一遍。
这个组件没有自己的属性。
类型
export type ExportFormat = 'png' | 'jpeg' | 'webp' | 'svg' | 'share-card'无障碍
- 导出失败会通过 onResult 报出来而不是被吞掉:一次悄无声息的点击,和一个坏掉的按钮是分不出来的。