导出能力 Export
注册 export 生命周期钩子,平台会在用户点击「导出」或「Open in Studio」时调用你的生成器并获取结果文件。返回值统一为 { filename, blob },支持任意文件格式(图片、SVG、3D 模型、PDF 等)。
放置导出按钮
导出按钮由你在应用内自己放置——在页面任意位置写一个带 data-atomm-export-button 的元素,SDK 会就地把它渲染成平台受控的 Export 下拉(下载 / Open in Studio + 积分提示)。点击只经平台触发:
<div data-atomm-export-button></div>
- 位置与外层定位由你控制(如
position: fixed固定在角落);一页可放多个,各自独立水合。 - 按钮渲染在 Shadow DOM 里做样式隔离;换肤只用文档化的
--atomm-export-*CSS 变量(在该元素或任意祖先上设置,自动继承进按钮):
[data-atomm-export-button] {
--atomm-export-bg: #d32f2f; /* 按钮底色 */
--atomm-export-radius: 0; /* 圆角 */
--atomm-export-width: 200px; /* 宽度:px 或 100% 填满容器 */
--atomm-export-height: 40px; /* 高度 */
}
| 变量 | 默认值 | 控什么 |
|---|---|---|
--atomm-export-bg / -bg-hover / -bg-active | #070b10 / #252c36 / #1c2129 | 按钮三态底色 |
--atomm-export-color | #fff | 按钮文字色 |
--atomm-export-width | auto(贴内容) | 按钮宽度(px 或 100% 填满容器,下限 24px) |
--atomm-export-height | 32px | 按钮高度(px 或 100%,下限 24px) |
--atomm-export-radius | 8px | 圆角 |
--atomm-export-font / -font-size | Inter, system-ui, sans-serif / 14px | 字体 / 字号 |
--atomm-export-menu-bg / -menu-color / -menu-hover-bg | #fff / #111 / #f4f4f5 | 下拉菜单配色 |
--atomm-export-menu-radius / -menu-shadow | 8px / 0 4px 16px rgba(16,24,40,.12) | 菜单圆角 / 阴影 |
--atomm-export-z | 1000 | 下拉浮层层级 |
仅上表这些
--atomm-export-*变量是受支持的定制面;按钮内部 class 随时可能变化,请勿依赖。
导出按钮及其下载 / Open in Studio / 积分提示都由 atomm 平台驱动,只有当生成器运行在 atomm 环境里才生效——线上平台,或开发工具的本地预览(?local=)。
若脱离 atomm 单独打开生成器(如直接开本地 HTML),按钮可能照常显示,但点击不会产出文件、也不显示计费状态——这是设计如此,并非 bug。请始终用本地预览或线上平台来验证导出。
按钮上的免费次数 / 积分提示
按钮会自动显示当前计费状态(由平台下发,你无需干预):
| 形态 | 显示 | 含义 |
|---|---|---|
| 免费时段 | 30s 倒计时 | 一次导出成功后赠送的一小段时间,期内导出不计费 |
| 免费次数 | 免费 3/3 | 剩余 / 总免费次数 |
| 消耗积分 | 积分币 + 数字 | 免费用尽后每次导出消耗的积分数 |
本地调试(
?local=),点击导出不会真实扣费,刷新页面即重置。
注册 export hook
atomm.lifecycle.on('export', async () => {
// 触发时不传入任何参数,handler 自行读取当前生成结果并产出一个 Blob
const blob = await exportCurrentResultAsBlob()
if (!blob) {
throw new Error('请先生成作品后再下载')
}
return {
filename: 'my-generator.glb', // 含扩展名,决定下载文件名与 Open in Studio 的资产类型
blob, // 任意格式的 Blob;MIME 取自 blob.type
}
})
返回值字段
| 字段 | 类型 | 说明 |
|---|---|---|
| filename | string | 下载文件名,必须含扩展名(如 design.glb),且不含路径分隔符 / \ |
| blob | Blob | 任意格式的文件内容,单文件 ≤ 100MB;MIME 取自 blob.type,为空时按文件名扩展名兜底 |
多文件导出(可选)
handler 也可以返回一个文件数组,平台会把它们打成一个 zip 下载:
atomm.lifecycle.on('export', async () => [
{ filename: 'model.glb', blob: glbBlob },
{ filename: 'preview.png', blob: pngBlob },
])
| 规则 | 说明 |
|---|---|
| zip 文件名 | 取数组中第一个文件的主名(model.glb → model.zip) |
| 同名文件 | 自动去重为 name (1).ext |
| 大小上限 | 所有文件字节总和 ≤ 100MB,超出整体失败 |
| 数组长度 1 | 直接下载该文件,不套 zip |
| Open in Studio | 支持多文件——返回的文件全部交给 Studio 打开,不限制格式;Studio 不支持的格式由 Studio 端提示。多文件导入需 xTool Studio 1.8+;单文件兼容旧版本 |
单文件仍用
{ filename, blob };多文件用数组。返回数组中任一项不合规(非 Blob / 文件名无扩展名等)整体判为无效。
怎么得到 Blob
几乎任何导出源都能一行转成 Blob:
| 你手里的东西 | 转 Blob |
|---|---|
| Canvas(2D 图) | canvas.toBlob(cb, 'image/png') |
| SVG 字符串 / 文本 / JSON | new Blob([str], { type: 'image/svg+xml' }) |
| ArrayBuffer / 3D 网格(glb/stl…) | new Blob([buffer], { type: 'model/gltf-binary' }) |
| 已有 data URL / 远程 URL | await (await fetch(x)).blob() |
<input type=file> 的 File | 直接用(File 本就是 Blob) |
导出数据统一用 Blob 承载,支持任意格式——Blob 能原样保存任意文件类型的二进制内容。
filename 必须带扩展名且不含路径分隔符;文件超过 100MB 或返回值不是合法 { filename, blob } 时,平台会判为无效、导出失败并提示。
下载支持任意格式落盘。「Open in Studio」会把文件交给 xTool Studio 打开——平台不预判格式,Studio 不支持的格式会由 Studio 端自行提示。
导出按钮对所有生成器开放(在应用里放 data-atomm-export-button 即出现)。用户点击导出时若你未注册 export hook,平台会得到「应用未提供下载方法」——提交审核会因此被驳回。凡是支持导出的生成器都必须注册该 hook,可在本地预览中点「导出」自测是否正常产出文件。