@fusion.dev/helix 0.0.0-dev → 0.0.3

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 (227) hide show
  1. package/custom-elements.json +5565 -5519
  2. package/dist/accordion/item/accordion-item.css.js +1 -19
  3. package/dist/accordion/root/accordion-root.css.js +1 -1
  4. package/dist/accordion/root/accordion-root.d.ts +1 -1
  5. package/dist/accordion/root/accordion-root.js +1 -1
  6. package/dist/announcement/root/announcement-root.css.js +1 -7
  7. package/dist/app-header/root/app-header-root.css.js +1 -7
  8. package/dist/app-header/root/app-header-root.d.ts +20 -23
  9. package/dist/app-header/root/app-header-root.js +4 -4
  10. package/dist/aura/root/aura-axis.d.ts +5 -7
  11. package/dist/aura/root/aura-axis.js +5 -7
  12. package/dist/aura/root/aura-root.css.js +1 -1
  13. package/dist/aura/root/aura-root.d.ts +75 -87
  14. package/dist/aura/root/aura-root.js +100 -109
  15. package/dist/aura/root/aura-shader.d.ts +10 -13
  16. package/dist/aura/root/aura-shader.js +165 -238
  17. package/dist/avatar/group/avatar-group.css.js +1 -1
  18. package/dist/avatar/root/avatar-root.css.js +1 -1
  19. package/dist/badge/root/badge-root.css.js +1 -13
  20. package/dist/badge/root/badge-root.d.ts +4 -5
  21. package/dist/bar-chart/root/bar-chart-root.css.js +1 -13
  22. package/dist/bar-chart/root/bar-chart-root.d.ts +51 -60
  23. package/dist/bar-chart/root/bar-chart-root.js +10 -17
  24. package/dist/blockquote/root/blockquote-root.css.js +1 -1
  25. package/dist/breadcrumbs/breadcrumb/breadcrumb.css.js +1 -7
  26. package/dist/breadcrumbs/root/breadcrumbs-root.css.js +1 -1
  27. package/dist/button/root/button-root.css.js +1 -7
  28. package/dist/button/root/button-root.d.ts +16 -25
  29. package/dist/button/root/button-root.js +3 -3
  30. package/dist/button-group/root/button-group-root.css.js +1 -1
  31. package/dist/button-group/root/button-group-root.d.ts +5 -7
  32. package/dist/callout/root/callout-root.css.js +1 -1
  33. package/dist/callout/root/callout-root.d.ts +4 -4
  34. package/dist/callout/root/callout-root.js +4 -4
  35. package/dist/card/root/card-root.css.js +2 -2
  36. package/dist/card/root/card-root.d.ts +38 -48
  37. package/dist/card/root/card-root.js +8 -11
  38. package/dist/carousel/root/carousel-root.css.js +1 -11
  39. package/dist/carousel/root/carousel-root.d.ts +39 -43
  40. package/dist/carousel/root/carousel-root.js +7 -7
  41. package/dist/chat/composer/chat-composer.css.js +1 -1
  42. package/dist/chat/message/chat-message.css.js +1 -7
  43. package/dist/chat/message/chat-message.d.ts +8 -13
  44. package/dist/chat/root/chat-root.css.js +1 -1
  45. package/dist/checkbox/root/checkbox-root.css.js +1 -14
  46. package/dist/checkbox-group/root/checkbox-group-root.css.js +1 -1
  47. package/dist/code/root/code-root.css.js +9 -7
  48. package/dist/code/root/code-root.d.ts +4 -0
  49. package/dist/code/root/code-root.js +4 -0
  50. package/dist/code-block/root/code-block-root.css.js +1 -1
  51. package/dist/color-input/root/color-input-root.css.js +2 -2
  52. package/dist/color-input/root/color-input-root.js +3 -3
  53. package/dist/color-picker/root/color-picker-root.css.js +1 -9
  54. package/dist/color-picker/root/color-picker-root.js +3 -3
  55. package/dist/combobox/root/combobox-root.css.js +1 -8
  56. package/dist/combobox/root/combobox-root.js +1 -1
  57. package/dist/command/root/command-root.css.js +1 -1
  58. package/dist/copy-button/root/copy-button-root.css.js +1 -1
  59. package/dist/data-table/root/data-table-root.css.js +9 -3
  60. package/dist/data-table/root/data-table-root.d.ts +4 -1
  61. package/dist/data-table/root/data-table-root.js +4 -1
  62. package/dist/date-input/root/date-input-root.css.js +1 -1
  63. package/dist/date-picker/root/date-picker-root.css.js +1 -7
  64. package/dist/date-picker/root/date-picker-root.d.ts +1 -1
  65. package/dist/date-picker/root/date-picker-root.js +1 -1
  66. package/dist/dialog/root/dialog-root.css.js +1 -1
  67. package/dist/dialog/root/dialog-root.d.ts +15 -20
  68. package/dist/dialog/root/dialog-root.js +2 -2
  69. package/dist/divider/root/divider-root.css.js +1 -1
  70. package/dist/donut-chart/root/donut-chart-root.css.js +2 -20
  71. package/dist/donut-chart/root/donut-chart-root.d.ts +14 -19
  72. package/dist/donut-chart/root/donut-chart-root.js +6 -7
  73. package/dist/drawer/root/drawer-root.css.js +1 -11
  74. package/dist/drawer/root/drawer-root.d.ts +3 -7
  75. package/dist/drilldown/item/drilldown-item.css.js +1 -1
  76. package/dist/drilldown/root/drilldown-root.css.js +1 -1
  77. package/dist/element-events.generated.js +1 -1
  78. package/dist/empty/root/empty-root.css.js +1 -1
  79. package/dist/file-input/root/file-input-root.css.js +1 -1
  80. package/dist/file-input/root/file-input-root.js +1 -2
  81. package/dist/flex/root/flex-root.css.js +1 -1
  82. package/dist/flex/root/flex-root.d.ts +6 -6
  83. package/dist/flex/root/flex-root.js +9 -9
  84. package/dist/format-date/root/format-date-root.css.js +1 -1
  85. package/dist/grid/root/grid-root.css.js +1 -1
  86. package/dist/grid/root/grid-root.d.ts +8 -8
  87. package/dist/grid/root/grid-root.js +8 -9
  88. package/dist/heatmap/root/heatmap-root.css.js +2 -2
  89. package/dist/heatmap/root/heatmap-root.d.ts +11 -12
  90. package/dist/heatmap/root/heatmap-root.js +11 -12
  91. package/dist/icon/glyph.css.js +1 -1
  92. package/dist/icon/root/icon-root.css.js +1 -1
  93. package/dist/icon-button/root/icon-button-root.css.js +1 -7
  94. package/dist/icon-button/root/icon-button-root.d.ts +10 -10
  95. package/dist/icon-button/root/icon-button-root.js +4 -4
  96. package/dist/image/root/image-root.css.js +1 -7
  97. package/dist/input/root/input-root.css.js +1 -9
  98. package/dist/kbd/root/kbd-root.css.js +1 -1
  99. package/dist/legend/root/legend-root.css.js +1 -1
  100. package/dist/legend/root/legend-root.d.ts +34 -37
  101. package/dist/legend/root/legend-root.js +10 -10
  102. package/dist/line-chart/root/line-chart-root.css.js +1 -8
  103. package/dist/line-chart/root/line-chart-root.d.ts +6 -9
  104. package/dist/list/item/list-item.css.js +1 -1
  105. package/dist/list/root/list-root.css.js +1 -1
  106. package/dist/list/root/list-root.d.ts +4 -7
  107. package/dist/listbox/root/listbox-root.css.js +3 -3
  108. package/dist/listbox/root/listbox-root.d.ts +2 -0
  109. package/dist/listbox/root/listbox-root.js +2 -0
  110. package/dist/loader/root/loader-root.css.js +1 -1
  111. package/dist/loader/root/loader-root.d.ts +5 -9
  112. package/dist/loader/root/loader-root.js +2 -2
  113. package/dist/megamenu/root/megamenu-root.css.js +3 -2
  114. package/dist/menu/item/menu-item.css.js +1 -7
  115. package/dist/menu/root/menu-root.css.js +1 -1
  116. package/dist/meter/root/meter-root.css.js +1 -14
  117. package/dist/meter/root/meter-root.d.ts +18 -18
  118. package/dist/meter/root/meter-root.js +6 -8
  119. package/dist/mixins/mixin-control-surface/mixin-control-surface.d.ts +1 -1
  120. package/dist/navigation/root/navigation-root.css.js +1 -7
  121. package/dist/notifications/notification/notification.css.js +1 -7
  122. package/dist/notifications/root/notifications-root.css.js +1 -1
  123. package/dist/number-input/root/number-input-root.css.js +1 -9
  124. package/dist/option/group/option-group.css.js +1 -1
  125. package/dist/option/root/option-root.css.js +1 -1
  126. package/dist/outline/root/outline-root.css.js +1 -14
  127. package/dist/outline/root/outline-root.d.ts +1 -1
  128. package/dist/outline/root/outline-root.js +1 -1
  129. package/dist/pagination/root/pagination-root.css.js +1 -12
  130. package/dist/pagination/size/pagination-size.css.js +1 -1
  131. package/dist/pagination/summary/pagination-summary.css.js +1 -1
  132. package/dist/pin-input/root/pin-input-root.css.js +1 -7
  133. package/dist/popover/root/popover-root.css.js +4 -2
  134. package/dist/progress/root/progress-root.css.js +1 -7
  135. package/dist/progress/root/progress-root.d.ts +10 -9
  136. package/dist/qr-code/root/qr-code-root.css.js +1 -1
  137. package/dist/qr-code/root/qr-code-root.d.ts +1 -1
  138. package/dist/qr-code/root/qr-code-root.js +1 -1
  139. package/dist/quote/root/quote-root.css.js +1 -1
  140. package/dist/radio/group/radio-group.css.js +1 -1
  141. package/dist/radio/root/radio-root.css.js +1 -14
  142. package/dist/radio/root/radio-root.d.ts +20 -18
  143. package/dist/radio/root/radio-root.js +5 -6
  144. package/dist/rating/root/rating-root.css.js +1 -1
  145. package/dist/rating/root/rating-root.d.ts +4 -5
  146. package/dist/sandbox/preview/sandbox-preview.css.js +1 -1
  147. package/dist/sandbox/preview/sandbox-preview.d.ts +48 -44
  148. package/dist/sandbox/preview/sandbox-preview.js +63 -50
  149. package/dist/sandbox/root/sandbox-root.css.js +1 -2
  150. package/dist/sandbox/root/sandbox-root.d.ts +50 -59
  151. package/dist/sandbox/root/sandbox-root.js +75 -91
  152. package/dist/sandbox/source/sandbox-source.css.js +1 -1
  153. package/dist/sandbox/source/sandbox-source.d.ts +21 -29
  154. package/dist/sandbox/source/sandbox-source.js +26 -34
  155. package/dist/sandbox/status-bar/sandbox-status-bar.css.js +1 -1
  156. package/dist/sandbox/terminal/sandbox-terminal.css.js +1 -1
  157. package/dist/sandbox/toolbar/sandbox-toolbar.css.js +1 -1
  158. package/dist/scroll-area/root/scroll-area-root.css.js +5 -5
  159. package/dist/select/root/select-root.css.js +2 -15
  160. package/dist/select/root/select-root.d.ts +4 -4
  161. package/dist/select/root/select-root.js +5 -7
  162. package/dist/shared/chart/series.css.js +1 -1
  163. package/dist/shared/chart/terminus.css.js +1 -1
  164. package/dist/shared/field/field-inline.css.js +1 -1
  165. package/dist/shared/field/field-stacked.css.js +1 -1
  166. package/dist/shared/field/field.css.js +1 -1
  167. package/dist/skeleton/root/skeleton-root.css.js +1 -1
  168. package/dist/slider/root/slider-root.css.js +1 -3
  169. package/dist/sparkline/root/sparkline-root.css.js +1 -1
  170. package/dist/sparkline/root/sparkline-root.d.ts +22 -24
  171. package/dist/sparkline/root/sparkline-root.js +6 -6
  172. package/dist/speed-dial/item/speed-dial-item.css.js +1 -7
  173. package/dist/speed-dial/root/speed-dial-root.css.js +1 -1
  174. package/dist/splitter/root/splitter-root.css.js +1 -14
  175. package/dist/stat/group/stat-group.css.js +1 -1
  176. package/dist/stat/root/stat-root.css.js +1 -1
  177. package/dist/steps/root/steps-root.css.js +1 -1
  178. package/dist/steps/step/step.css.js +1 -8
  179. package/dist/steps/step/step.js +1 -1
  180. package/dist/switch/root/switch-root.css.js +1 -8
  181. package/dist/table/cell/table-cell.css.js +1 -1
  182. package/dist/table/column/table-column.css.js +1 -1
  183. package/dist/table/root/table-root.css.js +1 -1
  184. package/dist/table/row/table-row.css.js +1 -1
  185. package/dist/tabs/panel/tab-panel.css.js +1 -1
  186. package/dist/tabs/root/tabs-root.css.js +1 -7
  187. package/dist/tabs/tab/tab.css.js +2 -8
  188. package/dist/tag/root/tag-root.css.js +1 -1
  189. package/dist/tag/root/tag-root.d.ts +10 -19
  190. package/dist/tag/root/tag-root.js +3 -3
  191. package/dist/text/root/text-root.css.js +1 -1
  192. package/dist/text/root/text-root.d.ts +13 -14
  193. package/dist/text/root/text-root.js +6 -6
  194. package/dist/textarea/root/textarea-root.css.js +1 -7
  195. package/dist/time-input/root/time-input-root.css.js +1 -1
  196. package/dist/time-input/root/time-input-root.js +1 -1
  197. package/dist/time-picker/root/time-picker-root.css.js +1 -7
  198. package/dist/time-picker/root/time-picker-root.js +1 -1
  199. package/dist/timeline/item/timeline-item.css.js +1 -1
  200. package/dist/timeline/root/timeline-root.css.js +1 -1
  201. package/dist/toast/item/toast-item.css.js +1 -1
  202. package/dist/toast/root/toast-root.css.js +1 -1
  203. package/dist/toggle/group/toggle-group.css.js +1 -7
  204. package/dist/toggle/group/toggle-group.d.ts +6 -9
  205. package/dist/toggle/root/toggle-root.css.js +1 -1
  206. package/dist/toolbar/root/toolbar-root.css.js +1 -1
  207. package/dist/tooltip/root/tooltip-root.css.js +1 -1
  208. package/dist/tooltip/root/tooltip-root.d.ts +6 -7
  209. package/dist/tour/root/tour-root.css.js +1 -7
  210. package/dist/tour/stop/tour-stop.css.js +2 -2
  211. package/dist/tree/item/tree-item.css.js +1 -17
  212. package/dist/tree/root/tree-root.css.js +1 -1
  213. package/dist/tree/root/tree-root.d.ts +0 -2
  214. package/dist/trend/root/trend-root.css.js +1 -1
  215. package/dist/trend/root/trend-root.d.ts +4 -7
  216. package/dist/trend/root/trend-root.js +4 -7
  217. package/dist/video/root/video-root.css.js +1 -12
  218. package/dist/video/root/video-root.d.ts +3 -8
  219. package/dist/video-playlist/item/video-playlist-item.css.js +1 -7
  220. package/dist/video-playlist/menu/video-playlist-menu.css.js +1 -1
  221. package/dist/video-playlist/root/video-playlist-root.css.js +1 -1
  222. package/dist/virtual-list/root/virtual-list-root.css.js +1 -1
  223. package/elements.css +4 -5
  224. package/helix.css +31 -0
  225. package/jsx.d.ts +11625 -14561
  226. package/package.json +10 -8
  227. package/vue.d.ts +3594 -4231
@@ -21,12 +21,10 @@ export const SHAPES = [
21
21
  * What the pointer does, in the order the shader branches on them.
22
22
  *
23
23
  * `native` is the shape's own, and is what absence means: braid leans, rays are
24
- * occluded, threads pinch. The rest are generic, and deliberately few.
25
- *
26
- * **The generics are the thing this component spent a day removing**, so they
27
- * are opt-in and never a default. A response made of the same material as the
28
- * shape says something about that shape; a lamp that follows the cursor says
29
- * the same nothing on all nine. They are here because a consumer may want the
24
+ * occluded, threads pinch. The rest are generic, deliberately few, opt-in and
25
+ * never a default. A response made of the same material as the shape says
26
+ * something about that shape; a lamp that follows the cursor says the same
27
+ * nothing on every one of them. They are here because a consumer may want the
30
28
  * quieter, more conventional answer, not because it is the better one.
31
29
  */
32
30
  export const INTERACTIONS = ['native', 'light', 'shadow', 'ripple', 'none'];
@@ -45,18 +43,17 @@ export const VERTEX = `#version 300 es
45
43
  }
46
44
  `;
47
45
  /**
48
- * One program, branching on a uniform, for all five shapes.
46
+ * One program, branching on a uniform, for every shape.
49
47
  *
50
48
  * A branch on a uniform is uniform across the whole draw, so every lane takes
51
- * the same path and it costs a jump rather than divergence. Five programs would
52
- * mean compiling and linking on a property change, which is the one moment a
53
- * reader is watching.
49
+ * the same path and it costs a jump rather than divergence. A program per shape
50
+ * would mean compiling and linking on a property change, which is the one
51
+ * moment a reader is watching.
54
52
  *
55
53
  * **No backticks anywhere inside this string, including in comments.** One ends
56
54
  * the template literal early, and what follows is parsed as JavaScript: it has
57
55
  * silently stripped every brace out of a shader and left the driver reporting a
58
- * syntax error two hundred lines from the cause. `bun run check:shaders` fails
59
- * the build on it.
56
+ * syntax error two hundred lines from the cause. The build fails on it.
60
57
  */
61
58
  export const FRAGMENT = `#version 300 es
62
59
  precision highp float;
@@ -78,10 +75,10 @@ export const FRAGMENT = `#version 300 es
78
75
  /* How much the members of a population differ from one another, 1 being the
79
76
  resting amount and 0 a set that is uniform. Read by the shapes made of many
80
77
  similar things, whether those are counted or continuous: streaks has lanes,
81
- particles has motes, rays has a fan, and aurora has bundles and folds. Braid, waves and flow have a single subject and nothing to vary.
82
- Threads is the deliberate exception, being even on purpose: a pass had
83
- already given its strands their own hashes and produced a scatter rather
84
- than a set. */
78
+ particles has motes, rays has a fan, and aurora has bundles and folds.
79
+ Braid, waves and flow have a single subject and nothing to vary. Threads is
80
+ the deliberate exception, being even on purpose: strands given their own
81
+ hashes are a scatter rather than a set. */
85
82
  uniform float uVariance;
86
83
  /* Where the pointer has been, as x, y and age. Age runs 0 at the moment it
87
84
  was left to 1 when it has faded, so a spent slot costs a compare.
@@ -191,14 +188,11 @@ export const FRAGMENT = `#version 300 es
191
188
 
192
189
  /* A fan from a source above the frame, cut into filaments by angle. */
193
190
  float rays(vec2 q, float t, vec2 qp, float reach) {
194
- /* The pointer occludes, rather than the source moving.
195
-
196
- Swinging the source re-aimed the whole fan, which is a thing a light does
197
- and not a thing that happens when something passes in front of one. What
198
- a reader knows about rays is that an object crossing them takes a bite
199
- out of the light and drags a shadow behind itself, away from the source.
200
- So the source is fixed and the pointer is a blocker.
201
-
191
+ /* The pointer occludes, rather than the source moving. Swinging the source
192
+ re-aims the whole fan, which is a thing a light does and not a thing that
193
+ happens when something passes in front of one, so the source is fixed and
194
+ the pointer is a blocker.
195
+
202
196
  The shadow is angular, not radial: it is the wedge of directions the
203
197
  object covers as seen from the source, and it only exists further along
204
198
  than the object is. A fragment nearer the source than the blocker is in
@@ -245,13 +239,13 @@ export const FRAGMENT = `#version 300 es
245
239
  float agitate = falloff((q.x - qp.x) * (q.x - qp.x), 1.5) * reach;
246
240
 
247
241
  /* A curtain stands. It does not hang.
248
-
249
- This was a falloff symmetric about the ridge, which is a band with a
250
- wavy center line, and a band with vertical noise on it is an equaliser.
251
- An aurora has a sharp lower border where the field lines reach their
252
- lowest, and light that thins upward from it, so the top and the bottom
253
- cannot be the same function. Cut hard below, drawn long above.
254
-
242
+
243
+ A falloff symmetric about the ridge is a band with a wavy center line,
244
+ and vertical noise on a band is an equalizer. An aurora has a sharp lower
245
+ border where the field lines reach their lowest and light that thins
246
+ upward from it, so the top and the bottom cannot be the same function:
247
+ cut hard below, drawn long above.
248
+
255
249
  Two of them, offset and at different depths, because a single sheet reads
256
250
  as a decal and what makes the real thing look like drapery is one curtain
257
251
  seen through another. */
@@ -270,35 +264,29 @@ export const FRAGMENT = `#version 300 es
270
264
  f * 0.22;
271
265
  /* **The sheet stands on the ridge rather than hanging from it, and that
272
266
  inversion is the whole difference between an aurora and a landscape.**
273
- A hard edge with mass under it is a mountain silhouette, which is
274
- exactly what this drew: one unbroken ridge line across the frame with a
275
- striped solid below it. The real thing is the other way up. A curtain's
267
+ A hard edge with mass under it is a mountain silhouette: one unbroken
268
+ ridge line across the frame with a striped solid below it. A curtain's
276
269
  lower border is its sharpest, brightest line, and what rises from it
277
- thins and breaks into rays. Nothing else here had to change. */
270
+ thins and breaks into rays. */
278
271
  float depth = q.y - ridge;
279
272
  /* Sharp, but not a cliff: the edge is where the light stops, and a step
280
- narrower than a pixel is an aliased line rather than an edge. */
281
- /* **The border's sharpness varies along it.** One constant made one
282
- continuously crisp line across the whole curtain, and a line of even
283
- weight reads as drawn rather than lit however it wanders. A real lower
284
- border is hard where the
285
- sheet faces us and diffuse where it turns away, so the crispness is
286
- drawn from the same slow noise the folds are. */
273
+ narrower than a pixel is an aliased line rather than an edge.
274
+
275
+ **The border's sharpness varies along it.** A line of even weight reads
276
+ as drawn rather than lit however it wanders. A real lower border is
277
+ hard where the sheet faces us and diffuse where it turns away, so the
278
+ crispness is drawn from the same slow noise the folds are. */
287
279
  float crisp = mix(0.04, 0.3, noise(vec2(q.x * 0.8 + f * 5.0, t * 0.15)));
288
280
  float edge = smoothstep(-crisp, crisp * 0.5, depth);
289
- /* Steeper, so the curtain thins instead of filling everything above the
281
+ /* Steep, so the curtain thins instead of filling everything above the
290
282
  border. At 1.5 it still stood at a fifth a whole unit up, which with
291
283
  the bundles over it painted a solid wall of stripes from the border to
292
- the top of the frame: the dark under a hard line then read as a hill
293
- and the light over it as rain. A curtain is mostly the bottom of a
294
- curtain. */
284
+ the top of the frame. A curtain is mostly the bottom of a curtain. */
295
285
  float rise = exp(-max(depth, 0.0) * (2.9 + f * 1.1));
296
- /* Stretched hard along the fall, so the striations are the vertical rays
297
- a curtain is actually made of rather than texture on a stripe. */
298
- /* 0.9 along the fall, not 0.35. Stretched that hard the rays held one
299
- value for their whole length, which is a picket fence however the
300
- bundles are shaped: what varies along a ray is the thing that makes it
301
- look like moving light rather than a printed stripe. */
286
+ /* Stretched along the fall, so the striations are the vertical rays a
287
+ curtain is actually made of rather than texture on a stripe. Not
288
+ stretched harder than this: at 0.35 a ray held one value for its whole
289
+ length, which is a picket fence however the bundles are shaped. */
302
290
  float rays = fbm(vec2(q.x * (9.0 + f * 4.0), q.y * 0.9 - t * (2.2 + f)));
303
291
 
304
292
  /* A rim along the top edge. The brightest part of a curtain is the line
@@ -341,8 +329,7 @@ export const FRAGMENT = `#version 300 es
341
329
  *
342
330
  * The one shape here that is about motion rather than about a form. Each lane
343
331
  * carries a trail with its own speed, length and phase, so the field reads as
344
- * something passing rather than something standing: the streaks the earlier
345
- * ground plane wanted and never got.
332
+ * something passing rather than something standing.
346
333
  *
347
334
  * The wrap is deliberately outside the frame. A trail restarting is a pop, so
348
335
  * the travel runs to plus and minus 1.8 while the visible field ends nearer
@@ -358,7 +345,7 @@ export const FRAGMENT = `#version 300 es
358
345
  vec2 s = q + vec2((q.x - qp.x) * near * 1.1, 0.0);
359
346
 
360
347
  /* Three lanes are visited, not one, and that is the fix for a square edge.
361
-
348
+
362
349
  Each lane draws its speed, phase and length from a hash of its index, so
363
350
  every one of them is at a different point in its cycle. Sampled from the
364
351
  single lane a fragment falls in, the whole strip changes state at the
@@ -366,18 +353,15 @@ export const FRAGMENT = `#version 300 es
366
353
  measured at 23 straight edges across the frame, and at a tilt of 90 the
367
354
  same count arrives horizontal, which is what says they belong to the
368
355
  shape's own axes rather than to the screen.
369
-
370
- Visiting the neighbours and weighting each by its own distance is the
371
- same answer particles already uses for the same reason. The weight
372
- reaches zero between centres, so nothing is left to step. */
373
- /* **Fewer lanes, and not all of them carry anything.** At 2.4 a frame held
374
- a dozen streaks at once and read as rain: a streak is an event, and a
375
- field of simultaneous events is a texture. Sixteen hundredths of the
376
- lanes and a little over half of those alive puts the count at about
377
- two fifths of what it was.
378
-
379
- A dead lane contributes nothing anywhere rather than being cut off
380
- somewhere, so it costs the three lane blend nothing. */
356
+
357
+ Visiting the neighbors and weighting each by its own distance is the same
358
+ answer particles already uses for the same reason. The weight reaches
359
+ zero between centers, so nothing is left to step.
360
+
361
+ **Few lanes, and not all of them carry anything.** A streak is an event,
362
+ and a field of simultaneous events is a texture. A dead lane contributes
363
+ nothing anywhere rather than being cut off somewhere, so it costs the
364
+ three lane blend nothing. */
381
365
  float laneF = s.x * 1.6;
382
366
  float base = floor(laneF);
383
367
 
@@ -391,54 +375,47 @@ export const FRAGMENT = `#version 300 es
391
375
  float id = base + float(k);
392
376
  float within = laneF - (id + 0.5);
393
377
 
394
- /* Speed and length were already drawn per lane, and measure a little over
395
- four times and seventy times across a frame. What was not drawn was
396
- width, which came out flat at 47 to 53 pixels on every lane, so a set
397
- that moved variously was still a set of identical objects.
398
-
399
- All four now scale from a common resting value, so a variance of 0 is a
400
- rank of equal streaks at one speed rather than a special case. Phase is
401
- never scaled: lanes sharing a phase march in lockstep, which is not a
402
- uniform population but a broken one. */
403
- /* Clamped, and the upper half of that is not defensive tidying. These
404
- are mix() calls, so a value past 1 extrapolates rather than
405
- exaggerating: at 1.6 the length term reaches zero and beyond it goes
406
- negative, which makes exp(-behind / len) grow instead of decay and the
407
- lane becomes a full-height white bar. Measured at 2, the frame held 93
408
- apparent lanes and six straight edges. There is nothing above 1 worth
409
- reaching, the resting spread already being fourfold in speed. */
378
+ /* Speed, length, width and spacing all scale from a common resting value,
379
+ so a variance of 0 is a rank of equal streaks at one speed rather than
380
+ a special case. Phase is never scaled: lanes sharing a phase march in
381
+ lockstep, which is not a uniform population but a broken one.
382
+
383
+ Clamped, and the upper half of that is not defensive tidying. These are
384
+ mix() calls, so a value past 1 extrapolates rather than exaggerating:
385
+ at 1.6 the length term reaches zero and beyond it goes negative, which
386
+ makes exp(-behind / len) grow instead of decay and the lane becomes a
387
+ full-height white bar. Measured at 2, the frame held 93 apparent lanes
388
+ and six straight edges. There is nothing above 1 worth reaching, the
389
+ resting spread already being fourfold in speed. */
410
390
  float v = clamp(uVariance, 0.0, 1.0);
411
391
  float alive = step(0.42, hash(vec2(id, 97.0)));
412
392
  float speed = mix(1.3, 0.55 + hash(vec2(id, 11.0)) * 1.5, v);
413
393
  float phase = hash(vec2(id, 29.0));
414
- /* Longer than they were. At 0.3 to 1.3 the tail was spent within about
415
- half the gap and each streak read as a blob with a smudge behind it;
416
- the thing is named for the trail, so the trail is the part that should
417
- dominate the head. */
418
- /* Shorter than it was. A plume that stays bright for two and a half
419
- units is a searchlight: the frame is two units tall. */
394
+ /* Long enough that the trail dominates the head, which is what the shape
395
+ is named for, and no longer: a plume that stays bright for two and a
396
+ half units is a searchlight, and the frame is two units tall. */
420
397
  float len = mix(0.85, 0.5 + hash(vec2(id, 47.0)) * 0.8, v);
421
398
 
422
399
  /* **The lane is periodic, not a single streak that is put back when it
423
- runs out.** It was fract() over a fixed span of 3.6, so a head left the
424
- top at 1.8 and was moved to -1.8, taking whatever of its tail was still
425
- on screen with it. That span is only off screen while the frame is
426
- small enough to sit inside it, and the visible half-extent is
400
+ runs out.** With fract() over a fixed span of 3.6 a head left the top
401
+ at 1.8 and was moved to -1.8, taking whatever of its tail was still on
402
+ screen with it. That span is only off screen while the frame is small
403
+ enough to sit inside it, and the visible half-extent is
427
404
  (|sin tilt| * aspect + |cos tilt|) * scale, which reaches 1.97 at a
428
405
  tilt of 45 and 2.0 at a scale of 2. Past that the removal happens in
429
406
  plain view, which is the popping.
430
-
407
+
431
408
  Making the field periodic in y removes the event rather than moving it
432
409
  out of sight: heads sit at every integer of u and the whole rank slides
433
410
  through, so there is no frame in which one is created or destroyed and
434
411
  no scale or tilt at which that becomes visible.
435
-
436
- P is the gap between successive heads in a lane, and it is what density
437
- is now made of. It varies too: lanes that are alike in spacing read as
438
- a grid however much else about them differs. */
439
- /* Wider spacing, because the tails are longer: at the old gap a streak's
440
- tail reached the next one's nose and the lane read as a dashed line
441
- rather than as separate things traveling. */
412
+
413
+ The gap is the distance between successive heads in a lane, and it is
414
+ what density is made of. It varies too: lanes alike in spacing read as
415
+ a grid however much else about them differs, and it has to exceed the
416
+ tail length, or a streak's tail reaches the next one's nose and the
417
+ lane reads as a dashed line rather than as separate things
418
+ traveling. */
442
419
  float gap = mix(4.2, 3.2 + hash(vec2(id, 59.0)) * 2.2, v);
443
420
  float travel = phase + t * speed * 1.8 / gap;
444
421
  float u = s.y / gap - travel;
@@ -454,28 +431,24 @@ export const FRAGMENT = `#version 300 es
454
431
  full-width wall cut off across the lane. Together that is a teardrop,
455
432
  which is the silhouette the thing actually has. */
456
433
  float across = within / 1.6;
457
- /* 0.06, which is what the profile it replaces actually measured. Lanes
458
- sit 0.417 apart and the old exp(-|within| * 4) was half-height at 0.072
459
- of a lane, so a sigma of 0.15 was two and a half times too wide: every
460
- lane overlapped both neighbours and the frame came out a blue wash with
461
- no streaks in it at all. */
462
- /* Thinner, and paired with the longer tail below. Length against width is
463
- what makes a streak read as a streak: at a ratio near four these were
464
- stubby rods with rounded ends whichever way they tapered, and the fix
465
- for that is proportion rather than another change of profile. */
434
+ /* Narrow across the lane. Lanes sit 0.417 apart and a sigma of 0.15
435
+ overlapped both neighbors, so the frame came out a blue wash with no
436
+ streaks in it at all. Length against width is what makes a streak read
437
+ as a streak: at a ratio near four these were stubby rods with rounded
438
+ ends whichever way they tapered, and the fix for that is proportion
439
+ rather than another change of profile. */
466
440
  float wide = mix(0.045, 0.03 + hash(vec2(id, 71.0)) * 0.04, v);
467
441
 
468
- /* **A comet is a nucleus with a coma, and a plume behind it.** Neither of
469
- the two shapes this has been was that. A round cap the width of the
470
- body with the body widening behind it drew a bulb on a shaft; tapering
471
- the front instead drew a hairline that reads as a scratch. The fault
472
- common to both is that the head glow was computed from the distance
473
- *in front of* a head only, so there was never a round bright thing at
474
- the head at all, just where the profile happened to start.
475
-
476
- The glow is centered on the head now, measured to whichever head is
477
- nearer along the lane, so it is symmetric about the nucleus the way a
478
- coma is. */
442
+ /* **A comet is a nucleus with a coma, and a plume behind it.** A round
443
+ cap the width of the body with the body widening behind it draws a bulb
444
+ on a shaft; tapering the front instead draws a hairline that reads as a
445
+ scratch. The fault common to both is a head glow computed from the
446
+ distance *in front of* a head only, which never puts a round bright
447
+ thing at the head at all.
448
+
449
+ The glow is centered on the head, measured to whichever head is nearer
450
+ along the lane, so it is symmetric about the nucleus the way a coma
451
+ is. */
479
452
  float behind = (1.0 - w) * gap;
480
453
  float ahead = w * gap;
481
454
  float toHead = min(ahead, behind);
@@ -543,16 +516,15 @@ export const FRAGMENT = `#version 300 es
543
516
  vec2 w = q + warp * 0.32;
544
517
 
545
518
  /* Two systems crossing, lit where they agree, which is what the shape is
546
- named for and what it had stopped doing. One sine is a corrugation; two
547
- at different angles interfere, and the slow beat between them is the
548
- thing worth looking at. */
549
- /* **And the frequency was too low to be a wave at all.** At 2.3 the period
550
- is 2.7 in shape units against a visible half height of 1, so less than
551
- one crest fitted across the frame: there was nothing periodic to see, and
552
- every version of this that looked like anything looked like it because
553
- the warp was making clouds. Around 8 puts five crests across the frame,
554
- which is a wave field rather than a single swell.
555
-
519
+ named for.
520
+
521
+ **And the frequency has to be high enough to be a wave at all.** At 2.3
522
+ the period is 2.7 in shape units against a visible half height of 1, so
523
+ less than one crest fitted across the frame: there was nothing periodic
524
+ to see, and every version of this that looked like anything looked like
525
+ it because the warp was making clouds. Around 8 puts five crests across
526
+ the frame, which is a wave field rather than a single swell.
527
+
556
528
  The two are deliberately not harmonic. Close but unequal frequencies beat
557
529
  against each other, and the slow traveling interference that produces is
558
530
  the thing worth watching. */
@@ -592,13 +564,13 @@ export const FRAGMENT = `#version 300 es
592
564
  float gather = 1.0 - falloff((q.x - pinchAt) * (q.x - pinchAt), 1.1) * 0.6;
593
565
 
594
566
  /* Seven, and every one of them the same thread.
595
-
596
- The pass before this gave each its own amplitude, height, thickness and
597
- brightness, all from hashes, and the result was a scatter rather than a
598
- set: seven unrelated squiggles that happened to share a frame. What makes
599
- a weave read as a weave is that the strands are alike and only their
600
- phase differs, which is also what makes it a wave rather than a wobble.
601
-
567
+
568
+ What makes a weave read as a weave is that the strands are alike and only
569
+ their phase differs, which is also what makes it a wave rather than a
570
+ wobble. Given its own amplitude, height, thickness and brightness from
571
+ hashes, each becomes one of seven unrelated squiggles that happen to
572
+ share a frame.
573
+
602
574
  So one amplitude, one thickness, one weight, one frequency, and the
603
575
  phases fanned evenly across a turn. Alike, they cross at regular
604
576
  intervals instead of at coincidences. */
@@ -609,9 +581,8 @@ export const FRAGMENT = `#version 300 es
609
581
 
610
582
  /* Evenly spaced, and the spacing collapses at the pinch along with the
611
583
  amplitude: threads that only narrow still run parallel through it,
612
- where threads that also converge actually gather. */
613
- /* The spacing closes less than the amplitude does, so the threads draw
614
- together without stacking. */
584
+ where threads that also converge actually gather. It closes less than
585
+ the amplitude does, so they draw together without stacking. */
615
586
  float lane = (f - 3.0) * 0.17 * mix(1.0, gather, 0.65);
616
587
  float amp = 0.34 * gather;
617
588
 
@@ -636,7 +607,7 @@ export const FRAGMENT = `#version 300 es
636
607
  *
637
608
  * One per cell of a coarse lattice, jittered off center so the lattice never
638
609
  * shows, and drifting on its own small orbit. Nine cells are visited because a
639
- * point near a boundary has to be drawn by its neighbours too, which is what
610
+ * point near a boundary has to be drawn by its neighbors too, which is what
640
611
  * stops them popping in and out at the seams.
641
612
  *
642
613
  * The pointer repels. Pushing along the offset rather than by its sign keeps
@@ -663,25 +634,23 @@ export const FRAGMENT = `#version 300 es
663
634
  at += away * push * 0.55;
664
635
 
665
636
  vec2 off = q - at;
666
- /* Size, which was flat at 52 for every mote, so a field whose members
667
- already differed in brightness and in how fast they wandered was
668
- still made of one object repeated. Nine cells are visited here, so
669
- unlike a streak lane a mote may be broader as well as tighter
670
- without leaving an edge anywhere. */
637
+ /* Size varies with the rest, or a field whose members already differed
638
+ in brightness and in how fast they wandered is still made of one
639
+ object repeated. Nine cells are visited here, so unlike a streak lane
640
+ a mote may be broader as well as tighter without leaving an edge
641
+ anywhere. */
671
642
  float grade = mix(52.0, 52.0 * (0.62 + hash(c + 5.7) * 0.95), v);
672
643
 
673
- /* **Round, because a particle is round.** These were stretched two and a
674
- half times along a direction drawn per mote, on the reasoning that a
675
- starfield says nothing because stars are fixed. That was a problem
676
- nobody had, and the cure was worse: a fixed axis per mote is not
677
- motion, it is orientation, so a field of them reads as grains of rice
678
- pointing every which way rather than as particles at all. Motion, if
679
- it is ever wanted here, has to come from the direction each mote is
680
- actually traveling, and that is the wander below rather than a hash.
681
-
644
+ /* **Round, because a particle is round.** Stretching a mote along a
645
+ direction drawn per mote is not motion, it is orientation, so a field
646
+ of them reads as grains of rice pointing every which way rather than
647
+ as particles at all. Motion, if it is ever wanted here, has to come
648
+ from the direction each mote is actually traveling, which is the
649
+ wander above rather than a hash.
650
+
682
651
  The halo stays. An order of magnitude wider and a tenth the strength,
683
652
  so a mote sits in the field rather than on top of it: a hard little
684
- disc on a dark ground is a pixel, and light has a neighbourhood. */
653
+ disc on a dark ground is a pixel, and light has a neighborhood. */
685
654
  float core = falloff(dot(off, off), grade);
686
655
  float halo = falloff(dot(off, off), grade * 0.16) * 0.1;
687
656
  lit += (core + halo) * mix(0.8, 0.35 + a * 0.9, v);
@@ -692,12 +661,12 @@ export const FRAGMENT = `#version 300 es
692
661
 
693
662
  /* Ink in a viscous medium, drawn through by where the pointer went.
694
663
  *
695
- * **The wake is one stroke, not eight marks.** Each trail point used to add a
696
- * vortex of its own, rotating the sample around its own center, which drew
697
- * eight discrete swirls fading in place: a row of blobs rather than anything
698
- * a hand had done. The marks are a polyline now. Distance is measured to the
699
- * nearest *segment*, age is interpolated along it, and what a reader sees is
700
- * a continuous stroke however far apart the samples fell.
664
+ * **The wake is one stroke, not eight marks.** A vortex per trail point,
665
+ * rotating the sample around its own center, draws eight discrete swirls fading
666
+ * in place: a row of blobs rather than anything a hand had done. The marks are
667
+ * a polyline. Distance is measured to the nearest *segment*, age is
668
+ * interpolated along it, and what a reader sees is a continuous stroke however
669
+ * far apart the samples fell.
701
670
  *
702
671
  * **And the displacement runs along the stroke, not around it.** Pushing the
703
672
  * sample down the tangent is advection: the pattern is carried the way the
@@ -762,7 +731,7 @@ export const FRAGMENT = `#version 300 es
762
731
  /* Limited, because an unbounded displacement folds and a fold is a crease.
763
732
 
764
733
  Where the map from sample to displaced sample stops being one to one,
765
- neighbouring samples land on the same value and the pattern piles into a
734
+ neighboring samples land on the same value and the pattern piles into a
766
735
  hard bright line: a caustic, which is what a sharp diagonal with a bright
767
736
  wedge beside it always is. The sum runs over eight segments of unit
768
737
  tangents, so near the stroke it reached several times the width of the
@@ -785,52 +754,40 @@ export const FRAGMENT = `#version 300 es
785
754
 
786
755
  /* The field is warped by itself twice over, which is what gives a liquid
787
756
  its folded look: each sample is displaced by the field's own value, so
788
- structure gathers into sheets rather than staying a cloud. */
789
- /* **Halved, because the detail was the problem.** At 1.15 and 2.3 every
757
+ structure gathers into sheets rather than staying a cloud.
758
+
759
+ Big shapes first, detail on top of them. At twice these frequencies every
790
760
  octave landed small enough that the frame filled edge to edge with fine
791
761
  crumple at one density: marbled stone, and it looked the same at every
792
762
  scale, gain and bloom because there was no large form for any of them to
793
- act on. Big shapes first, detail on top of them. */
794
- /* *The directional pass is reverted.* Sampling the ink stretched along a
795
- slow angle field did make filaments, and it made the shape busier and
796
- more literal than the soft masses it replaced. Preferred as it was, so it
797
- is as it was. The finding is worth keeping even though the code is not:
798
- isotropic noise cannot make a current, so anything wanting one has to
763
+ act on.
764
+
765
+ Isotropic noise cannot make a current, so anything wanting one has to
799
766
  carry a direction, and that is a bigger change than this shape wants. */
800
767
  float ink = warped(p * 0.55, t * 0.55);
801
768
  float sheet = warped(p * 1.1 + vec2(3.1, 1.7), t * 0.35);
802
769
 
803
- /* **Floors of 0.55 and 0.5 meant it was never dark anywhere.** The lowest
804
- the field could reach was a quarter lit, so every fragment landed in the
805
- same middle band and the frame came out an even swatch of texture with no
806
- structure to look at. Dropping the floor gives it voids.
807
-
808
- And a slow large mass over the top, so the liquid is thick in places and
809
- clear in others. Fine detail everywhere at one density is static; what
810
- makes a fluid read is that it gathers. */
811
- /* Thresholded, not just varied. A gentle modulation over a field that is
812
- lit everywhere is still lit everywhere; what a liquid needs is somewhere
813
- it simply is not, so the empty parts of the frame are what give the full
814
- parts a shape. */
770
+ /* Voids, not an even swatch. With a floor under each term the lowest the
771
+ field can reach is a quarter lit, so every fragment lands in the same
772
+ middle band and there is no structure to look at.
773
+
774
+ And a slow large mass over the top, thresholded rather than merely
775
+ varied: a gentle modulation over a field that is lit everywhere is still
776
+ lit everywhere, and what a liquid needs is somewhere it simply is not.
777
+ The empty parts of the frame are what give the full parts a shape. */
815
778
  float mass = smoothstep(0.24, 0.72, noise(vec2(p.x * 0.45 - t * 0.1, p.y * 0.4 + t * 0.07)));
816
- /* The void floor is 0.18 rather than 0.05. At a low scale the mass noise
817
- varies less across the frame than the frame is wide, so a reader can land
818
- inside one void and see nothing at all: empty has to mean faint, not
819
- absent, or the shape can disappear entirely at a setting the property
820
- explicitly allows. */
821
- /* 0.28 rather than 0.18 under the voids, and a brighter ceiling. At a low
822
- scale the mass noise varies less across the frame than the frame is wide,
823
- so a reader can sit inside one void and see almost nothing: measured at
824
- scale 0.5, which came out near black. Empty has to mean faint. */
779
+ /* The void floor sits well above zero. At a low scale the mass noise varies
780
+ less across the frame than the frame is wide, so a reader can sit inside
781
+ one void and see almost nothing: measured at scale 0.5, which came out
782
+ near black. Empty has to mean faint, not absent, or the shape can
783
+ disappear entirely at a setting the property explicitly allows. */
825
784
  float body = mix(0.05, 1.4, ink) * mix(0.4, 1.2, sheet) * mix(0.22, 1.45, mass);
826
785
 
827
786
  /* The resting state matters more than the stirred one: most readers never
828
787
  move the pointer, and a shape that is dark until touched is a shape most
829
- people never see. */
830
- /* 0.85 at rest, not 0.5. Halving an untouched field made sense when the
831
- field had a floor under it and could not go dark; with the voids in, the
832
- two together took it to a dim murk that read as wet rock. The wake still
833
- lifts what it touches, from a resting level that is worth looking at. */
788
+ people never see. With the voids in, halving an untouched field takes it
789
+ to a dim murk that reads as wet rock, so the wake lifts from a resting
790
+ level that is already worth looking at. */
834
791
  return body * (0.85 + clamp(wake, 0.0, 1.0) * 0.5) * falloff(dot(q, q), 0.55);
835
792
  }
836
793
 
@@ -838,7 +795,7 @@ export const FRAGMENT = `#version 300 es
838
795
  *
839
796
  * **A caustic is where a wavefront folds, not where it is bright.** Sampling
840
797
  * a noise field and lighting the high parts gives clouds; what makes the
841
- * pattern on a pool floor is that the surface bends light and neighbouring
798
+ * pattern on a pool floor is that the surface bends light and neighboring
842
799
  * rays land on the same spot. The cheap stand-in for that is the *zero* of a
843
800
  * displaced wave sum rather than its peak: 1 - |sum| is thin and bright
844
801
  * exactly where the sum crosses, which is the fold.
@@ -997,39 +954,19 @@ export const FRAGMENT = `#version 300 es
997
954
  falloff(dot(q, q), 0.42);
998
955
  }
999
956
 
1000
- /* Two wave fields crossed, lit where they agree. */
957
+ /* The sampling frame, the shape branch, and the ramp from field to color. */
1001
958
  void main() {
1002
959
  vec2 p = uv * 2.0 - 1.0;
1003
960
  float aspect = uResolution.x / max(uResolution.y, 1.0);
1004
961
  p.x *= aspect;
1005
962
 
1006
- /* What the pointer does, and the two answers this stopped giving.
1007
-
1008
- It multiplied what was already lit, which shows nothing over a dark part
1009
- of the field, so the visible answer to moving the cursor appeared
1010
- wherever the shape happened to be bright rather than where the cursor
1011
- was. Replacing that with a pull toward the pointer fixed the location and
1012
- introduced the second problem: a radial pull is a magnifier, so every
1013
- shape answered a pointer by zooming, and the lift that remained answered
1014
- by glowing. Two gestures, applied identically to six different things,
1015
- neither of which had anything to do with the thing it was applied to.
1016
-
1017
- There is no shared response now. What is left here is parallax, and each
1018
- shape answers for itself below. */
1019
963
  /* **No global response, parallax included.** Every named interaction is a
1020
964
  promise about what the pointer does, and translating the whole field is
1021
965
  not any of them: a consumer asking for a light asked for a light, not for
1022
- a light and a lean. It survived a pass that removed the other two shared
1023
- gestures on the grounds that it was small, and small is not the test.
1024
-
1025
- Measured on threads before removing it, sampling a column band on the far
1026
- side of the frame from the cursor and correlating: 90 pixels of vertical
1027
- travel on a 1224 pixel canvas, seven per cent of the frame, identical
1028
- under native, light, shadow and ripple and zero under none. Whatever the
1029
- pointer was told to do, it also moved everything.
1030
-
1031
- What answers the pointer now is each shape, in the terms it is made of,
1032
- and the three generics for a consumer who asks for one. */
966
+ a light and a lean. Small is not the test.
967
+
968
+ What answers the pointer is each shape, in the terms it is made of, and
969
+ the three generics for a consumer who asks for one. */
1033
970
  vec2 q = p;
1034
971
 
1035
972
  /* **The tilt is an angle on the screen, not in the sampling space.**
@@ -1056,21 +993,11 @@ export const FRAGMENT = `#version 300 es
1056
993
 
1057
994
  float t = uTime * 0.06;
1058
995
 
1059
- /* Each shape answers the pointer in the terms it is made of, and there is
1060
- no shared response left over.
1061
-
1062
- There used to be two, applied to everything: the field was pulled toward
1063
- the cursor, and what was already lit was multiplied over a floor. Those
1064
- are a zoom and a glow, they are the same gesture on every shape, and
1065
- neither says anything about the shape it is on. A braid has a length and
1066
- can lean. Rays have a source and can re-aim. A curtain has a horizon and
1067
- can swell. Rings are made of spacing and can crowd. A weave is made of
1068
- agreement and can shear. Flow is stirred, and had the only one of these
1069
- that was ever about its own material. */
1070
996
  /* A shape answers for itself only when nothing else has been asked for.
1071
997
  Given a generic response, its own is switched off rather than layered
1072
- under: two answers to one gesture is how the zoom and the glow got here
1073
- in the first place. */
998
+ under: two answers to one gesture is how a shared zoom and a shared glow
999
+ got here in the first place, applied identically to every shape and
1000
+ saying nothing about any of them. */
1074
1001
  float own = uInteraction == 0 ? uReach : 0.0;
1075
1002
 
1076
1003
  float d = 0.0;
@@ -1100,7 +1027,7 @@ export const FRAGMENT = `#version 300 es
1100
1027
 
1101
1028
  /* Bloom as an exponent on the field rather than a term inside each shape.
1102
1029
  Every shape is a density that falls off, so a power tightens or spreads
1103
- that falloff and one control means the same thing in all five. */
1030
+ that falloff and one control means the same thing in all of them. */
1104
1031
  d = pow(max(d, 0.0), mix(2.0, 0.5, clamp(uBloom, 0.0, 1.0))) * uGain;
1105
1032
 
1106
1033
  /* The generic answers, for a consumer who has asked for one.