@cosmos.gl/graph 2.6.0 → 2.6.2-rc.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 (169) hide show
  1. package/dist/config.d.ts +3 -0
  2. package/dist/index.d.ts +48 -6
  3. package/dist/index.js +1346 -1289
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.min.js +15 -15
  6. package/dist/index.min.js.map +1 -1
  7. package/package.json +5 -1
  8. package/.eslintrc +0 -147
  9. package/.github/SECURITY.md +0 -19
  10. package/.github/dco.yml +0 -4
  11. package/.github/workflows/github_pages.yml +0 -54
  12. package/.storybook/main.ts +0 -26
  13. package/.storybook/manager-head.html +0 -1
  14. package/.storybook/manager.ts +0 -14
  15. package/.storybook/preview.ts +0 -29
  16. package/.storybook/style.css +0 -3
  17. package/CHARTER.md +0 -69
  18. package/CODE_OF_CONDUCT.md +0 -178
  19. package/CONTRIBUTING.md +0 -22
  20. package/GOVERNANCE.md +0 -21
  21. package/cosmos-2-0-migration-notes.md +0 -98
  22. package/cosmos_awesome.md +0 -96
  23. package/dist/stories/beginners/basic-set-up/data-gen.d.ts +0 -4
  24. package/dist/stories/beginners/basic-set-up/index.d.ts +0 -5
  25. package/dist/stories/beginners/link-hovering/data-generator.d.ts +0 -19
  26. package/dist/stories/beginners/link-hovering/index.d.ts +0 -5
  27. package/dist/stories/beginners/pinned-points/data-gen.d.ts +0 -5
  28. package/dist/stories/beginners/pinned-points/index.d.ts +0 -5
  29. package/dist/stories/beginners/point-labels/data.d.ts +0 -13
  30. package/dist/stories/beginners/point-labels/index.d.ts +0 -9
  31. package/dist/stories/beginners/point-labels/labels.d.ts +0 -8
  32. package/dist/stories/beginners/quick-start.d.ts +0 -5
  33. package/dist/stories/beginners/remove-points/config.d.ts +0 -2
  34. package/dist/stories/beginners/remove-points/data-gen.d.ts +0 -4
  35. package/dist/stories/beginners/remove-points/index.d.ts +0 -5
  36. package/dist/stories/beginners.stories.d.ts +0 -11
  37. package/dist/stories/clusters/polygon-selection/index.d.ts +0 -6
  38. package/dist/stories/clusters/polygon-selection/polygon.d.ts +0 -20
  39. package/dist/stories/clusters/radial.d.ts +0 -5
  40. package/dist/stories/clusters/with-labels.d.ts +0 -6
  41. package/dist/stories/clusters/worm.d.ts +0 -5
  42. package/dist/stories/clusters.stories.d.ts +0 -9
  43. package/dist/stories/create-cluster-labels.d.ts +0 -4
  44. package/dist/stories/create-cosmos.d.ts +0 -16
  45. package/dist/stories/create-story.d.ts +0 -16
  46. package/dist/stories/experiments/full-mesh.d.ts +0 -5
  47. package/dist/stories/experiments/mesh-with-holes.d.ts +0 -5
  48. package/dist/stories/experiments.stories.d.ts +0 -7
  49. package/dist/stories/generate-mesh-data.d.ts +0 -12
  50. package/dist/stories/geospatial/moscow-metro-stations/index.d.ts +0 -15
  51. package/dist/stories/geospatial/moscow-metro-stations/moscow-metro-coords.d.ts +0 -1
  52. package/dist/stories/geospatial/moscow-metro-stations/point-colors.d.ts +0 -1
  53. package/dist/stories/geospatial.stories.d.ts +0 -6
  54. package/dist/stories/shapes/all-shapes/index.d.ts +0 -5
  55. package/dist/stories/shapes/image-example/index.d.ts +0 -5
  56. package/dist/stories/shapes.stories.d.ts +0 -7
  57. package/logo.svg +0 -3
  58. package/rollup.config.js +0 -70
  59. package/src/config.ts +0 -734
  60. package/src/declaration.d.ts +0 -12
  61. package/src/graph/utils/error-message.ts +0 -23
  62. package/src/helper.ts +0 -74
  63. package/src/index.ts +0 -1635
  64. package/src/modules/Clusters/calculate-centermass.frag +0 -9
  65. package/src/modules/Clusters/calculate-centermass.vert +0 -26
  66. package/src/modules/Clusters/force-cluster.frag +0 -39
  67. package/src/modules/Clusters/index.ts +0 -200
  68. package/src/modules/Drag/index.ts +0 -33
  69. package/src/modules/FPSMonitor/css.ts +0 -53
  70. package/src/modules/FPSMonitor/index.ts +0 -28
  71. package/src/modules/ForceCenter/calculate-centermass.frag +0 -9
  72. package/src/modules/ForceCenter/calculate-centermass.vert +0 -18
  73. package/src/modules/ForceCenter/force-center.frag +0 -27
  74. package/src/modules/ForceCenter/index.ts +0 -104
  75. package/src/modules/ForceGravity/force-gravity.frag +0 -27
  76. package/src/modules/ForceGravity/index.ts +0 -33
  77. package/src/modules/ForceLink/force-spring.ts +0 -73
  78. package/src/modules/ForceLink/index.ts +0 -149
  79. package/src/modules/ForceManyBody/calculate-level.frag +0 -9
  80. package/src/modules/ForceManyBody/calculate-level.vert +0 -25
  81. package/src/modules/ForceManyBody/force-centermass.frag +0 -52
  82. package/src/modules/ForceManyBody/force-level.frag +0 -121
  83. package/src/modules/ForceManyBody/index.ts +0 -223
  84. package/src/modules/ForceManyBody/quadtree-frag-shader.ts +0 -90
  85. package/src/modules/ForceManyBodyQuadtree/calculate-level.frag +0 -9
  86. package/src/modules/ForceManyBodyQuadtree/calculate-level.vert +0 -25
  87. package/src/modules/ForceManyBodyQuadtree/index.ts +0 -157
  88. package/src/modules/ForceManyBodyQuadtree/quadtree-frag-shader.ts +0 -93
  89. package/src/modules/ForceMouse/force-mouse.frag +0 -24
  90. package/src/modules/ForceMouse/index.ts +0 -32
  91. package/src/modules/GraphData/index.ts +0 -384
  92. package/src/modules/Lines/draw-curve-line.frag +0 -46
  93. package/src/modules/Lines/draw-curve-line.vert +0 -194
  94. package/src/modules/Lines/geometry.ts +0 -18
  95. package/src/modules/Lines/hovered-line-index.frag +0 -27
  96. package/src/modules/Lines/hovered-line-index.vert +0 -8
  97. package/src/modules/Lines/index.ts +0 -273
  98. package/src/modules/Points/atlas-utils.ts +0 -137
  99. package/src/modules/Points/drag-point.frag +0 -20
  100. package/src/modules/Points/draw-highlighted.frag +0 -16
  101. package/src/modules/Points/draw-highlighted.vert +0 -86
  102. package/src/modules/Points/draw-points.frag +0 -243
  103. package/src/modules/Points/draw-points.vert +0 -127
  104. package/src/modules/Points/fill-sampled-points.frag +0 -9
  105. package/src/modules/Points/fill-sampled-points.vert +0 -29
  106. package/src/modules/Points/find-hovered-point.frag +0 -9
  107. package/src/modules/Points/find-hovered-point.vert +0 -57
  108. package/src/modules/Points/find-points-on-area-selection.frag +0 -48
  109. package/src/modules/Points/find-points-on-polygon-selection.frag +0 -65
  110. package/src/modules/Points/index.ts +0 -968
  111. package/src/modules/Points/track-positions.frag +0 -18
  112. package/src/modules/Points/update-position.frag +0 -37
  113. package/src/modules/Shared/buffer.ts +0 -37
  114. package/src/modules/Shared/clear.frag +0 -7
  115. package/src/modules/Shared/quad.vert +0 -12
  116. package/src/modules/Store/index.ts +0 -173
  117. package/src/modules/Zoom/index.ts +0 -148
  118. package/src/modules/core-module.ts +0 -28
  119. package/src/stories/1. welcome.mdx +0 -81
  120. package/src/stories/2. configuration.mdx +0 -113
  121. package/src/stories/3. api-reference.mdx +0 -591
  122. package/src/stories/beginners/basic-set-up/data-gen.ts +0 -33
  123. package/src/stories/beginners/basic-set-up/index.ts +0 -163
  124. package/src/stories/beginners/basic-set-up/style.css +0 -35
  125. package/src/stories/beginners/link-hovering/data-generator.ts +0 -198
  126. package/src/stories/beginners/link-hovering/index.ts +0 -61
  127. package/src/stories/beginners/link-hovering/style.css +0 -73
  128. package/src/stories/beginners/pinned-points/data-gen.ts +0 -153
  129. package/src/stories/beginners/pinned-points/index.ts +0 -61
  130. package/src/stories/beginners/point-labels/data.ts +0 -73
  131. package/src/stories/beginners/point-labels/index.ts +0 -65
  132. package/src/stories/beginners/point-labels/labels.ts +0 -46
  133. package/src/stories/beginners/point-labels/style.css +0 -16
  134. package/src/stories/beginners/quick-start.ts +0 -50
  135. package/src/stories/beginners/remove-points/config.ts +0 -25
  136. package/src/stories/beginners/remove-points/data-gen.ts +0 -30
  137. package/src/stories/beginners/remove-points/index.ts +0 -92
  138. package/src/stories/beginners/remove-points/style.css +0 -31
  139. package/src/stories/beginners.stories.ts +0 -131
  140. package/src/stories/clusters/polygon-selection/index.ts +0 -51
  141. package/src/stories/clusters/polygon-selection/polygon.ts +0 -143
  142. package/src/stories/clusters/polygon-selection/style.css +0 -8
  143. package/src/stories/clusters/radial.ts +0 -24
  144. package/src/stories/clusters/with-labels.ts +0 -53
  145. package/src/stories/clusters/worm.ts +0 -40
  146. package/src/stories/clusters.stories.ts +0 -77
  147. package/src/stories/create-cluster-labels.ts +0 -50
  148. package/src/stories/create-cosmos.ts +0 -68
  149. package/src/stories/create-story.ts +0 -51
  150. package/src/stories/experiments/full-mesh.ts +0 -13
  151. package/src/stories/experiments/mesh-with-holes.ts +0 -13
  152. package/src/stories/experiments.stories.ts +0 -43
  153. package/src/stories/generate-mesh-data.ts +0 -125
  154. package/src/stories/geospatial/moscow-metro-stations/index.ts +0 -62
  155. package/src/stories/geospatial/moscow-metro-stations/moscow-metro-coords.ts +0 -1
  156. package/src/stories/geospatial/moscow-metro-stations/point-colors.ts +0 -46
  157. package/src/stories/geospatial/moscow-metro-stations/style.css +0 -30
  158. package/src/stories/geospatial.stories.ts +0 -30
  159. package/src/stories/shapes/all-shapes/index.ts +0 -69
  160. package/src/stories/shapes/image-example/icons/box.png +0 -0
  161. package/src/stories/shapes/image-example/icons/lego.png +0 -0
  162. package/src/stories/shapes/image-example/icons/s.png +0 -0
  163. package/src/stories/shapes/image-example/icons/swift.png +0 -0
  164. package/src/stories/shapes/image-example/icons/toolbox.png +0 -0
  165. package/src/stories/shapes/image-example/index.ts +0 -238
  166. package/src/stories/shapes.stories.ts +0 -37
  167. package/src/variables.ts +0 -68
  168. package/tsconfig.json +0 -41
  169. package/vite.config.ts +0 -54
@@ -1,273 +0,0 @@
1
- import regl from 'regl'
2
- import { CoreModule } from '@/graph/modules/core-module'
3
- import drawLineFrag from '@/graph/modules/Lines/draw-curve-line.frag'
4
- import drawLineVert from '@/graph/modules/Lines/draw-curve-line.vert'
5
- import hoveredLineIndexFrag from '@/graph/modules/Lines/hovered-line-index.frag'
6
- import hoveredLineIndexVert from '@/graph/modules/Lines/hovered-line-index.vert'
7
- import { defaultConfigValues } from '@/graph/variables'
8
- import { getCurveLineGeometry } from '@/graph/modules/Lines/geometry'
9
-
10
- export class Lines extends CoreModule {
11
- public linkIndexFbo: regl.Framebuffer2D | undefined
12
- public hoveredLineIndexFbo: regl.Framebuffer2D | undefined
13
- private drawCurveCommand: regl.DrawCommand | undefined
14
- private hoveredLineIndexCommand: regl.DrawCommand | undefined
15
- private pointsBuffer: regl.Buffer | undefined
16
- private colorBuffer: regl.Buffer | undefined
17
- private widthBuffer: regl.Buffer | undefined
18
- private arrowBuffer: regl.Buffer | undefined
19
- private curveLineGeometry: number[][] | undefined
20
- private curveLineBuffer: regl.Buffer | undefined
21
- private linkIndexBuffer: regl.Buffer | undefined
22
- private quadBuffer: regl.Buffer | undefined
23
-
24
- public initPrograms (): void {
25
- const { reglInstance, config, store } = this
26
-
27
- this.updateLinkIndexFbo()
28
-
29
- // Initialize the hovered line index FBO
30
- if (!this.hoveredLineIndexFbo) {
31
- this.hoveredLineIndexFbo = reglInstance.framebuffer({
32
- color: reglInstance.texture({
33
- width: 1,
34
- height: 1,
35
- format: 'rgba',
36
- type: 'float',
37
- }),
38
- depth: false,
39
- stencil: false,
40
- })
41
- }
42
-
43
- if (!this.drawCurveCommand) {
44
- this.drawCurveCommand = reglInstance({
45
- vert: drawLineVert,
46
- frag: drawLineFrag,
47
-
48
- attributes: {
49
- position: {
50
- buffer: () => this.curveLineBuffer,
51
- divisor: 0,
52
- },
53
- pointA: {
54
- buffer: () => this.pointsBuffer,
55
- divisor: 1,
56
- offset: Float32Array.BYTES_PER_ELEMENT * 0,
57
- stride: Float32Array.BYTES_PER_ELEMENT * 4,
58
- },
59
- pointB: {
60
- buffer: () => this.pointsBuffer,
61
- divisor: 1,
62
- offset: Float32Array.BYTES_PER_ELEMENT * 2,
63
- stride: Float32Array.BYTES_PER_ELEMENT * 4,
64
- },
65
- color: {
66
- buffer: () => this.colorBuffer,
67
- divisor: 1,
68
- offset: Float32Array.BYTES_PER_ELEMENT * 0,
69
- stride: Float32Array.BYTES_PER_ELEMENT * 4,
70
- },
71
- width: {
72
- buffer: () => this.widthBuffer,
73
- divisor: 1,
74
- offset: Float32Array.BYTES_PER_ELEMENT * 0,
75
- stride: Float32Array.BYTES_PER_ELEMENT * 1,
76
- },
77
- arrow: {
78
- buffer: () => this.arrowBuffer,
79
- divisor: 1,
80
- offset: Float32Array.BYTES_PER_ELEMENT * 0,
81
- stride: Float32Array.BYTES_PER_ELEMENT * 1,
82
- },
83
- linkIndices: {
84
- buffer: () => this.linkIndexBuffer,
85
- divisor: 1,
86
- offset: Float32Array.BYTES_PER_ELEMENT * 0,
87
- stride: Float32Array.BYTES_PER_ELEMENT * 1,
88
- },
89
- },
90
- uniforms: {
91
- positionsTexture: () => this.points?.currentPositionFbo,
92
- pointGreyoutStatus: () => this.points?.greyoutStatusFbo,
93
- transformationMatrix: () => store.transform,
94
- pointsTextureSize: () => store.pointsTextureSize,
95
- widthScale: () => config.linkWidthScale,
96
- linkArrowsSizeScale: () => config.linkArrowsSizeScale,
97
- spaceSize: () => store.adjustedSpaceSize,
98
- screenSize: () => store.screenSize,
99
- linkVisibilityDistanceRange: () => config.linkVisibilityDistanceRange,
100
- linkVisibilityMinTransparency: () => config.linkVisibilityMinTransparency,
101
- linkOpacity: () => config.linkOpacity,
102
- greyoutOpacity: () => config.linkGreyoutOpacity,
103
- scaleLinksOnZoom: () => config.scaleLinksOnZoom,
104
- maxPointSize: () => store.maxPointSize,
105
- curvedWeight: () => config.curvedLinkWeight,
106
- curvedLinkControlPointDistance: () => config.curvedLinkControlPointDistance,
107
- curvedLinkSegments: () => config.curvedLinks ? config.curvedLinkSegments ?? defaultConfigValues.curvedLinkSegments : 1,
108
- hoveredLinkIndex: () => store.hoveredLinkIndex ?? -1,
109
- hoveredLinkColor: () => store.hoveredLinkColor,
110
- hoveredLinkWidthIncrease: () => config.hoveredLinkWidthIncrease,
111
- renderMode: reglInstance.prop<{ renderMode: number }, 'renderMode'>('renderMode'),
112
- },
113
- cull: {
114
- enable: true,
115
- face: 'back',
116
- },
117
- /**
118
- * Blending behavior for link index rendering (renderMode: 1.0 - hover detection):
119
- *
120
- * When rendering link indices to the framebuffer, we use full opacity (1.0).
121
- * This means:
122
- * - The source color completely overwrites the destination
123
- * - No blending occurs - it's like drawing with a permanent marker
124
- * - This preserves the exact index values we need for picking/selection
125
- */
126
- blend: {
127
- enable: true,
128
- func: {
129
- dstRGB: 'one minus src alpha',
130
- srcRGB: 'src alpha',
131
- dstAlpha: 'one minus src alpha',
132
- srcAlpha: 'one',
133
- },
134
- equation: {
135
- rgb: 'add',
136
- alpha: 'add',
137
- },
138
- },
139
- depth: {
140
- enable: false,
141
- mask: false,
142
- },
143
- framebuffer: reglInstance.prop<{ framebuffer: regl.Framebuffer2D }, 'framebuffer'>('framebuffer'),
144
- count: () => this.curveLineGeometry?.length ?? 0,
145
- instances: () => this.data.linksNumber ?? 0,
146
- primitive: 'triangle strip',
147
- })
148
- }
149
-
150
- if (!this.hoveredLineIndexCommand) {
151
- this.hoveredLineIndexCommand = reglInstance({
152
- vert: hoveredLineIndexVert,
153
- frag: hoveredLineIndexFrag,
154
- attributes: {
155
- position: {
156
- buffer: () => this.quadBuffer,
157
- },
158
- },
159
- uniforms: {
160
- linkIndexTexture: () => this.linkIndexFbo,
161
- mousePosition: () => store.screenMousePosition,
162
- screenSize: () => store.screenSize,
163
- },
164
- framebuffer: this.hoveredLineIndexFbo,
165
- count: 4,
166
- primitive: 'triangle strip',
167
- })
168
- }
169
-
170
- // Initialize quad buffer for full-screen rendering
171
- if (!this.quadBuffer) {
172
- this.quadBuffer = reglInstance.buffer([-1, -1, 1, -1, -1, 1, 1, 1])
173
- }
174
- }
175
-
176
- public draw (): void {
177
- if (!this.pointsBuffer) return
178
- if (!this.colorBuffer) this.updateColor()
179
- if (!this.widthBuffer) this.updateWidth()
180
- if (!this.arrowBuffer) this.updateArrow()
181
- if (!this.curveLineGeometry) this.updateCurveLineGeometry()
182
-
183
- // Render normal links (renderMode: 0.0 = normal rendering)
184
- this.drawCurveCommand?.({ framebuffer: null, renderMode: 0.0 })
185
- }
186
-
187
- public updateLinkIndexFbo (): void {
188
- const { reglInstance, store } = this
189
-
190
- // Only create and update the link index FBO if link hovering is enabled
191
- if (!this.store.isLinkHoveringEnabled) return
192
-
193
- if (!this.linkIndexFbo) this.linkIndexFbo = reglInstance.framebuffer()
194
- this.linkIndexFbo({
195
- color: reglInstance.texture({
196
- width: store.screenSize[0],
197
- height: store.screenSize[1],
198
- format: 'rgba',
199
- type: 'float',
200
- }),
201
- depth: false,
202
- stencil: false,
203
- })
204
- }
205
-
206
- public updatePointsBuffer (): void {
207
- const { reglInstance, data, store } = this
208
- if (data.linksNumber === undefined || data.links === undefined) return
209
- const instancePoints = new Float32Array(data.linksNumber * 4)
210
- for (let i = 0; i < data.linksNumber; i++) {
211
- const fromIndex = data.links[i * 2] as number
212
- const toIndex = data.links[i * 2 + 1] as number
213
- const fromX = fromIndex % store.pointsTextureSize
214
- const fromY = Math.floor(fromIndex / store.pointsTextureSize)
215
- const toX = toIndex % store.pointsTextureSize
216
- const toY = Math.floor(toIndex / store.pointsTextureSize)
217
- const offset = i * 4
218
- instancePoints[offset] = fromX
219
- instancePoints[offset + 1] = fromY
220
- instancePoints[offset + 2] = toX
221
- instancePoints[offset + 3] = toY
222
- }
223
-
224
- if (!this.pointsBuffer) this.pointsBuffer = reglInstance.buffer(0)
225
- this.pointsBuffer(instancePoints)
226
-
227
- const linkIndices = new Float32Array(data.linksNumber)
228
- for (let i = 0; i < data.linksNumber; i++) {
229
- linkIndices[i] = i
230
- }
231
- if (!this.linkIndexBuffer) this.linkIndexBuffer = reglInstance.buffer(0)
232
- this.linkIndexBuffer(linkIndices)
233
- }
234
-
235
- public updateColor (): void {
236
- const { reglInstance, data } = this
237
- if (!this.colorBuffer) this.colorBuffer = reglInstance.buffer(0)
238
- this.colorBuffer(data.linkColors ?? new Float32Array())
239
- }
240
-
241
- public updateWidth (): void {
242
- const { reglInstance, data } = this
243
- if (!this.widthBuffer) this.widthBuffer = reglInstance.buffer(0)
244
- this.widthBuffer(data.linkWidths ?? new Float32Array())
245
- }
246
-
247
- public updateArrow (): void {
248
- const { reglInstance, data } = this
249
- if (!this.arrowBuffer) this.arrowBuffer = reglInstance.buffer(0)
250
- this.arrowBuffer(data.linkArrows ?? new Float32Array())
251
- }
252
-
253
- public updateCurveLineGeometry (): void {
254
- const { reglInstance, config: { curvedLinks, curvedLinkSegments } } = this
255
- this.curveLineGeometry = getCurveLineGeometry(curvedLinks ? curvedLinkSegments ?? defaultConfigValues.curvedLinkSegments : 1)
256
- if (!this.curveLineBuffer) this.curveLineBuffer = reglInstance.buffer(0)
257
- this.curveLineBuffer(this.curveLineGeometry)
258
- }
259
-
260
- public findHoveredLine (): void {
261
- if (!this.data.linksNumber || !this.store.isLinkHoveringEnabled) return
262
- if (!this.linkIndexFbo) this.updateLinkIndexFbo()
263
- this.reglInstance.clear({
264
- framebuffer: this.linkIndexFbo as regl.Framebuffer2D,
265
- color: [0, 0, 0, 0],
266
- })
267
- // Render to index buffer for picking/hover detection (renderMode: 1.0 = index rendering)
268
- this.drawCurveCommand?.({ framebuffer: this.linkIndexFbo, renderMode: 1.0 })
269
-
270
- // Execute the command to read the link index at mouse position
271
- this.hoveredLineIndexCommand?.()
272
- }
273
- }
@@ -1,137 +0,0 @@
1
- /**
2
- * Creates a texture atlas from an array of ImageData objects.
3
- *
4
- * A texture atlas is a single large texture that contains multiple smaller images.
5
- * This allows efficient rendering by reducing the number of texture bindings needed.
6
- *
7
- * The atlas uses a grid layout where each image gets a square region sized to
8
- * accommodate the largest image dimension. Images are placed left-to-right, top-to-bottom.
9
- *
10
- * @param imageDataArray - Array of ImageData objects to pack into the atlas
11
- * @param webglMaxTextureSize - WebGL maximum texture size limit (default: 16384)
12
- * @returns Atlas data object containing:
13
- * - atlasData: RGBA pixel data as Uint8Array
14
- * - atlasSize: Total atlas texture size in pixels
15
- * - atlasCoords: UV coordinates for each image as Float32Array
16
- * - atlasCoordsSize: Grid size (number of rows/columns)
17
- * Returns null if creation fails or no valid images provided
18
- */
19
- export function createAtlasDataFromImageData (
20
- imageDataArray: ImageData[],
21
- webglMaxTextureSize = 16384
22
- ): {
23
- atlasData: Uint8Array;
24
- atlasSize: number;
25
- atlasCoords: Float32Array;
26
- atlasCoordsSize: number;
27
- } | null {
28
- // Step 1: Validate input - ensure we have images to process
29
- if (!imageDataArray?.length) {
30
- return null
31
- }
32
-
33
- // Step 2: Find the maximum dimension across all images
34
- // The max dimension determines the size of each grid cell in the atlas
35
- let maxDimension = 0
36
- for (const imageData of imageDataArray) {
37
- const dimension = Math.max(imageData.width, imageData.height)
38
- if (dimension > maxDimension) {
39
- maxDimension = dimension
40
- }
41
- }
42
-
43
- // Step 3: Validate that we found valid image dimensions
44
- if (maxDimension === 0) {
45
- console.warn('Invalid image dimensions: all images have zero width or height')
46
- return null
47
- }
48
-
49
- const originalMaxDimension = maxDimension
50
-
51
- // Step 4: Calculate optimal atlas grid size
52
- const atlasCoordsSize = Math.ceil(Math.sqrt(imageDataArray.length))
53
- let atlasSize = atlasCoordsSize * maxDimension
54
-
55
- // Step 5: Apply WebGL size limit scaling if necessary
56
- let scalingFactor = 1.0
57
-
58
- if (atlasSize > webglMaxTextureSize) {
59
- // Calculate required scale to fit within WebGL limits
60
- scalingFactor = webglMaxTextureSize / atlasSize
61
-
62
- // Apply scaling to both the individual image dimensions and atlas size
63
- maxDimension = Math.max(1, Math.floor(maxDimension * scalingFactor))
64
- atlasSize = Math.max(1, Math.floor(atlasSize * scalingFactor))
65
-
66
- console.warn(
67
- '🖼️ Atlas scaling required: Original size ' +
68
- `${(originalMaxDimension * atlasCoordsSize).toLocaleString()}px exceeds WebGL limit ` +
69
- `${webglMaxTextureSize.toLocaleString()}px. Scaling down to ${atlasSize.toLocaleString()}px ` +
70
- `(${Math.round(scalingFactor * 100)}% of original quality)`
71
- )
72
- }
73
-
74
- // Step 6: Create buffers for atlas data
75
- const atlasData = new Uint8Array(atlasSize * atlasSize * 4).fill(0)
76
- const atlasCoords = new Float32Array(atlasCoordsSize * atlasCoordsSize * 4).fill(-1)
77
-
78
- // Step 7: Pack each image into the atlas grid
79
- for (const [index, imageData] of imageDataArray.entries()) {
80
- const originalWidth = imageData.width
81
- const originalHeight = imageData.height
82
- if (originalWidth === 0 || originalHeight === 0) {
83
- // leave coords at -1 for this index and continue
84
- continue
85
- }
86
-
87
- // Calculate individual scale for this image based on maxDimension
88
- // This ensures each image fits optimally within its grid cell
89
- const individualScale = Math.min(1.0, maxDimension / Math.max(originalWidth, originalHeight))
90
-
91
- const scaledWidth = Math.floor(originalWidth * individualScale)
92
- const scaledHeight = Math.floor(originalHeight * individualScale)
93
-
94
- // Calculate grid position (row, column) for this image
95
- const row = Math.floor(index / atlasCoordsSize)
96
- const col = index % atlasCoordsSize
97
-
98
- // Calculate pixel position in the atlas texture
99
- const atlasX = col * maxDimension
100
- const atlasY = row * maxDimension
101
-
102
- // Calculate and store UV coordinates for this image
103
- atlasCoords[index * 4] = atlasX / atlasSize // minU
104
- atlasCoords[index * 4 + 1] = atlasY / atlasSize // minV
105
- atlasCoords[index * 4 + 2] = (atlasX + scaledWidth) / atlasSize // maxU
106
- atlasCoords[index * 4 + 3] = (atlasY + scaledHeight) / atlasSize // maxV
107
-
108
- // Copy image pixel data into the atlas texture
109
- for (let y = 0; y < scaledHeight; y++) {
110
- for (let x = 0; x < scaledWidth; x++) {
111
- // Calculate source pixel coordinates (with scaling)
112
- const srcX = Math.floor(x * (originalWidth / scaledWidth))
113
- const srcY = Math.floor(y * (originalHeight / scaledHeight))
114
-
115
- // Calculate source pixel index in the original image
116
- const srcIndex = (srcY * originalWidth + srcX) * 4
117
-
118
- // Calculate target pixel index in the atlas texture
119
- const atlasIndex = ((atlasY + y) * atlasSize + (atlasX + x)) * 4
120
-
121
- // Copy RGBA values from source to atlas
122
- atlasData[atlasIndex] = imageData.data[srcIndex] ?? 0 // Red channel
123
- atlasData[atlasIndex + 1] = imageData.data[srcIndex + 1] ?? 0 // Green channel
124
- atlasData[atlasIndex + 2] = imageData.data[srcIndex + 2] ?? 0 // Blue channel
125
- atlasData[atlasIndex + 3] = imageData.data[srcIndex + 3] ?? 255 // Alpha channel
126
- }
127
- }
128
- }
129
-
130
- // Return the complete atlas data
131
- return {
132
- atlasData,
133
- atlasSize,
134
- atlasCoords,
135
- atlasCoordsSize,
136
- }
137
- }
@@ -1,20 +0,0 @@
1
- #ifdef GL_ES
2
- precision highp float;
3
- #endif
4
-
5
- uniform sampler2D positionsTexture;
6
- uniform vec2 mousePos;
7
- uniform float index;
8
-
9
- varying vec2 textureCoords;
10
-
11
- void main() {
12
- vec4 pointPosition = texture2D(positionsTexture, textureCoords);
13
-
14
- // Check if a point is being dragged
15
- if (index >= 0.0 && index == pointPosition.b) {
16
- pointPosition.rg = mousePos.rg;
17
- }
18
-
19
- gl_FragColor = pointPosition;
20
- }
@@ -1,16 +0,0 @@
1
- precision mediump float;
2
-
3
- uniform float width;
4
-
5
- varying vec2 vertexPosition;
6
- varying float pointOpacity;
7
- varying vec3 rgbColor;
8
-
9
- const float smoothing = 1.05;
10
-
11
- void main () {
12
- float r = dot(vertexPosition, vertexPosition);
13
- float opacity = smoothstep(r, r * smoothing, 1.0);
14
- float stroke = smoothstep(width, width * smoothing, r);
15
- gl_FragColor = vec4(rgbColor, opacity * stroke * pointOpacity);
16
- }
@@ -1,86 +0,0 @@
1
- precision mediump float;
2
-
3
- attribute vec2 vertexCoord;
4
-
5
- uniform sampler2D positionsTexture;
6
- uniform sampler2D pointGreyoutStatusTexture;
7
- uniform float size;
8
- uniform mat3 transformationMatrix;
9
- uniform float pointsTextureSize;
10
- uniform float sizeScale;
11
- uniform float spaceSize;
12
- uniform vec2 screenSize;
13
- uniform bool scalePointsOnZoom;
14
- uniform float pointIndex;
15
- uniform float maxPointSize;
16
- uniform vec4 color;
17
- uniform float universalPointOpacity;
18
- uniform float greyoutOpacity;
19
- uniform bool isDarkenGreyout;
20
- uniform vec4 backgroundColor;
21
- uniform vec4 greyoutColor;
22
- varying vec2 vertexPosition;
23
- varying float pointOpacity;
24
- varying vec3 rgbColor;
25
-
26
- float calculatePointSize(float size) {
27
- float pSize;
28
- if (scalePointsOnZoom) {
29
- pSize = size * transformationMatrix[0][0];
30
- } else {
31
- pSize = size * min(5.0, max(1.0, transformationMatrix[0][0] * 0.01));
32
- }
33
- return min(pSize, maxPointSize);
34
- }
35
-
36
- const float relativeRingRadius = 1.3;
37
-
38
- void main () {
39
- vertexPosition = vertexCoord;
40
-
41
- vec2 textureCoordinates = vec2(mod(pointIndex, pointsTextureSize), floor(pointIndex / pointsTextureSize)) + 0.5;
42
- vec4 pointPosition = texture2D(positionsTexture, textureCoordinates / pointsTextureSize);
43
-
44
- rgbColor = color.rgb;
45
- pointOpacity = color.a * universalPointOpacity;
46
- vec4 greyoutStatus = texture2D(pointGreyoutStatusTexture, textureCoordinates / pointsTextureSize);
47
- if (greyoutStatus.r > 0.0) {
48
- if (greyoutColor[0] != -1.0) {
49
- rgbColor = greyoutColor.rgb;
50
- pointOpacity = greyoutColor.a;
51
- } else {
52
- // If greyoutColor is not set, make color lighter or darker based on isDarkenGreyout
53
- float blendFactor = 0.65; // Controls how much to modify (0.0 = original, 1.0 = target color)
54
-
55
- if (isDarkenGreyout) {
56
- // Darken the color
57
- rgbColor = mix(rgbColor, vec3(0.2), blendFactor);
58
- } else {
59
- // Lighten the color
60
- rgbColor = mix(rgbColor, max(backgroundColor.rgb, vec3(0.8)), blendFactor);
61
- }
62
- }
63
-
64
- if (greyoutOpacity != -1.0) {
65
- pointOpacity *= greyoutOpacity;
66
- }
67
- }
68
-
69
- // Calculate point radius
70
- float pointSize = (calculatePointSize(size * sizeScale) * relativeRingRadius) / transformationMatrix[0][0];
71
- float radius = pointSize * 0.5;
72
-
73
- // Calculate point position in screen space
74
- vec2 a = pointPosition.xy;
75
- vec2 b = pointPosition.xy + vec2(0.0, radius);
76
- vec2 xBasis = b - a;
77
- vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x));
78
- vec2 pointPositionInScreenSpace = a + xBasis * vertexCoord.x + yBasis * radius * vertexCoord.y;
79
-
80
- // Transform point position to normalized device coordinates
81
- vec2 p = 2.0 * pointPositionInScreenSpace / spaceSize - 1.0;
82
- p *= spaceSize / screenSize;
83
- vec3 final = transformationMatrix * vec3(p, 1);
84
-
85
- gl_Position = vec4(final.rg, 0, 1);
86
- }