49 lines
1.9 KiB
TypeScript
49 lines
1.9 KiB
TypeScript
import type { ParticleSystem } from '../store/particleStore'
|
|
import { collectSpineExportImages } from './spineConnectorClient'
|
|
import { createZipArchive } from './zipArchive'
|
|
import { translate } from '../i18n'
|
|
|
|
function decodeBase64(value: string) {
|
|
const binary = atob(value)
|
|
const bytes = new Uint8Array(binary.length)
|
|
for (let index = 0; index < binary.length; index++) bytes[index] = binary.charCodeAt(index)
|
|
return bytes
|
|
}
|
|
|
|
function imagesDirectory(value: string) {
|
|
const path = String(value || './images/').replace(/\\/g, '/').replace(/^\.\//, '').replace(/^\/+|\/+$/g, '')
|
|
const parts = path.split('/').filter(Boolean)
|
|
if (!parts.length || parts.some((part) => part === '..' || /^[a-z]+:/i.test(part))) return 'images'
|
|
return parts.join('/')
|
|
}
|
|
|
|
function safeFileName(value: string) {
|
|
const name = String(value || 'SpineParticle').replace(/\.json$/i, '').replace(/[\\/:*?"<>|]+/g, '_').replace(/^\.+/, '')
|
|
return name || 'SpineParticle'
|
|
}
|
|
|
|
export async function buildSpineImagesArchive(input: { systems: ParticleSystem[]; imagesPath: string }) {
|
|
const images = await collectSpineExportImages(input.systems)
|
|
if (!images.length) throw new Error(translate('errors.noExportableImages'))
|
|
const folder = imagesDirectory(input.imagesPath)
|
|
const blob = createZipArchive(images.map((image) => ({
|
|
name: `${folder}/${image.path}`,
|
|
data: decodeBase64(image.dataBase64),
|
|
})))
|
|
return { blob, imageCount: images.length, folder }
|
|
}
|
|
|
|
export function downloadSpineImagesArchive(blob: Blob, exportFileName: string) {
|
|
const fileName = `${safeFileName(exportFileName)}-images.zip`
|
|
const url = URL.createObjectURL(blob)
|
|
const anchor = document.createElement('a')
|
|
anchor.href = url
|
|
anchor.download = fileName
|
|
anchor.style.display = 'none'
|
|
document.body.appendChild(anchor)
|
|
anchor.click()
|
|
anchor.remove()
|
|
setTimeout(() => URL.revokeObjectURL(url), 1000)
|
|
return fileName
|
|
}
|