Skip to content

Export 模块(导出)

Export 模块封装了下载和打开到 xTool Studio 的能力,不涉及计费。计费由 billing 模块负责,通过 withBilling() 组合使用。

API 列表

方法返回值说明
sdk.export.register(provider)void注册导出能力提供者(初始化时调用一次)
sdk.export.download(options?)Promise<ExportDownloadResult>下载图片到本地
sdk.export.openInStudio(source? | options?)Promise<ExportOpenInStudioResult>打开到 xTool Studio

注册导出提供者

重要

使用 download()openInStudio() 前必须先调用 register(),否则抛出错误。

Provider 必须至少实现 getExportDatagetExportCanvas 其中之一。

SDK 支持两种 provider 方法(优先级:getExportData > getExportCanvas):

  • getExportData — 灵活方式,适合非 canvas 场景(SVG 编辑器、DOM 截图、纯数据生成等)
  • getExportCanvas — 传统方式,直接返回 HTMLCanvasElement

示例:Canvas 场景(传统方式)

typescript
sdk.export.register({
  getExportCanvas: (purpose) => {
    // purpose: 'download' | 'studio' | 'cover'
    return document.getElementById('outputCanvas') as HTMLCanvasElement
  },
  getFileName: (purpose) => `my-design-${Date.now()}.png`,
})

示例:SVG / 非 canvas 场景(灵活方式)

typescript
sdk.export.register({
  getExportData: (purpose, format) => {
    if (format === 'svg') {
      const svgEl = document.getElementById('svgCanvas')
      return { type: 'svg', svgString: new XMLSerializer().serializeToString(svgEl) }
    }
    // 位图格式:将 SVG 渲染到临时 canvas
    const canvas = renderSvgToCanvas()
    return { type: 'canvas', canvas }
  },
  getFileName: (purpose) => `my-design-${Date.now()}.svg`,
})

ExportProvider 接口

typescript
interface ExportProvider {
  getExportData?: (
    purpose: ExportPurpose,
    format: ExportFormat,
  ) => ExportData | Promise<ExportData | null> | null

  getExportCanvas?: (
    purpose: ExportPurpose,
  ) => HTMLCanvasElement | Promise<HTMLCanvasElement | null> | null

  getFileName?: (purpose: ExportPurpose) => string
}

type ExportPurpose = 'download' | 'studio' | 'cover'
type ExportFormat = 'png' | 'jpeg' | 'webp' | 'svg'

type ExportData =
  | { type: 'canvas'; canvas: HTMLCanvasElement }
  | { type: 'blob'; blob: Blob }
  | { type: 'dataUrl'; dataUrl: string }
  | { type: 'url'; url: string }
  | { type: 'svg'; svgString: string }

解析优先级:

  1. 如果实现了 getExportData 且返回非 null 值,使用它
  2. 否则回退到 getExportCanvas
  3. 两者都无法获取数据时抛出 SdkError

下载到本地

支持 pngjpegwebpsvg 四种格式。

typescript
// 下载 PNG(默认)
const result = await sdk.export.download({
  fileName: 'my-design.png',
  format: 'png',
})
// { success: true, fileName: 'my-design.png' }

// 下载 JPEG 并指定质量
await sdk.export.download({
  fileName: 'my-design.jpg',
  format: 'jpeg',
  quality: 0.85,
})

// 下载 SVG(需要 provider 实现 getExportData 返回 SVG 数据)
await sdk.export.download({
  fileName: 'my-design.svg',
  format: 'svg',
})

SVG 导出限制

无法从 HTMLCanvasElement 导出 SVG。如果你的 provider 只实现了 getExportCanvas,请求 format: 'svg' 时会抛出错误。

要支持 SVG 导出,请实现 getExportData 并返回 { type: 'svg', svgString: '...' }

内部流程:

  1. 优先调用 getExportData(purpose, format) 获取导出数据
  2. 若未实现则回退到 getExportCanvas(purpose)canvas.toBlob(mimeType, quality)
  3. 生成 Blob → 创建 <a> 标签触发浏览器下载 → 清理

打开到 xTool Studio

openInStudio() 的作用是把内容导入到 xTool Studio。

支持两种调用方式(向后兼容):

typescript
// 原有方式:直接传图片源
await sdk.export.openInStudio('https://example.com/design.png')
await sdk.export.openInStudio(myBlob)

// 新方式:传 options 对象,可指定导入格式
await sdk.export.openInStudio({ format: 'svg' })
await sdk.export.openInStudio({ source: myBlob, format: 'png' })

// 无参数:通过 provider 获取 PNG(默认)
await sdk.export.openInStudio()

ExportOpenInStudioOptions

typescript
interface ExportOpenInStudioOptions {
  source?: ExportOpenInStudioSource  // URL / data URL / Blob / File
  format?: ExportFormat              // 默认 'png'
}

传入 source 时直接使用(行为与之前一致)。未传 source 时,SDK 根据 format 参数调用 provider 的 getExportDatagetExportCanvas 获取数据。

重要

调用 openInStudio() 前,用户必须先通过登录 SDK 完成登录。

原因是这个能力依赖登录后的 token 完成上传流程;如果用户未登录,导入到 xTool Studio 将无法正常完成。

typescript
// 默认:通过 provider 获取 PNG
const result = await sdk.export.openInStudio()
// { success: true }

// 直接传远程图片 URL
await sdk.export.openInStudio('https://example.com/design.png')

// SVG 格式:provider 产出 SVG,Studio 接收 type 'SVG'
await sdk.export.openInStudio({ format: 'svg' })

// 显式传入 source + format
await sdk.export.openInStudio({ source: myFile, format: 'png' })

内部流程:

  1. 如果 source 是 HTTP URL,直接传给 Studio
  2. 如果 source 是图片数据(data URL / Blob / File),先上传到 OSS
  3. 如果未传 source,根据 format 调用 provider → 生成 Blob → 上传到 OSS
  4. SVG 格式在 Studio 协议中使用 type: 'SVG',其他格式使用 type: '2D'
  5. 在 iframe 中运行时,通过 postMessage 通知父页面
  6. 降级处理:打开新窗口显示图片

MIT Licensed