debug-vfx 0.0.10 → 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 (3) hide show
  1. package/dist/index.d.ts +240 -5
  2. package/dist/index.js +448 -224
  3. package/package.json +2 -2
package/dist/index.d.ts CHANGED
@@ -1,8 +1,5 @@
1
1
  import * as THREE from 'three';
2
2
 
3
- declare function renderDebugPanel(values: any, onChange: any): void;
4
- declare function updateDebugPanel(values: any, onChange: any): void;
5
- declare function destroyDebugPanel(): void;
6
3
  declare const GeometryType: Readonly<{
7
4
  NONE: "none";
8
5
  BOX: "box";
@@ -19,6 +16,245 @@ declare const GeometryType: Readonly<{
19
16
  TETRAHEDRON: "tetrahedron";
20
17
  CAPSULE: "capsule";
21
18
  }>;
19
+ declare const createGeometry: (type: string, args?: Record<string, number>) => THREE.BufferGeometry | null;
20
+ declare function detectGeometryTypeAndArgs(geo: any): {
21
+ geometryType: string;
22
+ geometryArgs: null;
23
+ } | {
24
+ geometryType: string;
25
+ geometryArgs: {
26
+ width: any;
27
+ height: any;
28
+ depth: any;
29
+ widthSegments: any;
30
+ heightSegments: any;
31
+ depthSegments: any;
32
+ radius?: undefined;
33
+ radiusTop?: undefined;
34
+ radiusBottom?: undefined;
35
+ radialSegments?: undefined;
36
+ tube?: undefined;
37
+ tubularSegments?: undefined;
38
+ segments?: undefined;
39
+ innerRadius?: undefined;
40
+ outerRadius?: undefined;
41
+ thetaSegments?: undefined;
42
+ detail?: undefined;
43
+ length?: undefined;
44
+ capSegments?: undefined;
45
+ };
46
+ } | {
47
+ geometryType: string;
48
+ geometryArgs: {
49
+ radius: any;
50
+ widthSegments: any;
51
+ heightSegments: any;
52
+ width?: undefined;
53
+ height?: undefined;
54
+ depth?: undefined;
55
+ depthSegments?: undefined;
56
+ radiusTop?: undefined;
57
+ radiusBottom?: undefined;
58
+ radialSegments?: undefined;
59
+ tube?: undefined;
60
+ tubularSegments?: undefined;
61
+ segments?: undefined;
62
+ innerRadius?: undefined;
63
+ outerRadius?: undefined;
64
+ thetaSegments?: undefined;
65
+ detail?: undefined;
66
+ length?: undefined;
67
+ capSegments?: undefined;
68
+ };
69
+ } | {
70
+ geometryType: string;
71
+ geometryArgs: {
72
+ radiusTop: any;
73
+ radiusBottom: any;
74
+ height: any;
75
+ radialSegments: any;
76
+ heightSegments: any;
77
+ width?: undefined;
78
+ depth?: undefined;
79
+ widthSegments?: undefined;
80
+ depthSegments?: undefined;
81
+ radius?: undefined;
82
+ tube?: undefined;
83
+ tubularSegments?: undefined;
84
+ segments?: undefined;
85
+ innerRadius?: undefined;
86
+ outerRadius?: undefined;
87
+ thetaSegments?: undefined;
88
+ detail?: undefined;
89
+ length?: undefined;
90
+ capSegments?: undefined;
91
+ };
92
+ } | {
93
+ geometryType: string;
94
+ geometryArgs: {
95
+ radius: any;
96
+ height: any;
97
+ radialSegments: any;
98
+ heightSegments: any;
99
+ width?: undefined;
100
+ depth?: undefined;
101
+ widthSegments?: undefined;
102
+ depthSegments?: undefined;
103
+ radiusTop?: undefined;
104
+ radiusBottom?: undefined;
105
+ tube?: undefined;
106
+ tubularSegments?: undefined;
107
+ segments?: undefined;
108
+ innerRadius?: undefined;
109
+ outerRadius?: undefined;
110
+ thetaSegments?: undefined;
111
+ detail?: undefined;
112
+ length?: undefined;
113
+ capSegments?: undefined;
114
+ };
115
+ } | {
116
+ geometryType: string;
117
+ geometryArgs: {
118
+ radius: any;
119
+ tube: any;
120
+ radialSegments: any;
121
+ tubularSegments: any;
122
+ width?: undefined;
123
+ height?: undefined;
124
+ depth?: undefined;
125
+ widthSegments?: undefined;
126
+ heightSegments?: undefined;
127
+ depthSegments?: undefined;
128
+ radiusTop?: undefined;
129
+ radiusBottom?: undefined;
130
+ segments?: undefined;
131
+ innerRadius?: undefined;
132
+ outerRadius?: undefined;
133
+ thetaSegments?: undefined;
134
+ detail?: undefined;
135
+ length?: undefined;
136
+ capSegments?: undefined;
137
+ };
138
+ } | {
139
+ geometryType: string;
140
+ geometryArgs: {
141
+ width: any;
142
+ height: any;
143
+ widthSegments: any;
144
+ heightSegments: any;
145
+ depth?: undefined;
146
+ depthSegments?: undefined;
147
+ radius?: undefined;
148
+ radiusTop?: undefined;
149
+ radiusBottom?: undefined;
150
+ radialSegments?: undefined;
151
+ tube?: undefined;
152
+ tubularSegments?: undefined;
153
+ segments?: undefined;
154
+ innerRadius?: undefined;
155
+ outerRadius?: undefined;
156
+ thetaSegments?: undefined;
157
+ detail?: undefined;
158
+ length?: undefined;
159
+ capSegments?: undefined;
160
+ };
161
+ } | {
162
+ geometryType: string;
163
+ geometryArgs: {
164
+ radius: any;
165
+ segments: any;
166
+ width?: undefined;
167
+ height?: undefined;
168
+ depth?: undefined;
169
+ widthSegments?: undefined;
170
+ heightSegments?: undefined;
171
+ depthSegments?: undefined;
172
+ radiusTop?: undefined;
173
+ radiusBottom?: undefined;
174
+ radialSegments?: undefined;
175
+ tube?: undefined;
176
+ tubularSegments?: undefined;
177
+ innerRadius?: undefined;
178
+ outerRadius?: undefined;
179
+ thetaSegments?: undefined;
180
+ detail?: undefined;
181
+ length?: undefined;
182
+ capSegments?: undefined;
183
+ };
184
+ } | {
185
+ geometryType: string;
186
+ geometryArgs: {
187
+ innerRadius: any;
188
+ outerRadius: any;
189
+ thetaSegments: any;
190
+ width?: undefined;
191
+ height?: undefined;
192
+ depth?: undefined;
193
+ widthSegments?: undefined;
194
+ heightSegments?: undefined;
195
+ depthSegments?: undefined;
196
+ radius?: undefined;
197
+ radiusTop?: undefined;
198
+ radiusBottom?: undefined;
199
+ radialSegments?: undefined;
200
+ tube?: undefined;
201
+ tubularSegments?: undefined;
202
+ segments?: undefined;
203
+ detail?: undefined;
204
+ length?: undefined;
205
+ capSegments?: undefined;
206
+ };
207
+ } | {
208
+ geometryType: string;
209
+ geometryArgs: {
210
+ radius: any;
211
+ detail: any;
212
+ width?: undefined;
213
+ height?: undefined;
214
+ depth?: undefined;
215
+ widthSegments?: undefined;
216
+ heightSegments?: undefined;
217
+ depthSegments?: undefined;
218
+ radiusTop?: undefined;
219
+ radiusBottom?: undefined;
220
+ radialSegments?: undefined;
221
+ tube?: undefined;
222
+ tubularSegments?: undefined;
223
+ segments?: undefined;
224
+ innerRadius?: undefined;
225
+ outerRadius?: undefined;
226
+ thetaSegments?: undefined;
227
+ length?: undefined;
228
+ capSegments?: undefined;
229
+ };
230
+ } | {
231
+ geometryType: string;
232
+ geometryArgs: {
233
+ radius: any;
234
+ length: any;
235
+ capSegments: any;
236
+ radialSegments: any;
237
+ width?: undefined;
238
+ height?: undefined;
239
+ depth?: undefined;
240
+ widthSegments?: undefined;
241
+ heightSegments?: undefined;
242
+ depthSegments?: undefined;
243
+ radiusTop?: undefined;
244
+ radiusBottom?: undefined;
245
+ tube?: undefined;
246
+ tubularSegments?: undefined;
247
+ segments?: undefined;
248
+ innerRadius?: undefined;
249
+ outerRadius?: undefined;
250
+ thetaSegments?: undefined;
251
+ detail?: undefined;
252
+ };
253
+ };
254
+
255
+ declare function renderDebugPanel(values: any, onChange: any, mode?: string): void;
256
+ declare function updateDebugPanel(values: any, onChange: any, mode?: string): void;
257
+ declare function destroyDebugPanel(): void;
22
258
  declare const DEFAULT_VALUES: Readonly<{
23
259
  maxParticles: 10000;
24
260
  size: number[];
@@ -69,6 +305,5 @@ declare const DEFAULT_VALUES: Readonly<{
69
305
  softDistance: 0.5;
70
306
  collision: null;
71
307
  }>;
72
- declare function createGeometry(type: any, args?: {}): THREE.BoxGeometry | THREE.SphereGeometry | THREE.CylinderGeometry | THREE.TorusGeometry | THREE.PlaneGeometry | THREE.CircleGeometry | THREE.RingGeometry | THREE.DodecahedronGeometry | THREE.IcosahedronGeometry | THREE.OctahedronGeometry | THREE.TetrahedronGeometry | THREE.CapsuleGeometry | null;
73
308
 
74
- export { DEFAULT_VALUES, GeometryType, createGeometry, destroyDebugPanel, renderDebugPanel, updateDebugPanel };
309
+ export { DEFAULT_VALUES, GeometryType, createGeometry, destroyDebugPanel, detectGeometryTypeAndArgs, renderDebugPanel, updateDebugPanel };
package/dist/index.js CHANGED
@@ -31799,7 +31799,6 @@ var import_client = __toESM(require_client(), 1);
31799
31799
  var import_react2 = __toESM(require_react(), 1);
31800
31800
  import { Appearance, Blending, EmitterShape, Lighting } from "core-vfx";
31801
31801
  import { buildCurveTextureBin } from "core-vfx";
31802
- import * as THREE from "three";
31803
31802
 
31804
31803
  // ../../node_modules/zustand/esm/vanilla.mjs
31805
31804
  var createStoreImpl = (createState) => {
@@ -31845,15 +31844,8 @@ var createImpl = (createState) => {
31845
31844
  };
31846
31845
  var create = ((createState) => createState ? createImpl(createState) : createImpl);
31847
31846
 
31848
- // src/VFXParticlesDebugPanel.jsx
31849
- var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
31850
- var useDebugPanelStore = create(() => ({
31851
- flushChangesRef: { current: null }
31852
- }));
31853
- var getFlushChanges = () => useDebugPanelStore.getState().flushChangesRef.current;
31854
- var setFlushChanges = (fn) => {
31855
- useDebugPanelStore.getState().flushChangesRef.current = fn;
31856
- };
31847
+ // src/geometry.ts
31848
+ import * as THREE from "three";
31857
31849
  var GeometryType = Object.freeze({
31858
31850
  NONE: "none",
31859
31851
  // Sprite mode (no geometry)
@@ -31923,69 +31915,6 @@ var geometryDefaults = {
31923
31915
  radialSegments: 8
31924
31916
  }
31925
31917
  };
31926
- var DEFAULT_VALUES = Object.freeze({
31927
- maxParticles: 1e4,
31928
- size: [0.1, 0.3],
31929
- colorStart: ["#ffffff"],
31930
- colorEnd: null,
31931
- fadeSize: [1, 0],
31932
- fadeSizeCurve: null,
31933
- fadeOpacity: [1, 0],
31934
- fadeOpacityCurve: null,
31935
- velocityCurve: null,
31936
- gravity: [0, 0, 0],
31937
- lifetime: [1, 2],
31938
- direction: [
31939
- [-1, 1],
31940
- [0, 1],
31941
- [-1, 1]
31942
- ],
31943
- startPosition: [
31944
- [0, 0],
31945
- [0, 0],
31946
- [0, 0]
31947
- ],
31948
- speed: [0.1, 0.1],
31949
- friction: { intensity: 0, easing: "linear" },
31950
- appearance: Appearance.GRADIENT,
31951
- rotation: [
31952
- [0, 0],
31953
- [0, 0],
31954
- [0, 0]
31955
- ],
31956
- rotationSpeed: [
31957
- [0, 0],
31958
- [0, 0],
31959
- [0, 0]
31960
- ],
31961
- rotationSpeedCurve: null,
31962
- geometryType: GeometryType.NONE,
31963
- geometryArgs: null,
31964
- orientToDirection: false,
31965
- orientAxis: "z",
31966
- stretchBySpeed: null,
31967
- lighting: Lighting.STANDARD,
31968
- shadow: false,
31969
- blending: Blending.NORMAL,
31970
- intensity: 1,
31971
- position: [0, 0, 0],
31972
- autoStart: true,
31973
- delay: 0,
31974
- emitCount: 1,
31975
- emitterShape: EmitterShape.BOX,
31976
- emitterRadius: [0, 1],
31977
- emitterAngle: Math.PI / 4,
31978
- emitterHeight: [0, 1],
31979
- emitterSurfaceOnly: false,
31980
- emitterDirection: [0, 1, 0],
31981
- turbulence: null,
31982
- attractors: null,
31983
- attractToCenter: false,
31984
- startPositionAsDirection: false,
31985
- softParticles: false,
31986
- softDistance: 0.5,
31987
- collision: null
31988
- });
31989
31918
  var createGeometry = (type, args = {}) => {
31990
31919
  if (type === GeometryType.NONE || !type) return null;
31991
31920
  const defaults = geometryDefaults[type] || {};
@@ -32065,40 +31994,139 @@ var createGeometry = (type, args = {}) => {
32065
31994
  return null;
32066
31995
  }
32067
31996
  };
32068
- var debugRoot = null;
32069
- var debugContainer = null;
32070
- var currentValues = null;
32071
- var currentOnChange = null;
32072
- var wrapped = {
32073
- // Core backgrounds
32074
- bg: "rgba(10, 10, 12, 0.92)",
32075
- bgPanel: "rgba(18, 18, 22, 0.85)",
32076
- bgSection: "rgba(25, 25, 30, 0.7)",
32077
- bgInput: "rgba(0, 0, 0, 0.4)",
32078
- // Warm amber/orange accent (the signature wrapped glow)
32079
- accent: "#f97316",
32080
- accentLight: "#fb923c",
32081
- accentGlow: "rgba(249, 115, 22, 0.5)",
32082
- accentSoft: "rgba(249, 115, 22, 0.15)",
32083
- // Borders with soft warm light
32084
- border: "rgba(255, 255, 255, 0.08)",
32085
- borderLit: "rgba(251, 146, 60, 0.3)",
32086
- borderGlow: "rgba(249, 115, 22, 0.2)",
32087
- // Text colors
32088
- text: "rgba(255, 255, 255, 0.95)",
32089
- textMuted: "rgba(255, 255, 255, 0.5)",
32090
- textDim: "rgba(255, 255, 255, 0.3)",
32091
- textAccent: "#fdba74",
32092
- // Soft fading grid background (fades from bottom to top)
32093
- gridBg: `
32094
- linear-gradient(to top, rgba(10, 10, 12, 0) 0%, rgba(10, 10, 12, 0.95) 100%),
32095
- linear-gradient(rgba(249, 115, 22, 0.03) 1px, transparent 1px),
32096
- linear-gradient(90deg, rgba(249, 115, 22, 0.03) 1px, transparent 1px)
32097
- `,
32098
- gridSize: "24px 24px",
32099
- // Shadow with warm undertone
32100
- shadow: "0 30px 60px -15px rgba(0, 0, 0, 0.7), 0 0 1px rgba(251, 146, 60, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.04)"
32101
- };
31997
+ function detectGeometryTypeAndArgs(geo) {
31998
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q;
31999
+ if (!geo) return { geometryType: "none", geometryArgs: null };
32000
+ const name = geo.constructor.name;
32001
+ const params = geo.parameters || {};
32002
+ switch (name) {
32003
+ case "BoxGeometry":
32004
+ return {
32005
+ geometryType: "box",
32006
+ geometryArgs: {
32007
+ width: (_a = params.width) != null ? _a : 1,
32008
+ height: (_b = params.height) != null ? _b : 1,
32009
+ depth: (_c = params.depth) != null ? _c : 1,
32010
+ widthSegments: (_d = params.widthSegments) != null ? _d : 1,
32011
+ heightSegments: (_e = params.heightSegments) != null ? _e : 1,
32012
+ depthSegments: (_f = params.depthSegments) != null ? _f : 1
32013
+ }
32014
+ };
32015
+ case "SphereGeometry":
32016
+ return {
32017
+ geometryType: "sphere",
32018
+ geometryArgs: {
32019
+ radius: (_g = params.radius) != null ? _g : 0.5,
32020
+ widthSegments: (_h = params.widthSegments) != null ? _h : 16,
32021
+ heightSegments: (_i = params.heightSegments) != null ? _i : 12
32022
+ }
32023
+ };
32024
+ case "CylinderGeometry":
32025
+ return {
32026
+ geometryType: "cylinder",
32027
+ geometryArgs: {
32028
+ radiusTop: (_j = params.radiusTop) != null ? _j : 0.5,
32029
+ radiusBottom: (_k = params.radiusBottom) != null ? _k : 0.5,
32030
+ height: (_l = params.height) != null ? _l : 1,
32031
+ radialSegments: (_m = params.radialSegments) != null ? _m : 16,
32032
+ heightSegments: (_n = params.heightSegments) != null ? _n : 1
32033
+ }
32034
+ };
32035
+ case "ConeGeometry":
32036
+ return {
32037
+ geometryType: "cone",
32038
+ geometryArgs: {
32039
+ radius: (_o = params.radius) != null ? _o : 0.5,
32040
+ height: (_p = params.height) != null ? _p : 1,
32041
+ radialSegments: (_q = params.radialSegments) != null ? _q : 16,
32042
+ heightSegments: (_r = params.heightSegments) != null ? _r : 1
32043
+ }
32044
+ };
32045
+ case "TorusGeometry":
32046
+ return {
32047
+ geometryType: "torus",
32048
+ geometryArgs: {
32049
+ radius: (_s = params.radius) != null ? _s : 0.5,
32050
+ tube: (_t = params.tube) != null ? _t : 0.2,
32051
+ radialSegments: (_u = params.radialSegments) != null ? _u : 12,
32052
+ tubularSegments: (_v = params.tubularSegments) != null ? _v : 24
32053
+ }
32054
+ };
32055
+ case "PlaneGeometry":
32056
+ return {
32057
+ geometryType: "plane",
32058
+ geometryArgs: {
32059
+ width: (_w = params.width) != null ? _w : 1,
32060
+ height: (_x = params.height) != null ? _x : 1,
32061
+ widthSegments: (_y = params.widthSegments) != null ? _y : 1,
32062
+ heightSegments: (_z = params.heightSegments) != null ? _z : 1
32063
+ }
32064
+ };
32065
+ case "CircleGeometry":
32066
+ return {
32067
+ geometryType: "circle",
32068
+ geometryArgs: {
32069
+ radius: (_A = params.radius) != null ? _A : 0.5,
32070
+ segments: (_B = params.segments) != null ? _B : 16
32071
+ }
32072
+ };
32073
+ case "RingGeometry":
32074
+ return {
32075
+ geometryType: "ring",
32076
+ geometryArgs: {
32077
+ innerRadius: (_C = params.innerRadius) != null ? _C : 0.25,
32078
+ outerRadius: (_D = params.outerRadius) != null ? _D : 0.5,
32079
+ thetaSegments: (_E = params.thetaSegments) != null ? _E : 16
32080
+ }
32081
+ };
32082
+ case "DodecahedronGeometry":
32083
+ return {
32084
+ geometryType: "dodecahedron",
32085
+ geometryArgs: {
32086
+ radius: (_F = params.radius) != null ? _F : 0.5,
32087
+ detail: (_G = params.detail) != null ? _G : 0
32088
+ }
32089
+ };
32090
+ case "IcosahedronGeometry":
32091
+ return {
32092
+ geometryType: "icosahedron",
32093
+ geometryArgs: {
32094
+ radius: (_H = params.radius) != null ? _H : 0.5,
32095
+ detail: (_I = params.detail) != null ? _I : 0
32096
+ }
32097
+ };
32098
+ case "OctahedronGeometry":
32099
+ return {
32100
+ geometryType: "octahedron",
32101
+ geometryArgs: {
32102
+ radius: (_J = params.radius) != null ? _J : 0.5,
32103
+ detail: (_K = params.detail) != null ? _K : 0
32104
+ }
32105
+ };
32106
+ case "TetrahedronGeometry":
32107
+ return {
32108
+ geometryType: "tetrahedron",
32109
+ geometryArgs: {
32110
+ radius: (_L = params.radius) != null ? _L : 0.5,
32111
+ detail: (_M = params.detail) != null ? _M : 0
32112
+ }
32113
+ };
32114
+ case "CapsuleGeometry":
32115
+ return {
32116
+ geometryType: "capsule",
32117
+ geometryArgs: {
32118
+ radius: (_N = params.radius) != null ? _N : 0.25,
32119
+ length: (_O = params.length) != null ? _O : 0.5,
32120
+ capSegments: (_P = params.capSegments) != null ? _P : 4,
32121
+ radialSegments: (_Q = params.radialSegments) != null ? _Q : 8
32122
+ }
32123
+ };
32124
+ default:
32125
+ return { geometryType: "none", geometryArgs: null };
32126
+ }
32127
+ }
32128
+
32129
+ // src/code-generation.ts
32102
32130
  var formatJSXValue = (key, value) => {
32103
32131
  if (value === void 0 || value === null) return null;
32104
32132
  if (typeof value === "boolean") {
@@ -32199,7 +32227,8 @@ var arraysEqual = (a, b) => {
32199
32227
  if (!Array.isArray(a) || !Array.isArray(b)) return false;
32200
32228
  if (a.length !== b.length) return false;
32201
32229
  return a.every((v, i) => {
32202
- if (Array.isArray(v) && Array.isArray(b[i])) return arraysEqual(v, b[i]);
32230
+ if (Array.isArray(v) && Array.isArray(b[i]))
32231
+ return arraysEqual(v, b[i]);
32203
32232
  return v === b[i];
32204
32233
  });
32205
32234
  };
@@ -32215,54 +32244,113 @@ var isDefaultTurbulence = (t) => {
32215
32244
  if (!t) return true;
32216
32245
  return t.intensity === 0 || t.intensity === void 0;
32217
32246
  };
32247
+ var propOrder = [
32248
+ "name",
32249
+ "curveTexturePath",
32250
+ "maxParticles",
32251
+ "position",
32252
+ "autoStart",
32253
+ "emitCount",
32254
+ "delay",
32255
+ "intensity",
32256
+ "size",
32257
+ "fadeSize",
32258
+ "fadeSizeCurve",
32259
+ "colorStart",
32260
+ "colorEnd",
32261
+ "fadeOpacity",
32262
+ "fadeOpacityCurve",
32263
+ "gravity",
32264
+ "speed",
32265
+ "lifetime",
32266
+ "friction",
32267
+ "velocityCurve",
32268
+ "direction",
32269
+ "startPosition",
32270
+ "startPositionAsDirection",
32271
+ "rotation",
32272
+ "rotationSpeed",
32273
+ "rotationSpeedCurve",
32274
+ "orientToDirection",
32275
+ "orientAxis",
32276
+ "stretchBySpeed",
32277
+ "appearance",
32278
+ "blending",
32279
+ "lighting",
32280
+ "shadow",
32281
+ "emitterShape",
32282
+ "emitterRadius",
32283
+ "emitterAngle",
32284
+ "emitterHeight",
32285
+ "emitterDirection",
32286
+ "emitterSurfaceOnly",
32287
+ "turbulence",
32288
+ "collision",
32289
+ "softParticles",
32290
+ "softDistance",
32291
+ "attractToCenter"
32292
+ ];
32293
+ var shouldSkipDefault = (key, value, values) => {
32294
+ if (value === void 0 || value === null) return true;
32295
+ if (key === "name" && !value) return true;
32296
+ if (key === "curveTexturePath" && !value) return true;
32297
+ if (key === "maxParticles" && value === 1e4) return true;
32298
+ if (key === "position" && arraysEqual(value, [0, 0, 0])) return true;
32299
+ if (key === "autoStart" && value === true) return true;
32300
+ if (key === "emitCount" && value === 1) return true;
32301
+ if (key === "delay" && value === 0) return true;
32302
+ if (key === "intensity" && value === 1) return true;
32303
+ if (key === "size" && arraysEqual(value, [0.1, 0.3])) return true;
32304
+ if (key === "speed" && arraysEqual(value, [0.1, 0.1])) return true;
32305
+ if (key === "lifetime" && arraysEqual(value, [1, 2])) return true;
32306
+ if (key === "fadeSize" && arraysEqual(value, [1, 0])) return true;
32307
+ if (key === "fadeOpacity" && arraysEqual(value, [1, 0])) return true;
32308
+ if (key === "colorStart" && arraysEqual(value, ["#ffffff"])) return true;
32309
+ if (key === "gravity" && arraysEqual(value, [0, 0, 0])) return true;
32310
+ if (key === "friction" && isDefaultFriction(value)) return true;
32311
+ if (key === "friction" && values.velocityCurve) return true;
32312
+ if (key === "direction" && arraysEqual(value, [
32313
+ [-1, 1],
32314
+ [0, 1],
32315
+ [-1, 1]
32316
+ ]))
32317
+ return true;
32318
+ if (key === "direction" && values.startPositionAsDirection) return true;
32319
+ if (key === "startPosition" && arraysEqual(value, [
32320
+ [0, 0],
32321
+ [0, 0],
32322
+ [0, 0]
32323
+ ]))
32324
+ return true;
32325
+ if (key === "startPositionAsDirection" && value === false) return true;
32326
+ if (key === "rotation" && arraysEqual(value, [0, 0])) return true;
32327
+ if (key === "rotationSpeed" && arraysEqual(value, [0, 0])) return true;
32328
+ if (key === "appearance" && value === 0) return true;
32329
+ if (key === "blending" && value === 1) return true;
32330
+ if (key === "lighting" && value === 1) return true;
32331
+ if (key === "shadow" && value === false) return true;
32332
+ if (key === "orientToDirection" && value === false) return true;
32333
+ if (key === "orientAxis") {
32334
+ const axisNeeded = values.orientToDirection || values.stretchBySpeed;
32335
+ if (!axisNeeded || value === "z" || value === "+z") return true;
32336
+ }
32337
+ if (key === "stretchBySpeed" && !value) return true;
32338
+ if (key === "emitterShape" && value === 0) return true;
32339
+ if (key === "emitterRadius" && arraysEqual(value, [0, 1])) return true;
32340
+ if (key === "emitterAngle" && Math.abs(value - Math.PI / 4) < 1e-3)
32341
+ return true;
32342
+ if (key === "emitterHeight" && arraysEqual(value, [0, 1])) return true;
32343
+ if (key === "emitterDirection" && arraysEqual(value, [0, 1, 0])) return true;
32344
+ if (key === "emitterSurfaceOnly" && value === false) return true;
32345
+ if (key === "turbulence" && isDefaultTurbulence(value)) return true;
32346
+ if (key === "collision" && !value) return true;
32347
+ if (key === "softParticles" && value === false) return true;
32348
+ if (key === "softDistance" && !values.softParticles) return true;
32349
+ if (key === "attractToCenter" && value === false) return true;
32350
+ return false;
32351
+ };
32218
32352
  var generateVFXParticlesJSX = (values) => {
32219
32353
  const props = [];
32220
- const propOrder = [
32221
- "name",
32222
- "curveTexturePath",
32223
- "maxParticles",
32224
- "position",
32225
- "autoStart",
32226
- "emitCount",
32227
- "delay",
32228
- "intensity",
32229
- "size",
32230
- "fadeSize",
32231
- "fadeSizeCurve",
32232
- "colorStart",
32233
- "colorEnd",
32234
- "fadeOpacity",
32235
- "fadeOpacityCurve",
32236
- "gravity",
32237
- "speed",
32238
- "lifetime",
32239
- "friction",
32240
- "velocityCurve",
32241
- "direction",
32242
- "startPosition",
32243
- "startPositionAsDirection",
32244
- "rotation",
32245
- "rotationSpeed",
32246
- "rotationSpeedCurve",
32247
- "orientToDirection",
32248
- "orientAxis",
32249
- "stretchBySpeed",
32250
- "appearance",
32251
- "blending",
32252
- "lighting",
32253
- "shadow",
32254
- "emitterShape",
32255
- "emitterRadius",
32256
- "emitterAngle",
32257
- "emitterHeight",
32258
- "emitterDirection",
32259
- "emitterSurfaceOnly",
32260
- "turbulence",
32261
- "collision",
32262
- "softParticles",
32263
- "softDistance",
32264
- "attractToCenter"
32265
- ];
32266
32354
  if (values.geometryType && values.geometryType !== GeometryType.NONE) {
32267
32355
  const geoJsx = geometryTypeToJSX(values.geometryType, values.geometryArgs);
32268
32356
  if (geoJsx) {
@@ -32271,62 +32359,7 @@ var generateVFXParticlesJSX = (values) => {
32271
32359
  }
32272
32360
  for (const key of propOrder) {
32273
32361
  const value = values[key];
32274
- if (value === void 0 || value === null) continue;
32275
- if (key === "name" && !value) continue;
32276
- if (key === "curveTexturePath" && !value) continue;
32277
- if (key === "maxParticles" && value === 1e4) continue;
32278
- if (key === "position" && arraysEqual(value, [0, 0, 0])) continue;
32279
- if (key === "autoStart" && value === true) continue;
32280
- if (key === "emitCount" && value === 1) continue;
32281
- if (key === "delay" && value === 0) continue;
32282
- if (key === "intensity" && value === 1) continue;
32283
- if (key === "size" && arraysEqual(value, [0.1, 0.3])) continue;
32284
- if (key === "speed" && arraysEqual(value, [0.1, 0.1])) continue;
32285
- if (key === "lifetime" && arraysEqual(value, [1, 2])) continue;
32286
- if (key === "fadeSize" && arraysEqual(value, [1, 0])) continue;
32287
- if (key === "fadeOpacity" && arraysEqual(value, [1, 0])) continue;
32288
- if (key === "colorStart" && arraysEqual(value, ["#ffffff"])) continue;
32289
- if (key === "gravity" && arraysEqual(value, [0, 0, 0])) continue;
32290
- if (key === "friction" && isDefaultFriction(value)) continue;
32291
- if (key === "friction" && values.velocityCurve) continue;
32292
- if (key === "direction" && arraysEqual(value, [
32293
- [-1, 1],
32294
- [0, 1],
32295
- [-1, 1]
32296
- ]))
32297
- continue;
32298
- if (key === "direction" && values.startPositionAsDirection) continue;
32299
- if (key === "startPosition" && arraysEqual(value, [
32300
- [0, 0],
32301
- [0, 0],
32302
- [0, 0]
32303
- ]))
32304
- continue;
32305
- if (key === "startPositionAsDirection" && value === false) continue;
32306
- if (key === "rotation" && arraysEqual(value, [0, 0])) continue;
32307
- if (key === "rotationSpeed" && arraysEqual(value, [0, 0])) continue;
32308
- if (key === "appearance" && value === 0) continue;
32309
- if (key === "blending" && value === 1) continue;
32310
- if (key === "lighting" && value === 1) continue;
32311
- if (key === "shadow" && value === false) continue;
32312
- if (key === "orientToDirection" && value === false) continue;
32313
- if (key === "orientAxis") {
32314
- const axisNeeded = values.orientToDirection || values.stretchBySpeed;
32315
- if (!axisNeeded || value === "z" || value === "+z") continue;
32316
- }
32317
- if (key === "stretchBySpeed" && !value) continue;
32318
- if (key === "emitterShape" && value === 0) continue;
32319
- if (key === "emitterRadius" && arraysEqual(value, [0, 1])) continue;
32320
- if (key === "emitterAngle" && Math.abs(value - Math.PI / 4) < 1e-3)
32321
- continue;
32322
- if (key === "emitterHeight" && arraysEqual(value, [0, 1])) continue;
32323
- if (key === "emitterDirection" && arraysEqual(value, [0, 1, 0])) continue;
32324
- if (key === "emitterSurfaceOnly" && value === false) continue;
32325
- if (key === "turbulence" && isDefaultTurbulence(value)) continue;
32326
- if (key === "collision" && !value) continue;
32327
- if (key === "softParticles" && value === false) continue;
32328
- if (key === "softDistance" && !values.softParticles) continue;
32329
- if (key === "attractToCenter" && value === false) continue;
32362
+ if (shouldSkipDefault(key, value, values)) continue;
32330
32363
  const formatted = formatJSXValue(key, value);
32331
32364
  if (formatted) props.push(formatted);
32332
32365
  }
@@ -32337,6 +32370,114 @@ var generateVFXParticlesJSX = (values) => {
32337
32370
  ${props.join("\n ")}
32338
32371
  />`;
32339
32372
  };
32373
+ var formatObjectProp = (key, value) => {
32374
+ if (value === void 0 || value === null) return null;
32375
+ if (typeof value === "boolean") {
32376
+ return ` ${key}: ${value},`;
32377
+ }
32378
+ if (typeof value === "number") {
32379
+ return ` ${key}: ${value},`;
32380
+ }
32381
+ if (typeof value === "string") {
32382
+ return ` ${key}: "${value}",`;
32383
+ }
32384
+ if (Array.isArray(value)) {
32385
+ if (value.length > 0 && typeof value[0] === "string" && value[0].startsWith("#")) {
32386
+ return ` ${key}: [${value.map((v) => `"${v}"`).join(", ")}],`;
32387
+ }
32388
+ if (value.length > 0 && Array.isArray(value[0])) {
32389
+ return ` ${key}: [${value.map((v) => `[${v.join(", ")}]`).join(", ")}],`;
32390
+ }
32391
+ return ` ${key}: [${value.join(", ")}],`;
32392
+ }
32393
+ if (typeof value === "object") {
32394
+ const formatValue = (v, indent) => {
32395
+ if (v === void 0 || v === null) return "null";
32396
+ if (typeof v === "string") return `"${v}"`;
32397
+ if (typeof v === "number" || typeof v === "boolean") return String(v);
32398
+ if (Array.isArray(v)) {
32399
+ if (v.length > 0 && typeof v[0] === "object" && !Array.isArray(v[0])) {
32400
+ const items = v.map((item) => formatValue(item, indent + 2));
32401
+ return `[
32402
+ ${items.map((i) => " ".repeat(indent + 2) + i).join(",\n")}
32403
+ ${" ".repeat(indent)}]`;
32404
+ }
32405
+ return `[${v.map((item) => formatValue(item, indent)).join(", ")}]`;
32406
+ }
32407
+ if (typeof v === "object") {
32408
+ return formatObj(v, indent + 2);
32409
+ }
32410
+ return String(v);
32411
+ };
32412
+ const formatObj = (obj, indent = 4) => {
32413
+ const entries = Object.entries(obj).filter(
32414
+ ([, v]) => v !== void 0 && v !== null
32415
+ );
32416
+ if (entries.length === 0) return "{}";
32417
+ const lines = entries.map(([k, v]) => {
32418
+ return `${" ".repeat(indent)}${k}: ${formatValue(v, indent)}`;
32419
+ });
32420
+ return `{
32421
+ ${lines.join(",\n")}
32422
+ ${" ".repeat(indent - 2)}}`;
32423
+ };
32424
+ return ` ${key}: ${formatObj(value, 4)},`;
32425
+ }
32426
+ return null;
32427
+ };
32428
+ var generateVanillaCode = (values) => {
32429
+ const props = [];
32430
+ if (values.geometryType && values.geometryType !== GeometryType.NONE) {
32431
+ const geoCode = geometryTypeToJSX(values.geometryType, values.geometryArgs);
32432
+ if (geoCode) {
32433
+ props.push(` geometry: ${geoCode},`);
32434
+ }
32435
+ }
32436
+ for (const key of propOrder) {
32437
+ const value = values[key];
32438
+ if (shouldSkipDefault(key, value, values)) continue;
32439
+ const formatted = formatObjectProp(key, value);
32440
+ if (formatted) props.push(formatted);
32441
+ }
32442
+ if (props.length === 0) {
32443
+ return "const particles = new VFXParticles(renderer)";
32444
+ }
32445
+ return `const particles = new VFXParticles(renderer, {
32446
+ ${props.join("\n")}
32447
+ })`;
32448
+ };
32449
+
32450
+ // src/styles.ts
32451
+ var wrapped = {
32452
+ // Core backgrounds
32453
+ bg: "rgba(10, 10, 12, 0.92)",
32454
+ bgPanel: "rgba(18, 18, 22, 0.85)",
32455
+ bgSection: "rgba(25, 25, 30, 0.7)",
32456
+ bgInput: "rgba(0, 0, 0, 0.4)",
32457
+ // Warm amber/orange accent (the signature wrapped glow)
32458
+ accent: "#f97316",
32459
+ accentLight: "#fb923c",
32460
+ accentGlow: "rgba(249, 115, 22, 0.5)",
32461
+ accentSoft: "rgba(249, 115, 22, 0.15)",
32462
+ // Borders with soft warm light
32463
+ border: "rgba(255, 255, 255, 0.08)",
32464
+ borderLit: "rgba(251, 146, 60, 0.3)",
32465
+ borderGlow: "rgba(249, 115, 22, 0.2)",
32466
+ // Text colors
32467
+ text: "rgba(255, 255, 255, 0.95)",
32468
+ textMuted: "rgba(255, 255, 255, 0.5)",
32469
+ textDim: "rgba(255, 255, 255, 0.3)",
32470
+ textAccent: "#fdba74",
32471
+ // Soft fading grid background (fades from bottom to top)
32472
+ gridBg: `
32473
+ linear-gradient(to top, rgba(10, 10, 12, 0) 0%, rgba(10, 10, 12, 0.95) 100%),
32474
+ linear-gradient(rgba(249, 115, 22, 0.03) 1px, transparent 1px),
32475
+ linear-gradient(90deg, rgba(249, 115, 22, 0.03) 1px, transparent 1px)
32476
+ `,
32477
+ gridSize: "24px 24px",
32478
+ // Shadow with warm undertone
32479
+ shadow: "0 30px 60px -15px rgba(0, 0, 0, 0.7), 0 0 1px rgba(251, 146, 60, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.04)"
32480
+ };
32340
32481
  var styles = {
32341
32482
  container: {
32342
32483
  position: "fixed",
@@ -32609,9 +32750,7 @@ var styles = {
32609
32750
  letterSpacing: "0.05em",
32610
32751
  textTransform: "lowercase"
32611
32752
  },
32612
- optionalSection: {
32613
- // Same as regular sections - no special styling
32614
- },
32753
+ optionalSection: {},
32615
32754
  enableCheckbox: {
32616
32755
  marginBottom: "8px",
32617
32756
  paddingBottom: "8px",
@@ -32693,6 +32832,83 @@ var styles = {
32693
32832
  color: wrapped.accent
32694
32833
  }
32695
32834
  };
32835
+
32836
+ // src/VFXParticlesDebugPanel.jsx
32837
+ var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
32838
+ var useDebugPanelStore = create(() => ({
32839
+ flushChangesRef: { current: null }
32840
+ }));
32841
+ var getFlushChanges = () => useDebugPanelStore.getState().flushChangesRef.current;
32842
+ var setFlushChanges = (fn) => {
32843
+ useDebugPanelStore.getState().flushChangesRef.current = fn;
32844
+ };
32845
+ var DEFAULT_VALUES = Object.freeze({
32846
+ maxParticles: 1e4,
32847
+ size: [0.1, 0.3],
32848
+ colorStart: ["#ffffff"],
32849
+ colorEnd: null,
32850
+ fadeSize: [1, 0],
32851
+ fadeSizeCurve: null,
32852
+ fadeOpacity: [1, 0],
32853
+ fadeOpacityCurve: null,
32854
+ velocityCurve: null,
32855
+ gravity: [0, 0, 0],
32856
+ lifetime: [1, 2],
32857
+ direction: [
32858
+ [-1, 1],
32859
+ [0, 1],
32860
+ [-1, 1]
32861
+ ],
32862
+ startPosition: [
32863
+ [0, 0],
32864
+ [0, 0],
32865
+ [0, 0]
32866
+ ],
32867
+ speed: [0.1, 0.1],
32868
+ friction: { intensity: 0, easing: "linear" },
32869
+ appearance: Appearance.GRADIENT,
32870
+ rotation: [
32871
+ [0, 0],
32872
+ [0, 0],
32873
+ [0, 0]
32874
+ ],
32875
+ rotationSpeed: [
32876
+ [0, 0],
32877
+ [0, 0],
32878
+ [0, 0]
32879
+ ],
32880
+ rotationSpeedCurve: null,
32881
+ geometryType: GeometryType.NONE,
32882
+ geometryArgs: null,
32883
+ orientToDirection: false,
32884
+ orientAxis: "z",
32885
+ stretchBySpeed: null,
32886
+ lighting: Lighting.STANDARD,
32887
+ shadow: false,
32888
+ blending: Blending.NORMAL,
32889
+ intensity: 1,
32890
+ position: [0, 0, 0],
32891
+ autoStart: true,
32892
+ delay: 0,
32893
+ emitCount: 1,
32894
+ emitterShape: EmitterShape.BOX,
32895
+ emitterRadius: [0, 1],
32896
+ emitterAngle: Math.PI / 4,
32897
+ emitterHeight: [0, 1],
32898
+ emitterSurfaceOnly: false,
32899
+ emitterDirection: [0, 1, 0],
32900
+ turbulence: null,
32901
+ attractors: null,
32902
+ attractToCenter: false,
32903
+ startPositionAsDirection: false,
32904
+ softParticles: false,
32905
+ softDistance: 0.5,
32906
+ collision: null
32907
+ });
32908
+ var debugRoot = null;
32909
+ var debugContainer = null;
32910
+ var currentValues = null;
32911
+ var currentOnChange = null;
32696
32912
  var parseRange = (value, defaultVal = [0, 0]) => {
32697
32913
  if (value === void 0 || value === null) return defaultVal;
32698
32914
  if (Array.isArray(value))
@@ -35057,7 +35273,7 @@ var LoadingSpinner = () => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
35057
35273
  ]
35058
35274
  }
35059
35275
  );
35060
- var DebugPanelContent = ({ initialValues, onUpdate }) => {
35276
+ var DebugPanelContent = ({ initialValues, onUpdate, mode = "r3f" }) => {
35061
35277
  "use no memo";
35062
35278
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X;
35063
35279
  const [isMinimized, setIsMinimized] = (0, import_react2.useState)(false);
@@ -35123,19 +35339,19 @@ var DebugPanelContent = ({ initialValues, onUpdate }) => {
35123
35339
  }
35124
35340
  };
35125
35341
  }, []);
35126
- const handleCopyJSX = (0, import_react2.useCallback)(async () => {
35342
+ const handleCopyCode = (0, import_react2.useCallback)(async () => {
35127
35343
  if (hasPendingChanges) {
35128
35344
  flushChanges();
35129
35345
  }
35130
- const jsx2 = generateVFXParticlesJSX(valuesRef.current);
35346
+ const code = mode === "vanilla" ? generateVanillaCode(valuesRef.current) : generateVFXParticlesJSX(valuesRef.current);
35131
35347
  try {
35132
- await navigator.clipboard.writeText(jsx2);
35348
+ await navigator.clipboard.writeText(code);
35133
35349
  setCopySuccess(true);
35134
35350
  setTimeout(() => setCopySuccess(false), 2e3);
35135
35351
  } catch (err) {
35136
35352
  console.error("Failed to copy:", err);
35137
35353
  }
35138
- }, [hasPendingChanges, flushChanges]);
35354
+ }, [hasPendingChanges, flushChanges, mode]);
35139
35355
  const handleBakeCurves = (0, import_react2.useCallback)(async () => {
35140
35356
  if (hasPendingChanges) {
35141
35357
  flushChanges();
@@ -35523,7 +35739,7 @@ var DebugPanelContent = ({ initialValues, onUpdate }) => {
35523
35739
  "button",
35524
35740
  {
35525
35741
  style: __spreadValues(__spreadValues({}, styles.copyBtn), copySuccess ? styles.copyBtnSuccess : {}),
35526
- onClick: handleCopyJSX,
35742
+ onClick: handleCopyCode,
35527
35743
  onMouseEnter: (e) => {
35528
35744
  if (!copySuccess) {
35529
35745
  Object.assign(e.currentTarget.style, {
@@ -35546,7 +35762,7 @@ var DebugPanelContent = ({ initialValues, onUpdate }) => {
35546
35762
  });
35547
35763
  }
35548
35764
  },
35549
- children: copySuccess ? "\u2713 copied" : "copy jsx"
35765
+ children: copySuccess ? "\u2713 copied" : "copy code"
35550
35766
  }
35551
35767
  ),
35552
35768
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -36844,7 +37060,7 @@ var DebugPanelContent = ({ initialValues, onUpdate }) => {
36844
37060
  ] })
36845
37061
  ] });
36846
37062
  };
36847
- function renderDebugPanel(values, onChange) {
37063
+ function renderDebugPanel(values, onChange, mode = "r3f") {
36848
37064
  currentValues = values;
36849
37065
  currentOnChange = onChange;
36850
37066
  if (!debugContainer) {
@@ -36980,15 +37196,22 @@ function renderDebugPanel(values, onChange) {
36980
37196
  debugRoot = (0, import_client.createRoot)(debugContainer);
36981
37197
  }
36982
37198
  debugRoot.render(
36983
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DebugPanelContent, { initialValues: values, onUpdate: onChange })
37199
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DebugPanelContent, { initialValues: values, onUpdate: onChange, mode })
36984
37200
  );
36985
37201
  }
36986
- function updateDebugPanel(values, onChange) {
37202
+ function updateDebugPanel(values, onChange, mode = "r3f") {
36987
37203
  currentValues = values;
36988
37204
  currentOnChange = onChange;
36989
37205
  if (debugRoot) {
36990
37206
  debugRoot.render(
36991
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DebugPanelContent, { initialValues: values, onUpdate: onChange })
37207
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
37208
+ DebugPanelContent,
37209
+ {
37210
+ initialValues: values,
37211
+ onUpdate: onChange,
37212
+ mode
37213
+ }
37214
+ )
36992
37215
  );
36993
37216
  }
36994
37217
  }
@@ -37013,6 +37236,7 @@ export {
37013
37236
  GeometryType,
37014
37237
  createGeometry,
37015
37238
  destroyDebugPanel,
37239
+ detectGeometryTypeAndArgs,
37016
37240
  renderDebugPanel,
37017
37241
  updateDebugPanel
37018
37242
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "debug-vfx",
3
- "version": "0.0.10",
3
+ "version": "0.1.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
@@ -22,7 +22,7 @@
22
22
  "typecheck": "tsc"
23
23
  },
24
24
  "dependencies": {
25
- "core-vfx": "0.0.10"
25
+ "core-vfx": "0.1.0"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/react": "19.2.10",