导出优化

This commit is contained in:
tianmo committed 2026-09-05 18:45:43 +08:00
1 parent 72d8daa283
commit 79ce3165c1
17 files changed
+1559 -1291

No files matched your search

+26 -3
View File
@@ -1002,6 +1002,7 @@ import ColorGradientEditor from './ColorGradientEditor.vue'
import ImageResourceCard from './ImageResourceCard.vue'
import SpineObjectPanel from '../spine/SpineObjectPanel.vue'
import { downloadEditorConfig, loadEditorConfigFile, loadEditorConfigText } from '../editor/editorConfig'
import { beginTransfer, readResponseTextWithProgress } from '../editor/transferProgress'
import { defaultSpineExportSettings, ensureSpineExportSettings } from '../export/spineExportSettings'
import { buildSpineJson, downloadSpineJson } from '../export/spineJsonExporter'
import { validateSpineJson } from '../export/spineJsonValidator'
@@ -1112,15 +1113,24 @@ async function loadSelectedPreset() {
presetLoading.value = true
configError.value = false
configMessage.value = '正在加载预设…'
const transfer = beginTransfer('加载预设', `正在下载 ${file}…`)
try {
await transfer.paint()
const response = await fetch(`/Preset/${encodeURIComponent(file)}`, { cache: 'no-store' })
if (!response.ok) throw new Error(`无法读取预设:${file}`)
await loadEditorConfigText(store, await response.text())
const text = await readResponseTextWithProgress(response, (progress) => {
transfer.update(progress == null ? null : progress * 55, `正在下载 ${file}…`)
})
transfer.update(58, '正在解析预设配置…')
transfer.update(70, '正在解析并恢复预设资源…')
await loadEditorConfigText(store, text)
configMessage.value = `已加载预设:${file.replace(/\.json$/i, '')}`
await transfer.finish('预设加载完成')
} catch (error) {
configError.value = true
const message = error instanceof Error ? error.message : String(error)
configMessage.value = `${message},请检查预设文件命名`
await transfer.fail(message)
} finally {
presetLoading.value = false
selectedPreset.value = ''
@@ -1146,7 +1156,7 @@ function nextPaint() {
return new Promise<void>((resolve) => requestAnimationFrame(() => resolve()))
}
async function prepareExportFrames() {
async function prepareExportFrames(onProgress?: (progress: number) => void) {
store.timeline.playing = false
store.timeline.frame = 0
store.timeline.recorded = false
@@ -1158,8 +1168,10 @@ async function prepareExportFrames() {
const deadline = performance.now() + Math.max(8000, expectedMs * 2.5 + 3000)
while (!store.timeline.recorded) {
if (performance.now() > deadline) throw new Error('重新计算动画超时,请确认页面仍在运行后重试')
onProgress?.(Math.min(0.98, store.timeline.frame / Math.max(1, store.timeline.totalFrames - 1)))
await new Promise((resolve) => setTimeout(resolve, 50))
}
onProgress?.(1)
}
async function exportSpineJson() {
@@ -1192,8 +1204,11 @@ async function exportSpineProject() {
exportError.value = false
connectorPairUrl.value = ''
exportMessage.value = '正在重新计算粒子动画…'
const transfer = beginTransfer('导出 Spine 包', '正在重新计算粒子动画…')
try {
await prepareExportFrames()
await transfer.paint()
await prepareExportFrames((progress) => transfer.update(progress * 18, '正在重新计算粒子动画…'))
transfer.update(20, '正在生成 Spine JSON…')
const result = buildSpineJson({ systems: store.systems as unknown as ParticleSystem[], timeline: store.timeline, settings: exportSettings.value })
validateSpineJson(result.text, exportSettings.value.spineVersion)
exportMessage.value = '正在整理图片并调用本机 Spine…'
@@ -1203,15 +1218,23 @@ async function exportSpineProject() {
spineVersion: exportSettings.value.spineVersion,
skeletonJson: result.text,
systems: store.systems as unknown as ParticleSystem[],
}, ({ phase, progress }) => {
if (phase === 'images') transfer.update(progress == null ? null : 22 + progress * 18, '正在整理工程图片…')
else if (phase === 'upload') transfer.update(progress == null ? null : 40 + progress * 30, '正在上传数据到 Spine 连接器…')
else if (phase === 'processing') transfer.update(null, 'Spine 正在转换工程,请稍候…')
else transfer.update(progress == null ? null : 82 + progress * 16, '正在下载生成的 Spine 工程包…')
})
transfer.update(99, '正在交给浏览器下载…')
downloadSpineProject(converted.blob, converted.fileName)
exportMessage.value = `已生成 ${converted.fileName}:包含 .spine 工程和 ${converted.imageCount} 张图片,Spine ${converted.spineEditorVersion}`
await refreshConnectorHealth()
await transfer.finish('Spine 工程包已开始下载')
} catch (error) {
exportError.value = true
if (error instanceof SpineConnectorError && error.pairUrl) connectorPairUrl.value = error.pairUrl
exportMessage.value = error instanceof Error ? error.message : String(error)
await refreshConnectorHealth()
await transfer.fail(exportMessage.value)
} finally {
exportBusy.value = false
exportTarget.value = null