显示调整

This commit is contained in:
tianmo committed 2026-08-29 12:32:11 +08:00
1 parent 178a7d8412
commit b5ac9552a1
9 files changed
+1064 -81

No files matched your search

+64 -7
View File
@@ -5,6 +5,9 @@ import { releaseSpineAsset } from '../spine/spineAssetRegistry'
export interface ParticleSystem {
id: number
visible: boolean
/** 导出时所属的动画名称。 */
animation: string
config: EmitterConfig
/** 录制到的帧序列(每帧 = 该帧活动粒子快照) */
frames?: ParticleState[][]
@@ -12,6 +15,7 @@ export interface ParticleSystem {
export interface CollisionBody extends SceneCollider {
name: string
visible: boolean
tags: string[]
selectedTag: string
followPath: boolean
@@ -25,6 +29,7 @@ export interface CollisionBody extends SceneCollider {
export interface ScenePath {
id: number
name: string
visible: boolean
enabled: boolean
x: number
y: number
@@ -57,8 +62,6 @@ export interface SettingsState {
showAxisLabels: boolean
/** 坐标轴数值颜色(#rrggbb) */
axisColor: string
/** 是否在画布中显示已加载的 Spine 动画资源 */
showSpineResources: boolean
}
export interface TimelineState {
@@ -74,8 +77,10 @@ export interface TimelineState {
fps: number
/** 是否已录制 */
recorded: boolean
/** 动画名(暂用于显示) */
/** 当前选中的所属动画。 */
animation: string
/** 项目中可供粒子系统归属的动画列表,至少保留一个。 */
animations: string[]
}
let seq = 1
@@ -94,8 +99,8 @@ export const useParticleStore = defineStore('particle', {
activeObjectType: 'particle' as SceneObjectType,
activeObjectId: 0,
// 与 Spine 编辑器默认时间基准对齐:1 秒 = 30 帧。
timeline: { playing: true, loop: true, frame: 0, totalFrames: 60, fps: 30, recorded: false, animation: 'animation' } as TimelineState,
settings: { tickEnabled: false, axisFontSize: 12, tickWidth: 1, showAxisLabels: true, axisColor: '#7a86ad', showSpineResources: true } as SettingsState,
timeline: { playing: true, loop: true, frame: 0, totalFrames: 60, fps: 30, recorded: false, animation: 'animation', animations: ['animation'] } as TimelineState,
settings: { tickEnabled: false, axisFontSize: 12, tickWidth: 1, showAxisLabels: true, axisColor: '#7a86ad' } as SettingsState,
}),
getters: {
activeSystemCount: (s) => s.systems.length,
@@ -116,7 +121,10 @@ export const useParticleStore = defineStore('particle', {
let i = 2
while (existing.has(cfg.name)) { cfg.name = `ParticleSystem${maxN + i}`; i++ }
}
const sys: ParticleSystem = { id: seq++, config: cfg }
const animation = this.timeline.animations.includes(this.timeline.animation)
? this.timeline.animation
: this.timeline.animations[0] || 'animation'
const sys: ParticleSystem = { id: seq++, visible: true, animation, config: cfg }
this.systems.push(sys)
this.activeId = sys.id
this.activeObjectType = 'particle'
@@ -127,6 +135,8 @@ export const useParticleStore = defineStore('particle', {
const i = this.systems.findIndex((s) => s.id === id)
if (i >= 0) this.systems.splice(i, 1)
if (this.activeId === id) this.activeId = this.systems[0]?.id ?? 0
const activeSystem = this.systems.find((system) => system.id === this.activeId)
if (activeSystem) this.timeline.animation = activeSystem.animation
if (this.activeObjectType === 'particle' && this.activeObjectId === id) {
const next = this.systems[0]
this.activeObjectId = next?.id ?? 0
@@ -136,12 +146,52 @@ export const useParticleStore = defineStore('particle', {
this.activeId = id
this.activeObjectType = 'particle'
this.activeObjectId = id
const system = this.systems.find((item) => item.id === id)
if (system) this.timeline.animation = system.animation
},
setSystemAnimation(id: number, animation: string) {
if (!this.timeline.animations.includes(animation)) return
const system = this.systems.find((item) => item.id === id)
if (!system) return
system.animation = animation
this.timeline.animation = animation
},
addAnimation() {
const existing = new Set(this.timeline.animations)
let index = 2
let name = `animation${index}`
while (existing.has(name)) name = `animation${++index}`
this.timeline.animations.push(name)
this.timeline.animation = name
const system = this.systems.find((item) => item.id === this.activeId)
if (system) system.animation = name
return name
},
renameAnimation(previousName: string, nextName: string) {
const name = nextName.trim()
const index = this.timeline.animations.indexOf(previousName)
if (index < 0 || !name || (name !== previousName && this.timeline.animations.includes(name))) return false
this.timeline.animations[index] = name
for (const system of this.systems) if (system.animation === previousName) system.animation = name
if (this.timeline.animation === previousName) this.timeline.animation = name
return true
},
removeAnimation(name: string) {
if (this.timeline.animations.length <= 1) return false
const index = this.timeline.animations.indexOf(name)
if (index < 0) return false
this.timeline.animations.splice(index, 1)
const fallback = this.timeline.animations[Math.min(index, this.timeline.animations.length - 1)]
for (const system of this.systems) if (system.animation === name) system.animation = fallback
if (this.timeline.animation === name) this.timeline.animation = fallback
return true
},
addCollider() {
const id = colliderSeq++
const collider: CollisionBody = {
id,
name: `Collider${id}`,
visible: true,
tags: ['Default'],
selectedTag: 'Default',
shape: 'circle',
@@ -177,6 +227,7 @@ export const useParticleStore = defineStore('particle', {
const path: ScenePath = {
id,
name: `Path${id}`,
visible: true,
enabled: true,
x: 0,
y: 0,
@@ -199,6 +250,7 @@ export const useParticleStore = defineStore('particle', {
id,
name: `SpineSkeleton${id}`,
enabled: true,
visible: true,
x: 0,
y: 0,
rotation: 0,
@@ -209,6 +261,7 @@ export const useParticleStore = defineStore('particle', {
atlasFileName: '',
textureFileNames: [],
selectedAnimation: '',
selectedBone: '',
animations: [],
bones: [],
assetVersion: 0,
@@ -223,7 +276,11 @@ export const useParticleStore = defineStore('particle', {
selectSceneObject(type: SceneObjectType, id: number) {
this.activeObjectType = type
this.activeObjectId = id
if (type === 'particle') this.activeId = id
if (type === 'particle') {
this.activeId = id
const system = this.systems.find((item) => item.id === id)
if (system) this.timeline.animation = system.animation
}
},
removeCollider(id: number) {
const index = this.colliders.findIndex((item) => item.id === id)