@flighthq/particles-formats 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/detect.d.ts +18 -0
  2. package/dist/detect.d.ts.map +1 -0
  3. package/dist/detect.js +75 -0
  4. package/dist/detect.js.map +1 -0
  5. package/dist/formatRegistry.d.ts +60 -0
  6. package/dist/formatRegistry.d.ts.map +1 -0
  7. package/dist/formatRegistry.js +75 -0
  8. package/dist/formatRegistry.js.map +1 -0
  9. package/dist/index.d.ts +21 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +21 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/libgdxParse.d.ts +27 -0
  14. package/dist/libgdxParse.d.ts.map +1 -0
  15. package/dist/libgdxParse.js +316 -0
  16. package/dist/libgdxParse.js.map +1 -0
  17. package/dist/libgdxSchema.d.ts +68 -0
  18. package/dist/libgdxSchema.d.ts.map +1 -0
  19. package/dist/libgdxSchema.js +12 -0
  20. package/dist/libgdxSchema.js.map +1 -0
  21. package/dist/libgdxSerialize.d.ts +17 -0
  22. package/dist/libgdxSerialize.d.ts.map +1 -0
  23. package/dist/libgdxSerialize.js +295 -0
  24. package/dist/libgdxSerialize.js.map +1 -0
  25. package/dist/parseParticleConfig.d.ts +34 -0
  26. package/dist/parseParticleConfig.d.ts.map +1 -0
  27. package/dist/parseParticleConfig.js +96 -0
  28. package/dist/parseParticleConfig.js.map +1 -0
  29. package/dist/particleDesignerParse.d.ts +23 -0
  30. package/dist/particleDesignerParse.d.ts.map +1 -0
  31. package/dist/particleDesignerParse.js +214 -0
  32. package/dist/particleDesignerParse.js.map +1 -0
  33. package/dist/particleDesignerSchema.d.ts +51 -0
  34. package/dist/particleDesignerSchema.d.ts.map +1 -0
  35. package/dist/particleDesignerSchema.js +5 -0
  36. package/dist/particleDesignerSchema.js.map +1 -0
  37. package/dist/particleDesignerSerialize.d.ts +22 -0
  38. package/dist/particleDesignerSerialize.d.ts.map +1 -0
  39. package/dist/particleDesignerSerialize.js +209 -0
  40. package/dist/particleDesignerSerialize.js.map +1 -0
  41. package/dist/pixiParse.d.ts +18 -0
  42. package/dist/pixiParse.d.ts.map +1 -0
  43. package/dist/pixiParse.js +173 -0
  44. package/dist/pixiParse.js.map +1 -0
  45. package/dist/serializeResult.d.ts +15 -0
  46. package/dist/serializeResult.d.ts.map +1 -0
  47. package/dist/serializeResult.js +2 -0
  48. package/dist/serializeResult.js.map +1 -0
  49. package/dist/spineParse.d.ts +18 -0
  50. package/dist/spineParse.d.ts.map +1 -0
  51. package/dist/spineParse.js +263 -0
  52. package/dist/spineParse.js.map +1 -0
  53. package/dist/spineSchema.d.ts +41 -0
  54. package/dist/spineSchema.d.ts.map +1 -0
  55. package/dist/spineSchema.js +8 -0
  56. package/dist/spineSchema.js.map +1 -0
  57. package/dist/spineSerialize.d.ts +16 -0
  58. package/dist/spineSerialize.d.ts.map +1 -0
  59. package/dist/spineSerialize.js +108 -0
  60. package/dist/spineSerialize.js.map +1 -0
  61. package/dist/starlingPexParse.d.ts +29 -0
  62. package/dist/starlingPexParse.d.ts.map +1 -0
  63. package/dist/starlingPexParse.js +254 -0
  64. package/dist/starlingPexParse.js.map +1 -0
  65. package/dist/starlingPexSchema.d.ts +49 -0
  66. package/dist/starlingPexSchema.d.ts.map +1 -0
  67. package/dist/starlingPexSchema.js +15 -0
  68. package/dist/starlingPexSchema.js.map +1 -0
  69. package/dist/starlingPexSerialize.d.ts +20 -0
  70. package/dist/starlingPexSerialize.d.ts.map +1 -0
  71. package/dist/starlingPexSerialize.js +184 -0
  72. package/dist/starlingPexSerialize.js.map +1 -0
  73. package/dist/unityParse.d.ts +23 -0
  74. package/dist/unityParse.d.ts.map +1 -0
  75. package/dist/unityParse.js +347 -0
  76. package/dist/unityParse.js.map +1 -0
  77. package/dist/unitySchema.d.ts +109 -0
  78. package/dist/unitySchema.d.ts.map +1 -0
  79. package/dist/unitySchema.js +9 -0
  80. package/dist/unitySchema.js.map +1 -0
  81. package/dist/unitySerialize.d.ts +20 -0
  82. package/dist/unitySerialize.d.ts.map +1 -0
  83. package/dist/unitySerialize.js +148 -0
  84. package/dist/unitySerialize.js.map +1 -0
  85. package/package.json +38 -0
  86. package/src/detect.test.ts +99 -0
  87. package/src/formatRegistry.test.ts +118 -0
  88. package/src/libgdxParse.test.ts +309 -0
  89. package/src/libgdxSerialize.test.ts +279 -0
  90. package/src/parseParticleConfig.test.ts +447 -0
  91. package/src/particleDesignerParse.test.ts +279 -0
  92. package/src/particleDesignerSerialize.test.ts +113 -0
  93. package/src/pixiParse.test.ts +131 -0
  94. package/src/spineParse.test.ts +289 -0
  95. package/src/spineSerialize.test.ts +81 -0
  96. package/src/starlingPexParse.test.ts +154 -0
  97. package/src/starlingPexSerialize.test.ts +115 -0
  98. package/src/unityParse.test.ts +328 -0
  99. package/src/unitySerialize.test.ts +77 -0
@@ -0,0 +1,173 @@
1
+ import { createParticleEmitterConfig } from '@flighthq/particles';
2
+ /** Parse a Pixi.js / pixi-particle-emitter JSON config string directly to a ParticleEmitterConfig.
3
+ *
4
+ * Supports the pixi-particle-emitter v3/v4/v5 config shape.
5
+ * Throws a clear, format-tagged error when the input is not valid JSON or not an object. */
6
+ export function parsePixiParticle(json) {
7
+ return rawToConfig(parsePixiJson(json));
8
+ }
9
+ /** Parse a Pixi.js / pixi-particle-emitter JSON config string, returning the config
10
+ * and any import warnings for features that could not be represented. */
11
+ export function parsePixiParticleDocument(json) {
12
+ const raw = parsePixiJson(json);
13
+ return {
14
+ config: rawToConfig(raw),
15
+ warnings: collectPixiWarnings(raw),
16
+ };
17
+ }
18
+ const DEG2RAD = Math.PI / 180;
19
+ function collectPixiWarnings(raw) {
20
+ const warnings = [];
21
+ // Pixi supports spawnBurst which has no equivalent
22
+ if (raw.spawnBurst !== undefined) {
23
+ warnings.push('Pixi spawnBurst spawn type has no equivalent and was mapped to point emitter');
24
+ }
25
+ // Pixi spawnPolygon
26
+ if (raw.spawnPolygon !== undefined) {
27
+ warnings.push('Pixi spawnPolygon spawn type has no equivalent and was mapped to point emitter');
28
+ }
29
+ // Pixi acceleration (only warn when non-zero)
30
+ const accel = raw.acceleration;
31
+ if (accel !== undefined && (rn(accel.x, 0) !== 0 || rn(accel.y, 0) !== 0)) {
32
+ warnings.push('Pixi acceleration is not supported and was ignored');
33
+ }
34
+ // extraData / behaviors
35
+ if (raw.behaviors !== undefined) {
36
+ warnings.push('Pixi v5+ behaviors array is partially supported; only core properties were imported');
37
+ }
38
+ return warnings;
39
+ }
40
+ function parsePixiJson(json) {
41
+ let raw;
42
+ try {
43
+ raw = JSON.parse(json);
44
+ }
45
+ catch (e) {
46
+ throw new Error(`Invalid Pixi particle JSON: ${e.message}`);
47
+ }
48
+ if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
49
+ throw new Error(`Invalid Pixi particle document: expected a JSON object, got ${raw === null ? 'null' : Array.isArray(raw) ? 'array' : typeof raw}`);
50
+ }
51
+ return raw;
52
+ }
53
+ // The pixi-particle-emitter config shape (v5/v6):
54
+ // { pos: {x,y}, spawnRect/{...}, frequency, maxParticles, lifetime: {min,max},
55
+ // speed: {start,end}, scale: {start,end}, alpha: {start,end},
56
+ // color: {start,end}, blendMode, angle: {start,end}, startRotation: {min,max},
57
+ // noRotation, rotationSpeed, ... }
58
+ function rawToConfig(raw) {
59
+ const maxParticles = rn(raw.maxParticles, 1000) | 0;
60
+ const frequency = rn(raw.frequency, 0.1);
61
+ const spawnRate = frequency > 0 ? 1 / frequency : 10;
62
+ // Lifetime
63
+ const life = raw.lifetime;
64
+ const lifetimeMin = rn(life?.min, 0.5);
65
+ const lifetimeMax = rn(life?.max, 1.0);
66
+ // Speed
67
+ const [speedStart, speedEnd] = readStartEnd(raw.speed, 100, 50);
68
+ const speedMin = Math.min(speedStart, speedEnd);
69
+ const speedMax = Math.max(speedStart, speedEnd);
70
+ // Scale
71
+ const [scaleStart, scaleEnd] = readStartEnd(raw.scale, 1, 0.5);
72
+ const scaleMin = Math.min(scaleStart, scaleEnd);
73
+ const scaleMax = Math.max(scaleStart, scaleEnd);
74
+ const scaleEndRatio = scaleMax > 0 ? Math.min(scaleStart, scaleEnd) / scaleMax : 1;
75
+ // Alpha
76
+ const [alphaStart, alphaEnd] = readStartEnd(raw.alpha, 1, 0);
77
+ // Color
78
+ const colorObj = raw.color;
79
+ const [sr, sg, sb] = readColor(colorObj?.start, 'ffffff');
80
+ const [er, eg, eb] = readColor(colorObj?.end, 'ffffff');
81
+ // Angle (emit direction)
82
+ const angleObj = raw.angle;
83
+ const angleMin = rn(angleObj?.min, 0);
84
+ const angleMax = rn(angleObj?.max, 360);
85
+ const angleMid = (angleMin + angleMax) * 0.5 * DEG2RAD;
86
+ const spread = (angleMax - angleMin) * 0.5 * DEG2RAD;
87
+ // Spawn shape: pos + optional spawnRect/spawnCircle/spawnBurst
88
+ let emitterShape = 'point';
89
+ let emitterRadius = 0;
90
+ let emitterWidth = 0;
91
+ let emitterHeight = 0;
92
+ const spawnRect = raw.spawnRect;
93
+ const spawnCircle = raw.spawnCircle;
94
+ if (spawnCircle) {
95
+ emitterShape = 'circle';
96
+ emitterRadius = rn(spawnCircle.r, 0);
97
+ }
98
+ else if (spawnRect) {
99
+ emitterShape = 'rect';
100
+ emitterWidth = rn(spawnRect.w, 0);
101
+ emitterHeight = rn(spawnRect.h, 0);
102
+ }
103
+ // Blend mode
104
+ const blendModeStr = rs(raw.blendMode, 'normal').toLowerCase();
105
+ let blendMode = null;
106
+ if (blendModeStr === 'add' || blendModeStr === 'additive')
107
+ blendMode = 'add';
108
+ else if (blendModeStr === 'multiply')
109
+ blendMode = 'multiply';
110
+ else if (blendModeStr === 'screen')
111
+ blendMode = 'screen';
112
+ else if (blendModeStr === 'normal' || blendModeStr === 'src_alpha')
113
+ blendMode = 'normal';
114
+ // Rotation speed
115
+ const rotationSpeed = rn(raw.rotationSpeed, 0) * DEG2RAD;
116
+ return createParticleEmitterConfig({
117
+ maxParticles,
118
+ spawnRate,
119
+ lifetimeMin,
120
+ lifetimeMax,
121
+ speedMin,
122
+ speedMax,
123
+ directionX: Math.cos(angleMid),
124
+ directionY: Math.sin(angleMid),
125
+ spread,
126
+ emitterShape,
127
+ emitterRadius,
128
+ emitterWidth,
129
+ emitterHeight,
130
+ scaleMin,
131
+ scaleMax,
132
+ scaleEnd: scaleEndRatio,
133
+ colorStartR: sr,
134
+ colorStartG: sg,
135
+ colorStartB: sb,
136
+ colorEndR: er,
137
+ colorEndG: eg,
138
+ colorEndB: eb,
139
+ alphaStart,
140
+ alphaEnd,
141
+ rotationSpeedMin: rotationSpeed,
142
+ rotationSpeedMax: rotationSpeed,
143
+ blendMode,
144
+ });
145
+ }
146
+ function readColor(obj, def = 'ffffff') {
147
+ const valueObj = obj;
148
+ const hex = typeof obj === 'string' ? obj : typeof valueObj?.value === 'string' ? valueObj.value : def;
149
+ const s = hex.replace(/^#/, '').padEnd(6, 'f');
150
+ const channel = (i) => {
151
+ const v = parseInt(s.slice(i, i + 2), 16);
152
+ return Number.isFinite(v) ? v / 255 : 1;
153
+ };
154
+ return [channel(0), channel(2), channel(4)];
155
+ }
156
+ /** Read a pixi-particle-emitter "start/end" value pair (both may be a number or a {value} object). */
157
+ function readStartEnd(obj, defStart = 1, defEnd = 0) {
158
+ if (obj == null || typeof obj !== 'object')
159
+ return [defStart, defEnd];
160
+ const o = obj;
161
+ const startObj = o.start;
162
+ const endObj = o.end;
163
+ const start = typeof o.start === 'number' ? o.start : typeof startObj?.value === 'number' ? startObj.value : defStart;
164
+ const end = typeof o.end === 'number' ? o.end : typeof endObj?.value === 'number' ? endObj.value : defEnd;
165
+ return [rn(start, defStart), rn(end, defEnd)];
166
+ }
167
+ function rn(v, def = 0) {
168
+ return typeof v === 'number' && Number.isFinite(v) ? v : def;
169
+ }
170
+ function rs(v, def = '') {
171
+ return typeof v === 'string' ? v : def;
172
+ }
173
+ //# sourceMappingURL=pixiParse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pixiParse.js","sourceRoot":"","sources":["../src/pixiParse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /** The result of a particle-format serialize operation.
2
+ *
3
+ * `text` is the serialized format string. `warnings` lists features present in
4
+ * the source config that the target format cannot represent and were silently
5
+ * dropped or approximated — surface these in your asset pipeline to audit export
6
+ * fidelity. An empty `warnings` array means the export is lossless for the
7
+ * features the target format supports. */
8
+ export interface ParticleSerializeResult {
9
+ /** The serialized format string. */
10
+ readonly text: string;
11
+ /** Features in the config that the target format cannot represent and were
12
+ * dropped or approximated during serialization. */
13
+ readonly warnings: string[];
14
+ }
15
+ //# sourceMappingURL=serializeResult.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serializeResult.d.ts","sourceRoot":"","sources":["../src/serializeResult.ts"],"names":[],"mappings":"AAAA;;;;;;2CAM2C;AAC3C,MAAM,WAAW,uBAAuB;IACtC,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;wDACoD;IACpD,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;CAC7B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=serializeResult.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serializeResult.js","sourceRoot":"","sources":["../src/serializeResult.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ import type { ParticleEmitterConfig } from '@flighthq/types';
2
+ import type { SpineParticleDocument } from './spineSchema';
3
+ export interface SpineParsed {
4
+ config: ParticleEmitterConfig;
5
+ document: SpineParticleDocument;
6
+ /** Features present in the source that the common-subset importer cannot
7
+ * represent and silently dropped — surface these in your asset pipeline. */
8
+ warnings: string[];
9
+ }
10
+ /** Parse a Spine particle effect JSON string directly to a ParticleEmitterConfig.
11
+ *
12
+ * Single-pass: no intermediate document object is allocated.
13
+ * Use `parseSpineParticleDocument` instead when you need round-trip serialisation. */
14
+ export declare function parseSpineParticle(json: string): ParticleEmitterConfig;
15
+ /** Parse a Spine particle effect JSON string and preserve the full document for
16
+ * round-trip serialisation via `serializeSpineParticle`. */
17
+ export declare function parseSpineParticleDocument(json: string): SpineParsed;
18
+ //# sourceMappingURL=spineParse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spineParse.d.ts","sourceRoot":"","sources":["../src/spineParse.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAKV,qBAAqB,EACtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAsB,qBAAqB,EAAqB,MAAM,eAAe,CAAC;AAElG,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,qBAAqB,CAAC;IAC9B,QAAQ,EAAE,qBAAqB,CAAC;IAChC;iFAC6E;IAC7E,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AA4QD;;;uFAGuF;AACvF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,CAEtE;AAED;6DAC6D;AAC7D,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAGpE"}
@@ -0,0 +1,263 @@
1
+ import { createParticleEmitterConfig, particleColorCurveFromKeyframes, particleCurveFromKeyframes, } from '@flighthq/particles';
2
+ const DEG2RAD = Math.PI / 180;
3
+ // ─── Value helpers (operate on raw JSON, no document allocation) ─────────────
4
+ /** Parse a JSON string and assert the root is a plain object, throwing a clear,
5
+ * format-tagged error otherwise. Particle assets are frequently hand-edited or
6
+ * produced by external tools, so a corrupt or empty file must fail with an
7
+ * actionable message rather than a cryptic `Cannot read properties of null`. */
8
+ function parseSpineJson(json) {
9
+ let raw;
10
+ try {
11
+ raw = JSON.parse(json);
12
+ }
13
+ catch (e) {
14
+ throw new Error(`Invalid Spine particle JSON: ${e.message}`);
15
+ }
16
+ if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
17
+ throw new Error(`Invalid Spine particle document: expected a JSON object, got ${raw === null ? 'null' : Array.isArray(raw) ? 'array' : typeof raw}`);
18
+ }
19
+ return raw;
20
+ }
21
+ function rangeMid(obj, def = 0) {
22
+ if (obj != null && typeof obj === 'object') {
23
+ const o = obj;
24
+ const lo = typeof o.low === 'number' ? o.low : def;
25
+ const hi = typeof o.high === 'number' ? o.high : def;
26
+ return (lo + hi) * 0.5;
27
+ }
28
+ return def;
29
+ }
30
+ function rangeLow(obj, def = 0) {
31
+ if (obj != null && typeof obj === 'object') {
32
+ const o = obj;
33
+ return typeof o.low === 'number' ? o.low : def;
34
+ }
35
+ return def;
36
+ }
37
+ function rangeHigh(obj, def = 0) {
38
+ if (obj != null && typeof obj === 'object') {
39
+ const o = obj;
40
+ return typeof o.high === 'number' ? o.high : def;
41
+ }
42
+ return def;
43
+ }
44
+ function hexToRgb(hex) {
45
+ const s = hex.replace('#', '').padEnd(6, 'f');
46
+ // Fall back to a full channel (1) for any non-hex pair so a malformed color
47
+ // string never injects NaN into the config (which would poison the simulation).
48
+ const channel = (i) => {
49
+ const v = parseInt(s.slice(i, i + 2), 16);
50
+ return Number.isFinite(v) ? v / 255 : 1;
51
+ };
52
+ return [channel(0), channel(2), channel(4)];
53
+ }
54
+ function firstTintColor(arr) {
55
+ return hexToRgb(Array.isArray(arr) && arr.length > 0
56
+ ? (arr[0].color ?? 'ffffff')
57
+ : 'ffffff');
58
+ }
59
+ function lastTintColor(arr) {
60
+ if (!Array.isArray(arr) || arr.length === 0)
61
+ return [1, 1, 1];
62
+ return hexToRgb(arr[arr.length - 1].color ?? 'ffffff');
63
+ }
64
+ function firstAlpha(arr) {
65
+ return Array.isArray(arr) && arr.length > 0 ? (arr[0].alpha ?? 1) : 1;
66
+ }
67
+ function lastAlpha(arr) {
68
+ if (!Array.isArray(arr) || arr.length === 0)
69
+ return 0;
70
+ return arr[arr.length - 1].alpha ?? 0;
71
+ }
72
+ // ─── Shared raw → config mapping ─────────────────────────────────────────────
73
+ function rawToConfig(raw) {
74
+ const lifeLow = rangeLow(raw.life, 500) / 1000;
75
+ const lifeHigh = rangeHigh(raw.life, 1500) / 1000;
76
+ const angleLow = rangeLow(raw.angle, 60);
77
+ const angleHigh = rangeHigh(raw.angle, 120);
78
+ const angleMid = (angleLow + angleHigh) * 0.5 * DEG2RAD;
79
+ const spread = (angleHigh - angleLow) * 0.5 * DEG2RAD;
80
+ const spawnShape = typeof raw.spawnShape === 'string' ? raw.spawnShape : 'point';
81
+ const sx = rangeMid(raw.spawnWidth, 0);
82
+ const sy = rangeMid(raw.spawnHeight, 0);
83
+ const emitterShape = spawnShape === 'ellipse' ? (sx === sy ? 'circle' : 'rect') : 'point';
84
+ const spawnScaleMid = rangeMid(raw.scale, 1);
85
+ const endScaleMid = rangeMid(raw.scaleEnd, 0);
86
+ const startTint = firstTintColor(raw.tint);
87
+ const endTint = lastTintColor(raw.tint);
88
+ // Multi-stop tint/alpha timelines bake into lifetime curves (preserves the full
89
+ // shape); 2-stop timelines fall back to the linear start→end path.
90
+ const colorCurve = tintKeyframesToCurve(raw.tint);
91
+ const alphaCurve = alphaKeyframesToCurve(raw.alpha);
92
+ // A continuous Spine emitter emits forever; otherwise `duration` (ms) bounds it.
93
+ const continuous = typeof raw.continuous === 'boolean' ? raw.continuous : true;
94
+ const durationMs = typeof raw.duration === 'number' ? raw.duration : -1;
95
+ return createParticleEmitterConfig({
96
+ maxParticles: typeof raw.maxParticles === 'number' ? raw.maxParticles | 0 : 500,
97
+ spawnRate: rangeMid(raw.emission, 20),
98
+ loop: continuous,
99
+ duration: !continuous && durationMs > 0 ? durationMs / 1000 : 0,
100
+ colorCurve,
101
+ alphaCurve,
102
+ lifetimeMin: lifeLow,
103
+ lifetimeMax: lifeHigh,
104
+ speedMin: rangeLow(raw.velocity, 50),
105
+ speedMax: rangeHigh(raw.velocity, 150),
106
+ directionX: Math.cos(angleMid),
107
+ directionY: -Math.sin(angleMid),
108
+ spread,
109
+ gravityX: rangeMid(raw.wind, 0),
110
+ gravityY: rangeMid(raw.gravity, 0),
111
+ emitterShape,
112
+ emitterRadius: emitterShape === 'circle' ? sx * 0.5 : 0,
113
+ emitterWidth: emitterShape === 'rect' ? sx : 0,
114
+ emitterHeight: emitterShape === 'rect' ? sy : 0,
115
+ scaleMin: rangeLow(raw.scale, 1),
116
+ scaleMax: rangeHigh(raw.scale, 1),
117
+ scaleEnd: spawnScaleMid > 0 ? endScaleMid / spawnScaleMid : 0,
118
+ colorStartR: startTint[0],
119
+ colorStartG: startTint[1],
120
+ colorStartB: startTint[2],
121
+ colorEndR: endTint[0],
122
+ colorEndG: endTint[1],
123
+ colorEndB: endTint[2],
124
+ alphaStart: firstAlpha(raw.alpha),
125
+ alphaEnd: lastAlpha(raw.alpha),
126
+ rotationSpeedMin: rangeLow(raw.rotation, 0) * DEG2RAD,
127
+ rotationSpeedMax: rangeHigh(raw.rotation, 0) * DEG2RAD,
128
+ blendMode: spineBlendMode(typeof raw.blendMode === 'string' ? raw.blendMode : 'normal'),
129
+ });
130
+ }
131
+ function collectSpineWarnings(raw) {
132
+ const warnings = [];
133
+ // Multi-stop tint/alpha timelines are now baked into lifetime curves, so they
134
+ // no longer warn. Remaining unsupported features:
135
+ const nonZeroRange = (key) => {
136
+ const o = raw[key];
137
+ if (o == null || typeof o !== 'object')
138
+ return false;
139
+ const r = o;
140
+ return (typeof r.low === 'number' && r.low !== 0) || (typeof r.high === 'number' && r.high !== 0);
141
+ };
142
+ if (nonZeroRange('lifeOffset'))
143
+ warnings.push('Spine lifeOffset is not supported and was ignored');
144
+ if (nonZeroRange('x') || nonZeroRange('y')) {
145
+ warnings.push('Spine emitter x/y position ranges are not supported and were ignored');
146
+ }
147
+ return warnings;
148
+ }
149
+ // Build a color curve from a tint timeline, but only when it has more than two
150
+ // stops (a 2-stop timeline is exactly the linear start→end path, so we skip it).
151
+ function tintKeyframesToCurve(arr) {
152
+ if (!Array.isArray(arr) || arr.length <= 2)
153
+ return null;
154
+ const keys = [];
155
+ for (let i = 0; i < arr.length; i++) {
156
+ const k = arr[i];
157
+ const [r, g, b] = hexToRgb(typeof k.color === 'string' ? k.color : 'ffffff');
158
+ keys.push({ time: typeof k.time === 'number' ? k.time : i / (arr.length - 1), r, g, b });
159
+ }
160
+ return particleColorCurveFromKeyframes(keys);
161
+ }
162
+ function alphaKeyframesToCurve(arr) {
163
+ if (!Array.isArray(arr) || arr.length <= 2)
164
+ return null;
165
+ const keys = [];
166
+ for (let i = 0; i < arr.length; i++) {
167
+ const k = arr[i];
168
+ keys.push({
169
+ time: typeof k.time === 'number' ? k.time : i / (arr.length - 1),
170
+ value: typeof k.alpha === 'number' ? k.alpha : 1,
171
+ });
172
+ }
173
+ return particleCurveFromKeyframes(keys);
174
+ }
175
+ function spineBlendMode(mode) {
176
+ if (mode === 'additive')
177
+ return 'add';
178
+ if (mode === 'multiply')
179
+ return 'multiply';
180
+ if (mode === 'screen')
181
+ return 'screen';
182
+ if (mode === 'normal')
183
+ return 'normal';
184
+ return null;
185
+ }
186
+ // ─── Document construction (load path only) ──────────────────────────────────
187
+ function rawToDocument(raw) {
188
+ const s = (k, def) => (typeof raw[k] === 'string' ? raw[k] : def);
189
+ const n = (k, def) => (typeof raw[k] === 'number' ? raw[k] : def);
190
+ const b = (k, def) => (typeof raw[k] === 'boolean' ? raw[k] : def);
191
+ const rv = (obj, lo = 0, hi = 0) => ({
192
+ low: obj != null && typeof obj === 'object' && typeof obj.low === 'number'
193
+ ? obj.low
194
+ : lo,
195
+ high: obj != null && typeof obj === 'object' && typeof obj.high === 'number'
196
+ ? obj.high
197
+ : hi,
198
+ });
199
+ const tintKfs = (arr) => Array.isArray(arr)
200
+ ? arr.map((k) => ({
201
+ time: typeof k.time === 'number'
202
+ ? k.time
203
+ : 0,
204
+ color: typeof k.color === 'string'
205
+ ? k.color
206
+ : 'ffffff',
207
+ }))
208
+ : [{ time: 0, color: 'ffffff' }];
209
+ const alphaKfs = (arr) => Array.isArray(arr)
210
+ ? arr.map((k) => ({
211
+ time: typeof k.time === 'number'
212
+ ? k.time
213
+ : 0,
214
+ alpha: typeof k.alpha === 'number'
215
+ ? k.alpha
216
+ : 1,
217
+ }))
218
+ : [
219
+ { time: 0, alpha: 1 },
220
+ { time: 1, alpha: 0 },
221
+ ];
222
+ return {
223
+ name: s('name', ''),
224
+ maxParticles: n('maxParticles', 500) | 0,
225
+ continuous: b('continuous', true),
226
+ duration: n('duration', -1),
227
+ emission: rv(raw.emission, 10, 30),
228
+ life: rv(raw.life, 500, 1500),
229
+ lifeOffset: rv(raw.lifeOffset, 0, 0),
230
+ x: rv(raw.x, 0, 0),
231
+ y: rv(raw.y, 0, 0),
232
+ spawnShape: s('spawnShape', 'point'),
233
+ spawnWidth: rv(raw.spawnWidth, 0, 0),
234
+ spawnHeight: rv(raw.spawnHeight, 0, 0),
235
+ velocity: rv(raw.velocity, 50, 150),
236
+ angle: rv(raw.angle, 60, 120),
237
+ rotation: rv(raw.rotation, 0, 0),
238
+ wind: rv(raw.wind, 0, 0),
239
+ gravity: rv(raw.gravity, 0, 0),
240
+ scale: rv(raw.scale, 1, 1),
241
+ scaleEnd: rv(raw.scaleEnd, 0, 0),
242
+ tint: tintKfs(raw.tint),
243
+ alpha: alphaKfs(raw.alpha),
244
+ blendMode: s('blendMode', 'normal'),
245
+ premultiplied: b('premultiplied', false),
246
+ images: Array.isArray(raw.images) ? raw.images : [],
247
+ };
248
+ }
249
+ // ─── Public API ──────────────────────────────────────────────────────────────
250
+ /** Parse a Spine particle effect JSON string directly to a ParticleEmitterConfig.
251
+ *
252
+ * Single-pass: no intermediate document object is allocated.
253
+ * Use `parseSpineParticleDocument` instead when you need round-trip serialisation. */
254
+ export function parseSpineParticle(json) {
255
+ return rawToConfig(parseSpineJson(json));
256
+ }
257
+ /** Parse a Spine particle effect JSON string and preserve the full document for
258
+ * round-trip serialisation via `serializeSpineParticle`. */
259
+ export function parseSpineParticleDocument(json) {
260
+ const raw = parseSpineJson(json);
261
+ return { config: rawToConfig(raw), document: rawToDocument(raw), warnings: collectSpineWarnings(raw) };
262
+ }
263
+ //# sourceMappingURL=spineParse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spineParse.js","sourceRoot":"","sources":["../src/spineParse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ export type SpineBlendMode = 'normal' | 'additive' | 'multiply' | 'screen';
2
+ export interface SpineRangeValue {
3
+ low: number;
4
+ high: number;
5
+ }
6
+ export interface SpineAlphaKeyframe {
7
+ time: number;
8
+ alpha: number;
9
+ }
10
+ export interface SpineTintKeyframe {
11
+ time: number;
12
+ color: string;
13
+ }
14
+ /** Full Spine particle effect document. */
15
+ export interface SpineParticleDocument {
16
+ name: string;
17
+ maxParticles: number;
18
+ continuous: boolean;
19
+ duration: number;
20
+ emission: SpineRangeValue;
21
+ life: SpineRangeValue;
22
+ lifeOffset: SpineRangeValue;
23
+ x: SpineRangeValue;
24
+ y: SpineRangeValue;
25
+ spawnShape: 'point' | 'ellipse' | 'line';
26
+ spawnWidth: SpineRangeValue;
27
+ spawnHeight: SpineRangeValue;
28
+ velocity: SpineRangeValue;
29
+ angle: SpineRangeValue;
30
+ rotation: SpineRangeValue;
31
+ wind: SpineRangeValue;
32
+ gravity: SpineRangeValue;
33
+ scale: SpineRangeValue;
34
+ scaleEnd: SpineRangeValue;
35
+ tint: SpineTintKeyframe[];
36
+ alpha: SpineAlphaKeyframe[];
37
+ blendMode: SpineBlendMode;
38
+ premultiplied: boolean;
39
+ images: string[];
40
+ }
41
+ //# sourceMappingURL=spineSchema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spineSchema.d.ts","sourceRoot":"","sources":["../src/spineSchema.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE3E,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,2CAA2C;AAC3C,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IAGb,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IAGjB,QAAQ,EAAE,eAAe,CAAC;IAG1B,IAAI,EAAE,eAAe,CAAC;IACtB,UAAU,EAAE,eAAe,CAAC;IAG5B,CAAC,EAAE,eAAe,CAAC;IACnB,CAAC,EAAE,eAAe,CAAC;IACnB,UAAU,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACzC,UAAU,EAAE,eAAe,CAAC;IAC5B,WAAW,EAAE,eAAe,CAAC;IAG7B,QAAQ,EAAE,eAAe,CAAC;IAC1B,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,eAAe,CAAC;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,eAAe,CAAC;IAGzB,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,EAAE,eAAe,CAAC;IAC1B,IAAI,EAAE,iBAAiB,EAAE,CAAC;IAC1B,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,SAAS,EAAE,cAAc,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IAGvB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB"}
@@ -0,0 +1,8 @@
1
+ // Spine particle effect JSON schema.
2
+ // Targets the Spine 4.x particle effect format (`.p` JSON variant) as documented by
3
+ // Esoteric Software: https://esotericsoftware.com/spine-particle-effects
4
+ //
5
+ // Field naming follows the Spine editor export conventions.
6
+ // Units: time in milliseconds, sizes in pixels, angles in degrees.
7
+ export {};
8
+ //# sourceMappingURL=spineSchema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spineSchema.js","sourceRoot":"","sources":["../src/spineSchema.ts"],"names":[],"mappings":"AAAA,qCAAqC;AACrC,oFAAoF;AACpF,yEAAyE;AACzE,EAAE;AACF,4DAA4D;AAC5D,mEAAmE"}
@@ -0,0 +1,16 @@
1
+ import type { ParticleEmitterConfig } from '@flighthq/types';
2
+ import type { ParticleSerializeResult } from './serializeResult';
3
+ import type { SpineParticleDocument } from './spineSchema';
4
+ /** Serialise a ParticleEmitterConfig to a Spine particle effect JSON string.
5
+ *
6
+ * Pass the `document` returned by `parseSpineParticle` to preserve fields
7
+ * that don't round-trip through the config (name, image list, blend mode, etc.). */
8
+ export declare function serializeSpineParticle(config: Readonly<ParticleEmitterConfig>, existing?: Partial<SpineParticleDocument>): string;
9
+ /** Serialise a ParticleEmitterConfig to a Spine particle effect JSON string,
10
+ * returning both the serialized text and any warnings for features the format
11
+ * cannot represent.
12
+ *
13
+ * Pass the `document` returned by `parseSpineParticleDocument` to preserve
14
+ * fields that don't round-trip through the config. */
15
+ export declare function serializeSpineParticleDocument(config: Readonly<ParticleEmitterConfig>, existing?: Partial<SpineParticleDocument>): ParticleSerializeResult;
16
+ //# sourceMappingURL=spineSerialize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spineSerialize.d.ts","sourceRoot":"","sources":["../src/spineSerialize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAqB,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAEhF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,KAAK,EAAsB,qBAAqB,EAAqB,MAAM,eAAe,CAAC;AAkFlG;;;qFAGqF;AACrF,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,EACvC,QAAQ,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACxC,MAAM,CAGR;AAED;;;;;uDAKuD;AACvD,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,QAAQ,CAAC,qBAAqB,CAAC,EACvC,QAAQ,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,GACxC,uBAAuB,CAIzB"}