From 3f2699a9467b1fb4f891be3022d62726fc92b63b Mon Sep 17 00:00:00 2001 From: tianmo Date: Tue, 22 Sep 2026 14:42:21 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=BD=A2=E7=8A=B6=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E5=BC=80=E5=85=B3=EF=BC=8C=E4=BF=AE=E6=94=B9=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/particleConfig.ts | 2 +- src/core/particleTypes.ts | 3 ++- src/export/spineExportSettings.ts | 2 +- src/views/particle-panel/EmissionSection.vue | 4 ++++ src/views/particle-panel/useParticlePanel.ts | 2 +- src/views/stage/emitterGuides.ts | 2 +- src/views/stage/sceneGuides.ts | 8 +++++++- 7 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/core/particleConfig.ts b/src/core/particleConfig.ts index e81bd32..8410bac 100644 --- a/src/core/particleConfig.ts +++ b/src/core/particleConfig.ts @@ -47,6 +47,7 @@ export function defaultConfig(): EmitterConfig { delay: 0, duration: 1, // 持续发射时长;默认 1 秒(30f)。爆发模式运行时按 0 处理。 shape: 'point', + showShape: true, shapeRangeVersion: 1, innerRadius: 0, outerRadius: 30, @@ -476,4 +477,3 @@ export function ensureEmitterConfig(config: EmitterConfig): EmitterConfig { config.trailResourceVersion = 6 return config } - diff --git a/src/core/particleTypes.ts b/src/core/particleTypes.ts index beb0845..06b553d 100644 --- a/src/core/particleTypes.ts +++ b/src/core/particleTypes.ts @@ -141,6 +141,8 @@ export interface EmitterConfig { /** 持续发射时长(秒)= 时间轴绿色段;爆发模式不使用该时长 */ duration: number shape: EmitShape // 发射形状 + /** 是否在画布上显示当前发射形状。 */ + showShape: boolean /** 发射范围结构版本,用于旧配置迁移。 */ shapeRangeVersion: number /** 圆形和锥形发射范围的内外半径。 */ @@ -396,4 +398,3 @@ export interface TrailState { colorHex: number resourceId?: number } - diff --git a/src/export/spineExportSettings.ts b/src/export/spineExportSettings.ts index 0b0d639..d3326e5 100644 --- a/src/export/spineExportSettings.ts +++ b/src/export/spineExportSettings.ts @@ -20,7 +20,7 @@ export function defaultSpineExportSettings(): SpineExportSettings { return { imagesPath: './images/', spineVersion: '4.2', - keyframeCurve: 'linear', + keyframeCurve: 'bezier', fps: 30, omitFps: false, integerFrameAlignment: true, diff --git a/src/views/particle-panel/EmissionSection.vue b/src/views/particle-panel/EmissionSection.vue index 2fd2d39..6377724 100644 --- a/src/views/particle-panel/EmissionSection.vue +++ b/src/views/particle-panel/EmissionSection.vue @@ -120,6 +120,10 @@ + diff --git a/src/views/particle-panel/useParticlePanel.ts b/src/views/particle-panel/useParticlePanel.ts index 665a616..3619e1c 100644 --- a/src/views/particle-panel/useParticlePanel.ts +++ b/src/views/particle-panel/useParticlePanel.ts @@ -298,7 +298,7 @@ const MODULE_RESET_KEYS: Record, string[]> = { 'burstCount', 'burstLoop', 'delay', 'duration', ], shape: [ - 'shape', 'shapeRangeVersion', + 'shape', 'showShape', 'shapeRangeVersion', 'innerRadius', 'outerRadius', 'innerRectW', 'innerRectH', 'outerRectW', 'outerRectH', 'spawnPathId', 'spawnPathDistribution', 'radius', 'rectW', 'rectH', 'emissionAngleMode', 'direction', 'spread', 'coneDirection', 'coneAngle', ], diff --git a/src/views/stage/emitterGuides.ts b/src/views/stage/emitterGuides.ts index 4922a82..aab98b9 100644 --- a/src/views/stage/emitterGuides.ts +++ b/src/views/stage/emitterGuides.ts @@ -40,10 +40,10 @@ export function drawShapeRange(store: EditorStore, emitterPreviewTransform: Map< if (!shapeGfx) return const g = shapeGfx g.clear() - if (!store.settings.showEmitter) return const sys = store.systems.find((s) => s.id === store.activeId) if (!sys || sys.visible === false) return const c = sys.config + if (!c.showShape) return const preview = emitterPreviewTransform.get(sys.id) // root 中心(发射器容器 position = centerX/-centerY),数学坐标 const cx = preview?.x ?? c.centerX ?? 0 diff --git a/src/views/stage/sceneGuides.ts b/src/views/stage/sceneGuides.ts index a513e64..d60a24b 100644 --- a/src/views/stage/sceneGuides.ts +++ b/src/views/stage/sceneGuides.ts @@ -167,8 +167,14 @@ export function drawPaths(store: EditorStore, selectedPathNodes: Set, pa if (!pathGfx) return const g = pathGfx g.clear() + const activeSystem = store.activeObjectType === 'particle' + ? store.systems.find((system) => system.id === store.activeObjectId) + : null + const hiddenEmitterPathId = activeSystem?.config.shape === 'path' && !activeSystem.config.showShape + ? activeSystem.config.spawnPathId + : 0 for (const path of store.paths) { - if (path.visible === false || !path.enabled || !path.points.length) continue + if (path.id === hiddenEmitterPathId || path.visible === false || !path.enabled || !path.points.length) continue const selected = store.activeObjectType === 'path' && store.activeObjectId === path.id const color = colorNumber(path.color, 0xff933e) const screenPoint = (x: number, y: number) => {