diff --git a/public/Preset/index.json b/public/Preset/index.json index 08e7aa4..f1c56d2 100644 --- a/public/Preset/index.json +++ b/public/Preset/index.json @@ -1,7 +1,7 @@ [ { - "name": "方块粒子", - "file": "方块粒子.json" + "name": "多力场", + "file": "多力场.json" }, { "name": "雷电序列帧", @@ -11,6 +11,10 @@ "name": "粒子扫过", "file": "粒子扫过.json" }, + { + "name": "长条方块", + "file": "长条方块.json" + }, { "name": "spine", "file": "spine.json" diff --git a/public/Preset/多力场.json b/public/Preset/多力场.json new file mode 100644 index 0000000..834627c --- /dev/null +++ b/public/Preset/多力场.json @@ -0,0 +1,530 @@ +{ + "format": "SpineParticle.EditorConfig", + "version": 1, + "savedAt": "2026-09-22T08:54:10.890Z", + "editor": { + "viewScale": 0.8928571428571433, + "viewX": 27.26238807717155, + "viewY": -5.489695295473268 + }, + "settings": { + "backgroundX": 0, + "backgroundY": 0, + "backgroundOpacity": 1, + "backgroundImageName": "", + "backgroundImageData": "", + "showGrid": true, + "exportSettings": { + "imagesPath": "./images/", + "spineVersion": "4.2", + "keyframeCurve": "bezier", + "fps": 30, + "omitFps": false, + "integerFrameAlignment": true, + "bonePool": true, + "excludeEmptyAnimations": false, + "fileName": "SpineParticle.json" + } + }, + "timeline": { + "fps": 30, + "loop": true, + "playbackStart": 0, + "playbackEnd": 90, + "animations": [ + "animation" + ] + }, + "selection": { + "type": "particle", + "id": 1 + }, + "scene": { + "systems": [ + { + "id": 1, + "visible": true, + "animation": "animation", + "config": { + "imageResources": [ + { + "id": 1, + "textureName": "star", + "textureFolder": "", + "previewUrl": "/images/star.png", + "imageMode": "fixed", + "sequencePlayback": "loop-forward", + "sequenceFps": 30, + "sequenceFrames": [], + "weight": 100, + "locked": false, + "scale": 1, + "anchorX": 0.5, + "anchorY": 0.5, + "colorMode": "random", + "colorStart": "#ffffff", + "colorEnd": "#ff4d4d", + "colorGradient": [ + { + "position": 0, + "color": "#ffffff" + }, + { + "position": 1, + "color": "#ff4d4d" + }, + { + "position": 0.5, + "color": "#00e1ff" + }, + { + "position": 0.25, + "color": "#ffae00" + }, + { + "position": 0.75, + "color": "#c800ff" + } + ], + "blend": "add", + "independentAlpha": "off", + "alpha": 1, + "alphaCurveMode": "跟随导出", + "alphaCurve": [ + { + "x": 0, + "y": 0 + }, + { + "x": 0.1, + "y": 1 + }, + { + "x": 0.9, + "y": 1 + }, + { + "x": 1, + "y": 0 + } + ] + } + ], + "imageWeightVersion": 1, + "name": "lizi", + "mode": "burst", + "rate": 5, + "streamBehavior": "loop", + "loopDurationFrames": 120, + "generateLoopStartAnimation": false, + "loopStartUseCustomDuration": false, + "loopStartDurationFrames": 30, + "generateLoopEndAnimation": false, + "loopEndUseCustomDuration": false, + "loopEndDurationFrames": 30, + "burstCount": 50, + "burstLoop": false, + "delay": 0, + "duration": 1, + "shape": "circle", + "showShape": false, + "shapeRangeVersion": 1, + "innerRadius": 150, + "outerRadius": 150, + "innerRectW": 0, + "innerRectH": 0, + "outerRectW": 60, + "outerRectH": 40, + "spawnPathId": 0, + "spawnPathDistribution": "fixed", + "radius": 30, + "rectW": 60, + "rectH": 40, + "centerX": 0, + "centerY": 0, + "rootRotation": 0, + "rootScaleX": 1, + "rootScaleY": 1, + "emissionAngleMode": "radial", + "direction": -90, + "spread": 0, + "coneDirection": 90, + "coneAngle": 60, + "lifeMin": 3, + "lifeMax": 3, + "lifeMode": "fixed", + "lifeCurve": [ + { + "x": 0, + "y": 0 + }, + { + "x": 1, + "y": 1 + } + ], + "speedMin": 0, + "speedMax": 0, + "speedMode": "fixed", + "speedCurve": [ + { + "x": 0, + "y": 0 + }, + { + "x": 1, + "y": 1 + } + ], + "scaleMin": 0.2, + "scaleMax": 0.6, + "scaleMode": "random", + "scaleAxisMode": "uniform", + "scaleYMin": 0.3, + "scaleYMax": 0.8, + "scaleCurve": [ + { + "x": 0, + "y": 0 + }, + { + "x": 1, + "y": 1 + } + ], + "scaleYCurve": [ + { + "x": 0, + "y": 0 + }, + { + "x": 1, + "y": 1 + } + ], + "scaleEndRatio": 0.3, + "initialRotationMode": "random", + "initialRotationMin": 0, + "initialRotationMax": 360, + "initialRotationCurve": [ + { + "x": 0, + "y": 0 + }, + { + "x": 1, + "y": 1 + } + ], + "alpha": 1, + "alphaEnd": 0, + "rotationSpeedMin": 360, + "rotationSpeedMax": 720, + "speedOverLifeEnabled": false, + "speedOverLifeMode": "fixed", + "speedOverLifeMin": 1, + "speedOverLifeMax": 1, + "speedOverLifeCurve": [ + { + "x": 0, + "y": 1 + }, + { + "x": 1, + "y": 1 + } + ], + "scaleOverLifeEnabled": false, + "scaleOverLifeMode": "curve", + "scaleOverLifeAxisMode": "uniform", + "scaleOverLifeMin": 0, + "scaleOverLifeMax": 1, + "scaleYOverLifeMin": 0, + "scaleYOverLifeMax": 1, + "scaleOverLifeCurve": [ + { + "x": 0, + "y": 1 + }, + { + "x": 1, + "y": 1 + } + ], + "scaleYOverLifeCurve": [ + { + "x": 0, + "y": 1 + }, + { + "x": 1, + "y": 1 + } + ], + "rotationOverLifeEnabled": true, + "rotationOverLifeMode": "random", + "rotationOverLifeCurve": [ + { + "x": 0, + "y": 0 + }, + { + "x": 1, + "y": 1 + } + ], + "gravity": 980, + "gravityMode": "fixed", + "gravityMin": 980, + "gravityMax": 980, + "gravityDirection": -90, + "gravityCurve": [ + { + "x": 0, + "y": 1 + }, + { + "x": 1, + "y": 1 + } + ], + "damping": 0.6, + "seed": 457291, + "colorStart": "#ffffff", + "colorEnd": "#ff4d4d", + "colorOverLife": false, + "blend": "add", + "alphaMode": "curve", + "curveMode": "线性", + "alphaCurve": [ + { + "x": 0, + "y": 0 + }, + { + "x": 0.1, + "y": 1 + }, + { + "x": 0.91, + "y": 1 + }, + { + "x": 1, + "y": 0 + } + ], + "textureName": "star", + "textureFolder": "", + "alphaScale": 1, + "anchorX": 0.5, + "anchorY": 0.5, + "independentAlpha": "off", + "offsetX": 0, + "offsetY": 0, + "noise": true, + "noiseAmt": 10, + "noiseRange": 100, + "noiseSpeed": 1, + "useGravity": false, + "wind": false, + "windX": 0, + "windY": 0, + "windMode": "fixed", + "windMin": 100, + "windMax": 100, + "windDirection": 0, + "windCurve": [ + { + "x": 0, + "y": 1 + }, + { + "x": 1, + "y": 1 + } + ], + "forceField": true, + "forceStrength": 20, + "forceRadius": 300, + "forceCenterX": 0, + "forceCenterY": 0, + "forceFalloff": "constant", + "vortex": true, + "vortexStrength": 10, + "vortexRadius": 300, + "vortexCenterX": 0, + "vortexCenterY": 0, + "vortexFalloff": "constant", + "attraction": false, + "attractionCenterX": 200, + "attractionCenterY": 0, + "attractionRadius": 20, + "attractionDuration": 0.5, + "attractionDelay": 0.1, + "attractionDelayMode": "particle", + "attractionPath": "curve", + "trail": true, + "trailConfigVersion": 3, + "trailResources": [ + { + "id": 1, + "textureName": "trail", + "previewUrl": "/images/trail.png", + "weight": 100, + "locked": false, + "rotation": 0, + "colorMode": "particle", + "color": "#ffffff", + "colorGradient": [ + { + "position": 0, + "color": "#ffffff" + }, + { + "position": 1, + "color": "#ffffff" + } + ], + "blend": "normal", + "alphaMode": "particle", + "alpha": 1, + "alphaCurve": [ + { + "x": 0, + "y": 1 + }, + { + "x": 1, + "y": 1 + } + ], + "boneCount": 2, + "trailRatio": 100, + "lengthMode": "fixed", + "length": 100, + "lengthMin": 100, + "lengthMax": 100, + "widthSizeMode": "fixed", + "width": 10, + "widthMin": 100, + "widthMax": 100, + "widthMode": "particle", + "lifeLengthEnabled": false, + "lifeLengthCurve": [ + { + "x": 0, + "y": 1 + }, + { + "x": 1, + "y": 1 + } + ], + "shapeEnabled": false, + "shapeCurve": [ + { + "x": 0, + "y": 1 + }, + { + "x": 1, + "y": 1 + } + ] + } + ], + "trailResourceVersion": 6, + "trailTextureName": "trail", + "trailPreviewUrl": "/images/trail.png", + "trailColorMode": "particle", + "trailColor": "#ffffff", + "trailColorGradient": [ + { + "position": 0, + "color": "#ffffff" + }, + { + "position": 1, + "color": "#ffffff" + } + ], + "trailAlphaMode": "particle", + "trailAlpha": 1, + "trailAlphaCurve": [ + { + "x": 0, + "y": 1 + }, + { + "x": 1, + "y": 1 + } + ], + "trailBoneCount": 3, + "trailLength": 100, + "trailWidth": 100, + "trailWidthMode": "particle", + "trailLifeLengthEnabled": false, + "trailLifeLengthCurve": [ + { + "x": 0, + "y": 1 + }, + { + "x": 1, + "y": 1 + } + ], + "trailShapeEnabled": false, + "trailShapeCurve": [ + { + "x": 0, + "y": 1 + }, + { + "x": 1, + "y": 1 + } + ], + "trailGridRows": 2, + "trailGridCols": 2, + "collision": false, + "collisionColliderIds": [], + "pathFollow": false, + "emitterFollow": false, + "emitterFollowMode": "none", + "emitterFollowPathId": 0, + "emitterFollowSpineId": 0, + "emitterFollowBoneName": "", + "emitterFollowBoneOffsetX": 0, + "emitterFollowBoneOffsetY": 0, + "emitterFollowBoneRotation": 0, + "emitterFollowBoneScaleX": 1, + "emitterFollowBoneScaleY": 1, + "emitterAngleMode": "fixed", + "emitterFollowCurve": [ + { + "x": 0, + "y": 0 + }, + { + "x": 1, + "y": 1 + } + ], + "emitterFollowDuration": 2, + "emitterFollowSpace": "world", + "emitterFollowDirection": "forward", + "emitterFollowOffset": 0, + "showForceFieldShape": false, + "showVortexShape": false, + "showAttractionShape": true + } + } + ], + "colliders": [], + "paths": [], + "spines": [] + } +} \ No newline at end of file diff --git a/public/Preset/粒子扫过.json b/public/Preset/粒子扫过.json index c147e35..5bbab7e 100644 --- a/public/Preset/粒子扫过.json +++ b/public/Preset/粒子扫过.json @@ -1,11 +1,11 @@ { "format": "SpineParticle.EditorConfig", "version": 1, - "savedAt": "2026-09-14T09:25:05.330Z", + "savedAt": "2026-09-22T08:56:24.085Z", "editor": { "viewScale": 0.4038832279793692, - "viewX": 12.678891156789803, - "viewY": -24.27929100039178 + "viewX": 2.0968599067898026, + "viewY": 31.98633399960822 }, "settings": { "backgroundX": 0, @@ -501,7 +501,17 @@ "emitterFollowDuration": 1, "emitterFollowSpace": "world", "emitterFollowDirection": "forward", - "emitterFollowOffset": 0 + "emitterFollowOffset": 0, + "showShape": false, + "showForceFieldShape": true, + "vortex": false, + "vortexStrength": 10, + "vortexRadius": 100, + "vortexCenterX": 0, + "vortexCenterY": 0, + "vortexFalloff": "linear", + "showVortexShape": true, + "showAttractionShape": true } } ], diff --git a/public/Preset/方块粒子.json b/public/Preset/长条方块.json similarity index 96% rename from public/Preset/方块粒子.json rename to public/Preset/长条方块.json index ecbd612..1c839a9 100644 --- a/public/Preset/方块粒子.json +++ b/public/Preset/长条方块.json @@ -1,11 +1,11 @@ { "format": "SpineParticle.EditorConfig", "version": 1, - "savedAt": "2026-09-19T10:10:58.215Z", + "savedAt": "2026-09-22T08:55:50.419Z", "editor": { "viewScale": 0.892857142857143, - "viewX": -108.5419187636735, - "viewY": -9.030568128049083 + "viewX": 11.598706236326507, + "viewY": 20.938181871950917 }, "settings": { "backgroundX": 0, @@ -105,7 +105,7 @@ "imageWeightVersion": 1, "name": "ParticleSystem1", "mode": "stream", - "rate": 20, + "rate": 40, "streamBehavior": "loop", "loopDurationFrames": 60, "generateLoopStartAnimation": true, @@ -124,7 +124,7 @@ "outerRadius": 20, "innerRectW": 0, "innerRectH": 0, - "outerRectW": 200, + "outerRectW": 800, "outerRectH": 36, "spawnPathId": 0, "spawnPathDistribution": "fixed", @@ -505,7 +505,17 @@ "emitterFollowDuration": 2, "emitterFollowSpace": "world", "emitterFollowDirection": "forward", - "emitterFollowOffset": 0 + "emitterFollowOffset": 0, + "showShape": false, + "showForceFieldShape": true, + "vortex": false, + "vortexStrength": 10, + "vortexRadius": 100, + "vortexCenterX": 0, + "vortexCenterY": 0, + "vortexFalloff": "linear", + "showVortexShape": true, + "showAttractionShape": true } } ], diff --git a/src/core/particleConfig.ts b/src/core/particleConfig.ts index b3cc31f..855ca20 100644 --- a/src/core/particleConfig.ts +++ b/src/core/particleConfig.ts @@ -154,12 +154,14 @@ export function defaultConfig(): EmitterConfig { forceCenterX: 0, forceCenterY: 0, forceFalloff: 'linear', + showForceFieldShape: true, vortex: false, vortexStrength: 10, vortexRadius: 100, vortexCenterX: 0, vortexCenterY: 0, vortexFalloff: 'linear', + showVortexShape: true, attraction: false, attractionCenterX: 200, attractionCenterY: 0, @@ -168,6 +170,7 @@ export function defaultConfig(): EmitterConfig { attractionDelay: 0.1, attractionDelayMode: 'particle', attractionPath: 'curve', + showAttractionShape: true, trail: false, trailConfigVersion: 3, trailResources: [{ diff --git a/src/core/particleTypes.ts b/src/core/particleTypes.ts index e96bb31..6081097 100644 --- a/src/core/particleTypes.ts +++ b/src/core/particleTypes.ts @@ -291,6 +291,7 @@ export interface EmitterConfig { forceCenterX: number forceCenterY: number forceFalloff: FieldFalloff + showForceFieldShape: boolean /** 开启漩涡力;正强度逆时针,负强度顺时针。 */ vortex: boolean vortexStrength: number @@ -298,6 +299,7 @@ export interface EmitterConfig { vortexCenterX: number vortexCenterY: number vortexFalloff: FieldFalloff + showVortexShape: boolean /** 开启吸附:粒子在延迟后从当前位置移动到全局吸附点,到达范围后死亡 */ attraction: boolean attractionCenterX: number @@ -307,6 +309,7 @@ export interface EmitterConfig { attractionDelay: number attractionDelayMode: 'global' | 'particle' attractionPath: 'linear' | 'curve' + showAttractionShape: boolean /** 开启拖尾 */ trail: boolean trailConfigVersion: number diff --git a/src/views/particle-panel/ParticleModifiersSection.vue b/src/views/particle-panel/ParticleModifiersSection.vue index 1750fec..34c5e2a 100644 --- a/src/views/particle-panel/ParticleModifiersSection.vue +++ b/src/views/particle-panel/ParticleModifiersSection.vue @@ -80,6 +80,7 @@
正数吸向中心 · 负数向外排斥 · 可在画布内拖动力场圆
+
@@ -100,6 +101,7 @@
正数逆时针 · 负数顺时针
+
@@ -126,6 +128,7 @@
延迟后从当前位置开始吸附 · 到达红色范围即死亡 · 可在画布内拖动吸附圆
+
diff --git a/src/views/particle-panel/useParticlePanel.ts b/src/views/particle-panel/useParticlePanel.ts index dbdbf8c..19406cf 100644 --- a/src/views/particle-panel/useParticlePanel.ts +++ b/src/views/particle-panel/useParticlePanel.ts @@ -325,10 +325,10 @@ const MODULE_RESET_KEYS: Record, string[]> = { 'noise', 'noiseAmt', 'noiseRange', 'noiseSpeed', 'useGravity', 'gravity', 'gravityMode', 'gravityMin', 'gravityMax', 'gravityDirection', 'gravityCurve', 'wind', 'windX', 'windY', 'windMode', 'windMin', 'windMax', 'windDirection', 'windCurve', - 'forceField', 'forceStrength', 'forceRadius', 'forceCenterX', 'forceCenterY', 'forceFalloff', - 'vortex', 'vortexStrength', 'vortexRadius', 'vortexCenterX', 'vortexCenterY', 'vortexFalloff', + 'forceField', 'forceStrength', 'forceRadius', 'forceCenterX', 'forceCenterY', 'forceFalloff', 'showForceFieldShape', + 'vortex', 'vortexStrength', 'vortexRadius', 'vortexCenterX', 'vortexCenterY', 'vortexFalloff', 'showVortexShape', 'attraction', 'attractionCenterX', 'attractionCenterY', 'attractionRadius', - 'attractionDuration', 'attractionDelay', 'attractionDelayMode', 'attractionPath', + 'attractionDuration', 'attractionDelay', 'attractionDelayMode', 'attractionPath', 'showAttractionShape', 'trail', 'trailConfigVersion', 'trailResources', 'trailResourceVersion', 'trailTexture', 'trailTextureName', 'trailPreviewUrl', 'trailColorMode', 'trailColor', 'trailColorGradient', 'trailAlphaMode', 'trailAlpha', 'trailAlphaCurve', diff --git a/src/views/stage/emitterGuides.ts b/src/views/stage/emitterGuides.ts index 20187e0..df278de 100644 --- a/src/views/stage/emitterGuides.ts +++ b/src/views/stage/emitterGuides.ts @@ -116,7 +116,7 @@ export function drawForceField(store: EditorStore, forceFieldGfx: Graphics | nul const sys = store.systems.find((item) => item.id === store.activeId) if (sys?.visible === false) return const cfg = sys?.config - if (!cfg?.forceField || cfg.forceRadius <= 0) return + if (!cfg?.forceField || !cfg.showForceFieldShape || cfg.forceRadius <= 0) return const x = cfg.forceCenterX const y = -cfg.forceCenterY const color = cfg.forceStrength >= 0 ? 0x58c7ff : 0xff6b7a @@ -140,7 +140,7 @@ export function drawVortex(store: EditorStore, vortexGfx: Graphics | null) { const sys = store.systems.find((item) => item.id === store.activeId) if (sys?.visible === false) return const cfg = sys?.config - if (!cfg?.vortex || cfg.vortexRadius <= 0) return + if (!cfg?.vortex || !cfg.showVortexShape || cfg.vortexRadius <= 0) return const x = cfg.vortexCenterX const y = -cfg.vortexCenterY const color = cfg.vortexStrength >= 0 ? 0xb97cff : 0xffa24c @@ -168,7 +168,7 @@ export function drawAttraction(store: EditorStore, attractionGfx: Graphics | nul const sys = store.systems.find((item) => item.id === store.activeId) if (sys?.visible === false) return const cfg = sys?.config - if (!cfg?.attraction) return + if (!cfg?.attraction || !cfg.showAttractionShape) return const x = cfg.attractionCenterX const y = -cfg.attractionCenterY const radius = Math.max(0, cfg.attractionRadius)