find the global maximum dimensions across all actions

This commit is contained in:
Dennis Postma 2025-03-12 13:46:51 +01:00
parent 36c9522e8a
commit 9f42d1e59d

View File

@ -71,12 +71,43 @@ export default class SpriteUpdateEvent extends BaseEvent {
await this.spriteRepository.getEntityManager().removeAndFlush(existingAction)
}
// Process each action
// First pass: find the global maximum dimensions across all actions
let globalMaxWidth = 0
let globalMaxHeight = 0
// Extract all image metadata to find global maximums
for (const actionData of actionsData) {
if (actionData.sprites.length === 0) continue
// Generate and save the sprite sheet
const frameDimensions = await this.generateAndSaveSpriteSheet(actionData.sprites, sprite.getId(), actionData.action)
const imagesData = await Promise.all(
actionData.sprites.map(async (sprite) => {
const base64Data = sprite.url.split(';base64,').pop()
if (!base64Data) throw new Error('Invalid base64 image')
const buffer = Buffer.from(base64Data, 'base64')
const metadata = await sharp(buffer).metadata()
return {
width: metadata.width || 0,
height: metadata.height || 0
}
})
)
// Update global maximums with this action's maximums
const actionMaxWidth = Math.max(...imagesData.map((data) => data.width), 0)
const actionMaxHeight = Math.max(...imagesData.map((data) => data.height), 0)
globalMaxWidth = Math.max(globalMaxWidth, actionMaxWidth)
globalMaxHeight = Math.max(globalMaxHeight, actionMaxHeight)
}
// Process each action using the global maximum dimensions
for (const actionData of actionsData) {
if (actionData.sprites.length === 0) continue
// Generate and save the sprite sheet using global dimensions
const frameDimensions = await this.generateAndSaveSpriteSheet(actionData.sprites, sprite.getId(), actionData.action, globalMaxWidth, globalMaxHeight)
if (!frameDimensions) return false
// Create and save sprite action
@ -103,11 +134,11 @@ export default class SpriteUpdateEvent extends BaseEvent {
}
}
private async generateAndSaveSpriteSheet(sprites: SpriteImage[], spriteId: string, action: string): Promise<{ frameWidth: number; frameHeight: number } | null> {
private async generateAndSaveSpriteSheet(sprites: SpriteImage[], spriteId: string, action: string, maxWidth: number, maxHeight: number): Promise<{ frameWidth: number; frameHeight: number } | null> {
try {
if (sprites.length === 0) return { frameWidth: 0, frameHeight: 0 }
// Extract image data and get image metadata
// Extract image data
const imagesData = await Promise.all(
sprites.map(async (sprite) => {
const base64Data = sprite.url.split(';base64,').pop()
@ -129,10 +160,6 @@ export default class SpriteUpdateEvent extends BaseEvent {
return null
}
// Calculate the maximum width and height to use for all frames
const maxWidth = Math.max(...imagesData.map((data) => data.width))
const maxHeight = Math.max(...imagesData.map((data) => data.height))
// Create frames of uniform size with the original sprites centered
const uniformFrames = await Promise.all(
imagesData.map(async (imageData) => {
@ -185,7 +212,7 @@ export default class SpriteUpdateEvent extends BaseEvent {
await fs.promises.mkdir(dir, { recursive: true })
await fs.promises.writeFile(`${dir}/${action}.png`, spriteSheet)
// Return the uniform frame dimensions
// Return the uniform frame dimensions (now global maximum dimensions)
return {
frameWidth: maxWidth,
frameHeight: maxHeight