visualifyjs 2.5.3 → 3.0.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 (252) hide show
  1. package/.claude/mem/TIMELINE.md +36 -0
  2. package/.claude/mem/notes/2026-02-11-3d-visualization-docs-fix-external-script-solution.md +24 -0
  3. package/.claude/mem/notes/2026-02-11-3d-visualization-docs-fix-session-summary.md +43 -0
  4. package/.claude/mem/notes/2026-02-11-cli-fix-editor-command-alias.md +26 -0
  5. package/.claude/mem/notes/2026-02-11-phase-3-developer-experience-completed.md +51 -0
  6. package/.claude/mem/notes/2026-02-11-phase-4-web-workers-implementation-complete.md +59 -0
  7. package/.claude/mem/notes/2026-02-11-visualify-phase-2-3d-visualization-complete.md +50 -0
  8. package/.claude/mem/notes/2026-02-11-visualify-phase-2-committed-ready-for-phase-3.md +33 -0
  9. package/.claude/mem/notes/2026-02-11-visualify-phase-3-complete-developer-experience.md +52 -0
  10. package/.claude/mem/notes/2026-02-11-visualify-repository-cleanup-complete.md +28 -0
  11. package/.claude/mem/notes/2026-02-18-codebase-cleanup-docsify-plugin-documentation.md +37 -0
  12. package/.claude/mem/notes/2026-02-19-css-grid-layout-fix-displaycontents-on-vcontroller.md +18 -0
  13. package/.claude/mem/notes/2026-02-19-docsify-plugin-fixes-latex-and-visualify-code-bloc.md +26 -0
  14. package/.claude/mem/notes/2026-02-19-page-mode-docs-update-decisions.md +23 -0
  15. package/.claude/mem/notes/2026-02-19-react-context-infinite-re-render-loop-fix-pattern.md +31 -0
  16. package/.claude/mem/notes/2026-02-19-version-300-bump-and-build-fixes.md +32 -0
  17. package/.claude/mem/notes/2026-02-19-visualify-build-deployment-architecture-bug-fixes.md +25 -0
  18. package/.claude/mem/notes/2026-02-19-visualify-dist-iife-self-contained-build-config.md +30 -0
  19. package/.claude/mem/notes/2026-02-19-visualify-infinite-loop-i18n-fixes.md +31 -0
  20. package/.claude/mem/notes/2026-02-19-visualify-v3-bundle-splitting-docs-restructuring.md +32 -0
  21. package/.claude/mem/notes/2026-02-20-bundle-externalization-final-architecture.md +29 -0
  22. package/.claude/mem/notes/2026-02-20-chromium-page-fix-unstable-keys-and-double-event-b.md +27 -0
  23. package/.claude/mem/notes/2026-02-20-console-cleanup-bundle-optimization-commit.md +20 -0
  24. package/.claude/mem/notes/2026-02-20-dotbio-dot-plot-fix-useeffect-dependency.md +21 -0
  25. package/.claude/mem/notes/2026-02-20-public-folder-cleanup-and-readme-rewrite.md +25 -0
  26. package/.claude/mem/notes/2026-02-20-v300-release-and-beta-channel-strategy.md +29 -0
  27. package/.claude/mem/notes/2026-02-20-visium-background-image-unknown-legend-fix.md +19 -0
  28. package/.claude/mem/notes/2026-02-20-visualify-cdn-loader-bundle-externalization.md +34 -0
  29. package/.claude/mem/sessions/session-2026-02-20-031524.md +54 -0
  30. package/.claude/settings.local.json +21 -0
  31. package/.github/workflows/static.yml.bak +51 -51
  32. package/.sisyphus/boulder.json +65 -0
  33. package/.sisyphus/plans/phase-4-advanced-optimizations.md +217 -0
  34. package/LICENSE +674 -674
  35. package/README.md +94 -59
  36. package/config-overrides.js +31 -31
  37. package/dist/stats.html +4949 -0
  38. package/dist/visualify-3d.esm.js +1 -0
  39. package/dist/visualify-3d.js +1 -0
  40. package/dist/visualify-core.esm.js +1 -0
  41. package/dist/visualify-core.js +1 -0
  42. package/dist/visualify-docs.esm.js +1 -0
  43. package/dist/visualify-docs.js +1 -0
  44. package/dist/visualify-loader.js +1 -0
  45. package/dist/visualify-pages.esm.js +1 -0
  46. package/dist/visualify-pages.js +1 -0
  47. package/dist/visualify-portal.esm.js +1 -0
  48. package/dist/visualify-portal.js +1 -0
  49. package/dist/visualify-shared.js +26571 -0
  50. package/dist/visualify.js +1 -188
  51. package/docs/CHANGELOG.md +148 -0
  52. package/docs/cli/commands.md +513 -0
  53. package/docs/configuration/visualify-json.md +474 -0
  54. package/docs/docs/3d-visualization.md +374 -0
  55. package/docs/docs/CLI.md +303 -34
  56. package/docs/docs/README.md +65 -65
  57. package/docs/docs/Rechart/bar.md +190 -190
  58. package/docs/docs/Rechart/funnel.md +241 -193
  59. package/docs/docs/Rechart/line.md +355 -355
  60. package/docs/docs/Rechart/pie.md +225 -225
  61. package/docs/docs/Rechart/radar.md +253 -253
  62. package/docs/docs/Rechart/scatter.md +298 -0
  63. package/docs/docs/_404.md +51 -51
  64. package/docs/docs/_coverpage.md +11 -11
  65. package/docs/docs/_sidebar.md +54 -43
  66. package/docs/docs/components/dotBio.md +87 -34
  67. package/docs/docs/components/echart.md +171 -82
  68. package/docs/docs/components/html.md +61 -34
  69. package/docs/docs/components/macaron.md +156 -145
  70. package/docs/docs/components/markdown.md +42 -0
  71. package/docs/docs/components/more.md +183 -142
  72. package/docs/docs/components/plotly.md +132 -62
  73. package/docs/docs/components/scatterL.md +171 -70
  74. package/docs/docs/components/visium.md +112 -57
  75. package/docs/docs/configuration.md +121 -123
  76. package/docs/docs/deploy.md +31 -31
  77. package/docs/docs/docsify-plugin.md +655 -0
  78. package/docs/docs/hmr.md +165 -0
  79. package/docs/docs/i18n.md +332 -0
  80. package/docs/docs/log.md +30 -1
  81. package/docs/docs/more-pages.md +23 -23
  82. package/docs/docs/quickstart.md +148 -119
  83. package/docs/docs/rechart-attributes.md +74 -74
  84. package/docs/docs/rechart-basic-usage.md +160 -162
  85. package/docs/docs/theme.md +5 -5
  86. package/docs/docs/typescript.md +306 -0
  87. package/docs/docs/visual-editor.md +359 -0
  88. package/docs/index.html +85 -71
  89. package/docs/manifest.json +23 -23
  90. package/docs/migration/v3-migration.md +392 -0
  91. package/docs/static/css/fluff-stuff.css +169 -169
  92. package/docs/static/css/font-awesome.min.css +4 -4
  93. package/docs/static/css/visualify.css +6 -25
  94. package/docs/static/js/3d-viz-examples.js +181 -0
  95. package/docs/static/js/configuration.js +630 -448
  96. package/docs/static/js/visualify.js +1 -188
  97. package/package.json +106 -84
  98. package/rollup.config.mjs +766 -76
  99. package/src/_css/404.css +115 -115
  100. package/src/_css/App.css +37 -37
  101. package/src/_css/autoSuggestion.css +26 -26
  102. package/src/_css/circular-progress.css +32 -32
  103. package/src/_css/index.css +36 -36
  104. package/src/_css/modern.css +350 -25
  105. package/src/_media/corner.svg +8 -8
  106. package/src/_media/download.svg +3 -3
  107. package/src/_media/logo.svg +14 -14
  108. package/src/_test/App.test.js +15 -15
  109. package/src/_utils/reportWebVitals.js +13 -13
  110. package/src/a11y/README.md +177 -0
  111. package/src/a11y/aria-labels.js +339 -0
  112. package/src/a11y/color-contrast.js +535 -0
  113. package/src/a11y/index.js +197 -0
  114. package/src/a11y/keyboard-nav.js +523 -0
  115. package/src/a11y/styles.css +165 -0
  116. package/src/cli/commands/dev.js +214 -0
  117. package/src/cli/commands/docs.js +521 -0
  118. package/src/cli/commands/edit.js +379 -0
  119. package/src/cli/commands/init.js +213 -0
  120. package/src/cli/commands/portal.js +236 -0
  121. package/src/cli/dev-server.js +530 -0
  122. package/src/cli/hmr.js +456 -0
  123. package/src/cli/index.js +180 -0
  124. package/src/cli/utils/config.js +207 -0
  125. package/src/cli/utils/logger.js +241 -0
  126. package/src/config/defaults.ts +122 -0
  127. package/src/config/index.ts +72 -0
  128. package/src/config/loader.ts +478 -0
  129. package/src/config/schema.ts +227 -0
  130. package/src/config/validator.ts +337 -0
  131. package/src/core/appContext.js +34 -27
  132. package/src/core/components/Bar.js +383 -0
  133. package/src/core/components/Bar3D.js +473 -0
  134. package/src/core/components/LargeDatasetChart.js +296 -0
  135. package/src/core/components/Line3D.js +310 -0
  136. package/src/core/components/Scatter.js +392 -188
  137. package/src/core/components/Scatter3D.js +455 -0
  138. package/src/core/components/ScatterBio.js +601 -572
  139. package/src/core/components/Surface3D.js +326 -0
  140. package/src/core/components/ThreeCustom.js +648 -0
  141. package/src/core/components/ThreeScene.js +459 -0
  142. package/src/core/components/VisiumPlot.js +191 -165
  143. package/src/core/components/browser.js +42 -42
  144. package/src/core/components/dotplot.js +413 -413
  145. package/src/core/components/html.js +29 -29
  146. package/src/core/components/list.js +178 -178
  147. package/src/core/components/macaron.js +206 -201
  148. package/src/core/components/markdown.js +56 -56
  149. package/src/core/components/parser.scatterBio.js +582 -579
  150. package/src/core/components/ratio.js +82 -80
  151. package/src/core/components/scatterL.js +206 -173
  152. package/src/core/components/searchbar.js +156 -131
  153. package/src/core/components/selection.js +310 -193
  154. package/src/core/components/timeline.js +236 -281
  155. package/src/core/components/visium.js +114 -97
  156. package/src/core/data-processor.js +413 -0
  157. package/src/core/fetch/condfetch.js +82 -82
  158. package/src/core/fetch/fetch.js +92 -92
  159. package/src/core/fetch/json.js +29 -29
  160. package/src/core/fetch/vfetch.js +42 -42
  161. package/src/core/hmr-client.js +724 -0
  162. package/src/core/liveEditor.js +44 -44
  163. package/src/core/modules/codeEditorWithPreview.js +104 -104
  164. package/src/core/modules/echarts/common.js +20 -20
  165. package/src/core/modules/echarts/gl.js +228 -0
  166. package/src/core/modules/echarts/presetHandler.js +41 -41
  167. package/src/core/modules/echarts/presets/esodev.chromium.js +172 -172
  168. package/src/core/modules/echarts/presets/esodev.codex.js +130 -130
  169. package/src/core/modules/echarts/presets/esodev.visium.js +123 -123
  170. package/src/core/modules/echarts/presets/mmtrbc.js +186 -186
  171. package/src/core/modules/echarts.js +70 -71
  172. package/src/core/modules/echartsUtils.js +43 -43
  173. package/src/core/modules/echartswitcher.js +227 -152
  174. package/src/core/modules/replotly/presetHandler.js +24 -24
  175. package/src/core/modules/replotly/presets/minimum.js +18 -18
  176. package/src/core/modules/replotly/presets/mmtrbc.dot.js +114 -114
  177. package/src/core/modules/replotly/presets/mmtrbc.violin.js +100 -100
  178. package/src/core/modules/replotly.js +74 -71
  179. package/src/core/modules/threejs/Camera.js +373 -0
  180. package/src/core/modules/threejs/Lighting.js +459 -0
  181. package/src/core/modules/threejs/Renderer.js +364 -0
  182. package/src/core/modules/threejs/Scene.js +266 -0
  183. package/src/core/modules/threejs/index.js +155 -0
  184. package/src/core/pages/404.js +50 -50
  185. package/src/core/pages/error.js +27 -27
  186. package/src/core/pages/jsonPage.js +62 -62
  187. package/src/core/pages/loading.js +44 -44
  188. package/src/core/parser/echart.data.js +204 -183
  189. package/src/core/parser/echart.features.js +125 -125
  190. package/src/core/parser/echart.general.js +147 -143
  191. package/src/core/parser/echart.hilbert.js +57 -57
  192. package/src/core/parser/echart.parser.js +210 -210
  193. package/src/core/parser/echart.series.js +67 -67
  194. package/src/core/parser/echart.types.js +76 -76
  195. package/src/core/parser/plotly.config.js +10 -10
  196. package/src/core/parser/plotly.data.js +132 -132
  197. package/src/core/parser/plotly.layout.js +9 -9
  198. package/src/core/parser/plotly.violin.js +18 -18
  199. package/src/core/recharts.js +361 -62
  200. package/src/core/router/alias.js +49 -49
  201. package/src/core/router/jsonRouter.js +31 -31
  202. package/src/core/themes/modern.js +32 -32
  203. package/src/core/themes/themeSelector.js +33 -33
  204. package/src/core/visualify.js +213 -47
  205. package/src/core/widgets/circularProgress.js +23 -23
  206. package/src/core/widgets/controller.js +116 -83
  207. package/src/core/widgets/errorBoundary.js +36 -36
  208. package/src/core/widgets/footer.js +185 -177
  209. package/src/core/widgets/header.js +238 -234
  210. package/src/core/widgets/layout/Grid.js +31 -31
  211. package/src/core/widgets/layout.js +36 -36
  212. package/src/core/widgets/mapping.js +56 -42
  213. package/src/core/workers/data-worker.js +349 -0
  214. package/src/core/workers/worker-pool.js +396 -0
  215. package/src/docsify/bundle.js +215 -0
  216. package/src/docsify/markdown.js +271 -0
  217. package/src/docsify/plugin.js +268 -0
  218. package/src/editor/README.md +172 -0
  219. package/src/editor/components/ChartBuilder.jsx +341 -0
  220. package/src/editor/components/ChartTypeSidebar.jsx +91 -0
  221. package/src/editor/components/Editor.jsx +367 -0
  222. package/src/editor/components/Preview.jsx +446 -0
  223. package/src/editor/components/PropertyPanel.jsx +468 -0
  224. package/src/editor/components/StatusBar.jsx +85 -0
  225. package/src/editor/context/EditorContext.js +248 -0
  226. package/src/editor/hooks/useDebounce.js +32 -0
  227. package/src/editor/index.js +315 -0
  228. package/src/editor/styles/editor.css +637 -0
  229. package/src/editor/utils/chartValidator.js +263 -0
  230. package/src/entries/charts3d.js +70 -0
  231. package/src/entries/core.js +78 -0
  232. package/src/entries/docs.js +154 -0
  233. package/src/entries/pages.js +93 -0
  234. package/src/entries/portal.js +204 -0
  235. package/src/entries/shared.js +50 -0
  236. package/src/i18n/formatters.js +455 -0
  237. package/src/i18n/index.js +169 -0
  238. package/src/i18n/locales/ar.json +137 -0
  239. package/src/i18n/locales/de.json +137 -0
  240. package/src/i18n/locales/en.json +137 -0
  241. package/src/i18n/locales/es.json +137 -0
  242. package/src/i18n/locales/he.json +137 -0
  243. package/src/i18n/locales/zh.json +137 -0
  244. package/src/i18n/rtl.css +183 -0
  245. package/src/index.js +82 -62
  246. package/src/loader.js +103 -0
  247. package/src/setupTests.js +5 -5
  248. package/tsconfig.json +51 -0
  249. package/types/charts.d.ts +569 -0
  250. package/types/components.d.ts +441 -0
  251. package/types/config.d.ts +199 -0
  252. package/types/index.d.ts +353 -0
@@ -0,0 +1,459 @@
1
+ /**
2
+ * Lighting.js - Three.js Lighting Manager for Visualify.js
3
+ * Handles ambient, directional, point lights and shadow configuration
4
+ */
5
+
6
+ import * as THREE from 'three';
7
+
8
+ /**
9
+ * Light types
10
+ */
11
+ export const LightType = {
12
+ AMBIENT: 'ambient',
13
+ DIRECTIONAL: 'directional',
14
+ POINT: 'point',
15
+ SPOT: 'spot',
16
+ HEMISPHERE: 'hemisphere',
17
+ RECT_AREA: 'rectArea',
18
+ };
19
+
20
+ /**
21
+ * LightingManager class for managing lights
22
+ */
23
+ export class LightingManager {
24
+ constructor() {
25
+ this.lights = new Map();
26
+ this.lightGroups = new Map();
27
+ }
28
+
29
+ /**
30
+ * Create an ambient light
31
+ * @param {string} id - Light identifier
32
+ * @param {Object} options - Light options
33
+ * @returns {THREE.AmbientLight}
34
+ */
35
+ createAmbientLight(id, options = {}) {
36
+ const config = {
37
+ color: 0xffffff,
38
+ intensity: 0.5,
39
+ ...options,
40
+ };
41
+
42
+ const light = new THREE.AmbientLight(config.color, config.intensity);
43
+ this.storeLight(id, light, LightType.AMBIENT, config);
44
+
45
+ return light;
46
+ }
47
+
48
+ /**
49
+ * Create a directional light
50
+ * @param {string} id - Light identifier
51
+ * @param {Object} options - Light options
52
+ * @returns {THREE.DirectionalLight}
53
+ */
54
+ createDirectionalLight(id, options = {}) {
55
+ const config = {
56
+ color: 0xffffff,
57
+ intensity: 1,
58
+ position: [10, 10, 10],
59
+ target: [0, 0, 0],
60
+ castShadow: false,
61
+ shadow: null,
62
+ ...options,
63
+ };
64
+
65
+ const light = new THREE.DirectionalLight(config.color, config.intensity);
66
+ light.position.set(...config.position);
67
+ light.target.position.set(...config.target);
68
+
69
+ // Configure shadows
70
+ if (config.castShadow) {
71
+ light.castShadow = true;
72
+ this.configureShadow(light, config.shadow);
73
+ }
74
+
75
+ this.storeLight(id, light, LightType.DIRECTIONAL, config);
76
+
77
+ return light;
78
+ }
79
+
80
+ /**
81
+ * Create a point light
82
+ * @param {string} id - Light identifier
83
+ * @param {Object} options - Light options
84
+ * @returns {THREE.PointLight}
85
+ */
86
+ createPointLight(id, options = {}) {
87
+ const config = {
88
+ color: 0xffffff,
89
+ intensity: 1,
90
+ distance: 0,
91
+ decay: 2,
92
+ position: [0, 0, 0],
93
+ castShadow: false,
94
+ shadow: null,
95
+ ...options,
96
+ };
97
+
98
+ const light = new THREE.PointLight(
99
+ config.color,
100
+ config.intensity,
101
+ config.distance,
102
+ config.decay
103
+ );
104
+ light.position.set(...config.position);
105
+
106
+ // Configure shadows
107
+ if (config.castShadow) {
108
+ light.castShadow = true;
109
+ this.configureShadow(light, config.shadow);
110
+ }
111
+
112
+ this.storeLight(id, light, LightType.POINT, config);
113
+
114
+ return light;
115
+ }
116
+
117
+ /**
118
+ * Create a spot light
119
+ * @param {string} id - Light identifier
120
+ * @param {Object} options - Light options
121
+ * @returns {THREE.SpotLight}
122
+ */
123
+ createSpotLight(id, options = {}) {
124
+ const config = {
125
+ color: 0xffffff,
126
+ intensity: 1,
127
+ distance: 0,
128
+ angle: Math.PI / 6,
129
+ penumbra: 0,
130
+ decay: 2,
131
+ position: [0, 10, 0],
132
+ target: [0, 0, 0],
133
+ castShadow: false,
134
+ shadow: null,
135
+ ...options,
136
+ };
137
+
138
+ const light = new THREE.SpotLight(
139
+ config.color,
140
+ config.intensity,
141
+ config.distance,
142
+ config.angle,
143
+ config.penumbra,
144
+ config.decay
145
+ );
146
+ light.position.set(...config.position);
147
+ light.target.position.set(...config.target);
148
+
149
+ // Configure shadows
150
+ if (config.castShadow) {
151
+ light.castShadow = true;
152
+ this.configureShadow(light, config.shadow);
153
+ }
154
+
155
+ this.storeLight(id, light, LightType.SPOT, config);
156
+
157
+ return light;
158
+ }
159
+
160
+ /**
161
+ * Create a hemisphere light
162
+ * @param {string} id - Light identifier
163
+ * @param {Object} options - Light options
164
+ * @returns {THREE.HemisphereLight}
165
+ */
166
+ createHemisphereLight(id, options = {}) {
167
+ const config = {
168
+ skyColor: 0xffffff,
169
+ groundColor: 0x444444,
170
+ intensity: 1,
171
+ position: [0, 10, 0],
172
+ ...options,
173
+ };
174
+
175
+ const light = new THREE.HemisphereLight(
176
+ config.skyColor,
177
+ config.groundColor,
178
+ config.intensity
179
+ );
180
+ light.position.set(...config.position);
181
+
182
+ this.storeLight(id, light, LightType.HEMISPHERE, config);
183
+
184
+ return light;
185
+ }
186
+
187
+ /**
188
+ * Configure shadow properties for a light
189
+ * @param {THREE.Light} light - Light with shadow capabilities
190
+ * @param {Object} shadowConfig - Shadow configuration
191
+ */
192
+ configureShadow(light, shadowConfig = {}) {
193
+ if (!light.shadow) return;
194
+
195
+ const config = {
196
+ mapSize: { width: 1024, height: 1024 },
197
+ camera: {
198
+ near: 0.5,
199
+ far: 500,
200
+ left: -50,
201
+ right: 50,
202
+ top: 50,
203
+ bottom: -50,
204
+ },
205
+ bias: -0.001,
206
+ radius: 1,
207
+ ...shadowConfig,
208
+ };
209
+
210
+ // Set shadow map size
211
+ if (config.mapSize) {
212
+ light.shadow.mapSize.width = config.mapSize.width;
213
+ light.shadow.mapSize.height = config.mapSize.height;
214
+ }
215
+
216
+ // Configure shadow camera
217
+ if (config.camera && light.shadow.camera) {
218
+ Object.assign(light.shadow.camera, config.camera);
219
+ light.shadow.camera.updateProjectionMatrix();
220
+ }
221
+
222
+ // Set bias and radius
223
+ if (config.bias !== undefined) {
224
+ light.shadow.bias = config.bias;
225
+ }
226
+ if (config.radius !== undefined) {
227
+ light.shadow.radius = config.radius;
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Store light in manager
233
+ * @param {string} id
234
+ * @param {THREE.Light} light
235
+ * @param {string} type
236
+ * @param {Object} config
237
+ */
238
+ storeLight(id, light, type, config) {
239
+ if (this.lights.has(id)) {
240
+ console.warn(`Light with id "${id}" already exists. Replacing.`);
241
+ this.disposeLight(id);
242
+ }
243
+
244
+ this.lights.set(id, {
245
+ light,
246
+ type,
247
+ config,
248
+ createdAt: Date.now(),
249
+ });
250
+ }
251
+
252
+ /**
253
+ * Create a light from configuration
254
+ * @param {string} id - Light identifier
255
+ * @param {Object} config - Light configuration
256
+ * @returns {THREE.Light}
257
+ */
258
+ createLight(id, config = {}) {
259
+ const type = config.type || LightType.AMBIENT;
260
+
261
+ switch (type) {
262
+ case LightType.AMBIENT:
263
+ return this.createAmbientLight(id, config);
264
+ case LightType.DIRECTIONAL:
265
+ return this.createDirectionalLight(id, config);
266
+ case LightType.POINT:
267
+ return this.createPointLight(id, config);
268
+ case LightType.SPOT:
269
+ return this.createSpotLight(id, config);
270
+ case LightType.HEMISPHERE:
271
+ return this.createHemisphereLight(id, config);
272
+ default:
273
+ throw new Error(`Unknown light type: ${type}`);
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Get a light by ID
279
+ * @param {string} id - Light identifier
280
+ * @returns {THREE.Light|null}
281
+ */
282
+ getLight(id) {
283
+ const lightData = this.lights.get(id);
284
+ return lightData ? lightData.light : null;
285
+ }
286
+
287
+ /**
288
+ * Update light intensity
289
+ * @param {string} id - Light identifier
290
+ * @param {number} intensity - New intensity
291
+ */
292
+ updateIntensity(id, intensity) {
293
+ const lightData = this.lights.get(id);
294
+ if (lightData && lightData.light) {
295
+ lightData.light.intensity = intensity;
296
+ }
297
+ }
298
+
299
+ /**
300
+ * Update light color
301
+ * @param {string} id - Light identifier
302
+ * @param {string|number} color - New color
303
+ */
304
+ updateColor(id, color) {
305
+ const lightData = this.lights.get(id);
306
+ if (lightData && lightData.light) {
307
+ lightData.light.color.set(color);
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Update light position
313
+ * @param {string} id - Light identifier
314
+ * @param {number[]} position - New position [x, y, z]
315
+ */
316
+ updatePosition(id, position) {
317
+ const lightData = this.lights.get(id);
318
+ if (lightData && lightData.light) {
319
+ lightData.light.position.set(...position);
320
+ }
321
+ }
322
+
323
+ /**
324
+ * Create a light group
325
+ * @param {string} groupId - Group identifier
326
+ * @param {string[]} lightIds - Array of light IDs to include
327
+ */
328
+ createLightGroup(groupId, lightIds = []) {
329
+ const group = new THREE.Group();
330
+
331
+ lightIds.forEach((lightId) => {
332
+ const lightData = this.lights.get(lightId);
333
+ if (lightData) {
334
+ group.add(lightData.light);
335
+ }
336
+ });
337
+
338
+ this.lightGroups.set(groupId, {
339
+ group,
340
+ lightIds,
341
+ });
342
+
343
+ return group;
344
+ }
345
+
346
+ /**
347
+ * Get a light group
348
+ * @param {string} groupId - Group identifier
349
+ * @returns {THREE.Group|null}
350
+ */
351
+ getLightGroup(groupId) {
352
+ const groupData = this.lightGroups.get(groupId);
353
+ return groupData ? groupData.group : null;
354
+ }
355
+
356
+ /**
357
+ * Remove a light
358
+ * @param {string} id - Light identifier
359
+ */
360
+ removeLight(id) {
361
+ this.disposeLight(id);
362
+ this.lights.delete(id);
363
+ }
364
+
365
+ /**
366
+ * Dispose light resources
367
+ * @param {string} id - Light identifier
368
+ */
369
+ disposeLight(id) {
370
+ const lightData = this.lights.get(id);
371
+ if (!lightData) return;
372
+
373
+ const light = lightData.light;
374
+
375
+ // Dispose shadow map if exists
376
+ if (light.shadow && light.shadow.map) {
377
+ light.shadow.map.dispose();
378
+ }
379
+
380
+ // Remove from any groups
381
+ this.lightGroups.forEach((groupData) => {
382
+ groupData.group.remove(light);
383
+ });
384
+
385
+ lightData.light = null;
386
+ }
387
+
388
+ /**
389
+ * Remove a light group
390
+ * @param {string} groupId - Group identifier
391
+ */
392
+ removeLightGroup(groupId) {
393
+ const groupData = this.lightGroups.get(groupId);
394
+ if (!groupData) return;
395
+
396
+ // Remove all lights from group
397
+ groupData.lightIds.forEach((lightId) => {
398
+ const lightData = this.lights.get(lightId);
399
+ if (lightData) {
400
+ groupData.group.remove(lightData.light);
401
+ }
402
+ });
403
+
404
+ this.lightGroups.delete(groupId);
405
+ }
406
+
407
+ /**
408
+ * Get all light IDs
409
+ * @returns {string[]}
410
+ */
411
+ getLightIds() {
412
+ return Array.from(this.lights.keys());
413
+ }
414
+
415
+ /**
416
+ * Dispose all lights
417
+ */
418
+ dispose() {
419
+ this.getLightIds().forEach((id) => this.removeLight(id));
420
+ this.lightGroups.clear();
421
+ }
422
+ }
423
+
424
+ /**
425
+ * Create lights from configuration array
426
+ * @param {Object[]} lightConfigs - Array of light configurations
427
+ * @returns {THREE.Light[]}
428
+ */
429
+ export function createLightsFromConfig(lightConfigs = []) {
430
+ const manager = new LightingManager();
431
+ const lights = [];
432
+
433
+ lightConfigs.forEach((config, index) => {
434
+ const id = config.id || `light_${index}`;
435
+ const light = manager.createLight(id, config);
436
+ lights.push(light);
437
+ });
438
+
439
+ return lights;
440
+ }
441
+
442
+ /**
443
+ * Create a default lighting setup
444
+ * @returns {THREE.Light[]}
445
+ */
446
+ export function createDefaultLighting() {
447
+ return createLightsFromConfig([
448
+ { type: LightType.AMBIENT, color: 0xffffff, intensity: 0.5 },
449
+ {
450
+ type: LightType.DIRECTIONAL,
451
+ color: 0xffffff,
452
+ intensity: 1,
453
+ position: [10, 10, 10],
454
+ castShadow: true,
455
+ },
456
+ ]);
457
+ }
458
+
459
+ export default LightingManager;