Skip to content

Commit

Permalink
autoFit for costumes
Browse files Browse the repository at this point in the history
  • Loading branch information
nighca committed Sep 3, 2024
1 parent 099e7f8 commit b0787b3
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
4 changes: 3 additions & 1 deletion spx-gui/src/components/asset/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export function useAddSpriteFromLocalFile() {
}
await project.history.doAction({ name: actionMessage }, async () => {
project.addSprite(sprite)
await sprite.autoFitCostumes()
await sprite.autoFit()
})
selectAsset(project, sprite)
Expand All @@ -89,8 +90,9 @@ export function useAddCostumeFromLocalFile() {
title: actionMessage,
confirmText: { en: 'Add', zh: '添加' }
})
await project.history.doAction({ name: actionMessage }, () => {
await project.history.doAction({ name: actionMessage }, async () => {
for (const costume of costumes) sprite.addCostume(costume)
await sprite.autoFitCostumes(costumes)
sprite.setDefaultCostume(costumes[0].id)
})
}
Expand Down
29 changes: 25 additions & 4 deletions spx-gui/src/models/costume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { extname, resolve } from '@/utils/path'
import { adaptImg } from '@/utils/spx'
import { Disposable } from '@/utils/disposable'
import { File, type Files } from './common/file'
import { type Size } from './common'
import type { Size } from './common'
import type { Sprite } from './sprite'
import { getCostumeName, validateCostumeName } from './common/asset-name'
import { Animation } from './animation'
Expand Down Expand Up @@ -63,16 +63,16 @@ export class Costume {
this.bitmapResolution = bitmapResolution
}

async getSize() {
private async getRawSize() {
const d = new Disposable()
const imgUrl = await this.img.url((fn) => d.addDisposer(fn))
return new Promise<Size>((resolve, reject) => {
const img = new window.Image()
img.src = imgUrl
img.onload = () => {
resolve({
width: img.width / this.bitmapResolution,
height: img.height / this.bitmapResolution
width: img.width,
height: img.height
})
}
img.onerror = (e) => {
Expand All @@ -83,6 +83,14 @@ export class Costume {
})
}

async getSize() {
const rawSize = await this.getRawSize()
return {
width: rawSize.width / this.bitmapResolution,
height: rawSize.height / this.bitmapResolution
}
}

constructor(name: string, file: File, inits?: CostumeInits) {
this.name = name
this.img = file
Expand All @@ -103,6 +111,19 @@ export class Costume {
})
}

/**
* Adjust position to fit current sprite
* TODO: review the relation between `autoFit` & `Costume.create` / `Sprite addCostume`
*/
async autoFit() {
if (this.parent == null) throw new Error(`parent required to autoFit costume ${this.name}`)
const reference = this.parent.costumes[0]
if (reference == null || reference === this) return
const [referenceSize, size] = await Promise.all([reference.getRawSize(), this.getRawSize()])
this.setX(reference.x + (size.width - referenceSize.width) / 2)
this.setY(reference.y + (size.height - referenceSize.height) / 2)
}

/**
* Create instance with default inits
* Note that the "default" means default behavior for builder, not the default behavior of spx
Expand Down
4 changes: 4 additions & 0 deletions spx-gui/src/models/sprite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,10 @@ export class Sprite extends Disposable {
}
}

async autoFitCostumes(costumes = this.costumes) {
await Promise.all(costumes.map((c) => c.autoFit()))
}

/** Create sprite within builder (by user actions) */
static create(nameBase: string, code?: string, inits?: SpriteInits) {
return new Sprite(getSpriteName(null, nameBase), code, {
Expand Down

0 comments on commit b0787b3

Please sign in to comment.