首次上传
This commit is contained in:
1 parent
af9bda066c
commit
9b156a32c9
29 files changed
+14567
No files matched your search
@@ -0,0 +1,114 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { EmitterConfig, defaultConfig, ParticleState } from '../core/particleEmitter'
|
||||
|
||||
export interface ParticleSystem {
|
||||
id: number
|
||||
config: EmitterConfig
|
||||
/** 录制到的帧序列(每帧 = 该帧活动粒子快照) */
|
||||
frames?: ParticleState[][]
|
||||
}
|
||||
|
||||
export interface EditorState {
|
||||
viewScale: number
|
||||
viewX: number
|
||||
viewY: number
|
||||
}
|
||||
|
||||
/** 系统设置(可通过右上角设置面板调整) */
|
||||
export interface SettingsState {
|
||||
/** 是否启用刻度(主开关;启用=显示坐标轴+刻度线+数值,可调整字号/粗细) */
|
||||
tickEnabled: boolean
|
||||
/** 坐标轴刻度文字大小(px),默认 12 */
|
||||
axisFontSize: number
|
||||
/** 刻度线粗细(px) */
|
||||
tickWidth: number
|
||||
/** 是否显示坐标轴刻度数值 */
|
||||
showAxisLabels: boolean
|
||||
/** 坐标轴数值颜色(#rrggbb) */
|
||||
axisColor: string
|
||||
}
|
||||
|
||||
export interface TimelineState {
|
||||
/** 播放模式 */
|
||||
playing: boolean
|
||||
/** 循环 */
|
||||
loop: boolean
|
||||
/** 当前帧 */
|
||||
frame: number
|
||||
/** 总帧数 */
|
||||
totalFrames: number
|
||||
/** 帧率 */
|
||||
fps: number
|
||||
/** 是否已录制 */
|
||||
recorded: boolean
|
||||
/** 动画名(暂用于显示) */
|
||||
animation: string
|
||||
}
|
||||
|
||||
let seq = 1
|
||||
|
||||
export const useParticleStore = defineStore('particle', {
|
||||
state: () => ({
|
||||
editor: { viewScale: 1.0, viewX: 0, viewY: 0 } as EditorState,
|
||||
systems: [] as ParticleSystem[],
|
||||
activeId: 0,
|
||||
timeline: { playing: true, loop: true, frame: 0, totalFrames: 120, fps: 60, recorded: false, animation: 'animation' } as TimelineState,
|
||||
settings: { tickEnabled: false, axisFontSize: 12, tickWidth: 1, showAxisLabels: true, axisColor: '#7a86ad' } as SettingsState,
|
||||
}),
|
||||
getters: {
|
||||
activeSystemCount: (s) => s.systems.length,
|
||||
},
|
||||
actions: {
|
||||
addSystem(initial?: Partial<{ config: Partial<EmitterConfig> }>) {
|
||||
const cfg = defaultConfig()
|
||||
if (initial?.config) Object.assign(cfg, initial.config)
|
||||
// 自动生成不重复名字:若"ParticleSystemN"已存在,取已有数字最大值+1
|
||||
const existing = new Set(this.systems.map((s) => s.config.name))
|
||||
if (existing.has(cfg.name)) {
|
||||
let maxN = 0
|
||||
for (const s of this.systems) {
|
||||
const m = /^ParticleSystem(\d+)$/.exec(s.config.name)
|
||||
if (m) maxN = Math.max(maxN, parseInt(m[1], 10))
|
||||
}
|
||||
cfg.name = `ParticleSystem${maxN + 1}`
|
||||
let i = 2
|
||||
while (existing.has(cfg.name)) { cfg.name = `ParticleSystem${maxN + i}`; i++ }
|
||||
}
|
||||
const sys: ParticleSystem = { id: seq++, config: cfg }
|
||||
this.systems.push(sys)
|
||||
this.activeId = sys.id
|
||||
return sys
|
||||
},
|
||||
removeSystem(id: number) {
|
||||
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
|
||||
},
|
||||
selectSystem(id: number) { this.activeId = id },
|
||||
play() { this.timeline.playing = true },
|
||||
pause() { this.timeline.playing = false },
|
||||
togglePlay() { this.timeline.playing = !this.timeline.playing },
|
||||
toStart() { this.timeline.frame = 0 },
|
||||
toggleLoop() { this.timeline.loop = !this.timeline.loop },
|
||||
setFrame(f: number) {
|
||||
this.timeline.frame = Math.max(0, Math.min(f, this.timeline.totalFrames - 1))
|
||||
},
|
||||
/** 依据所有粒子系统的"最晚消失时间"重算总帧数。
|
||||
* 单系统总时长 = delay(延迟) + duration(发射时长) + lifeMax(粒子最大生命),
|
||||
* 多系统取最大;转帧 = ceil(sec * fps)。 */
|
||||
recalcTotalFrames() {
|
||||
const fps = this.timeline.fps || 60
|
||||
let maxSec = 0
|
||||
for (const sys of this.systems) {
|
||||
const c = sys.config
|
||||
const end = (c.delay || 0) + (c.duration || 0) + (c.lifeMax || 0)
|
||||
if (end > maxSec) maxSec = end
|
||||
}
|
||||
const frames = Math.max(1, Math.ceil(maxSec * fps))
|
||||
this.timeline.totalFrames = frames
|
||||
// clamp 当前帧
|
||||
if (this.timeline.frame >= frames) this.timeline.frame = frames - 1
|
||||
return frames
|
||||
},
|
||||
},
|
||||
})
|
||||
Reference in new issue
Block a user