nodality 1.0.192 → 1.0.194

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 (168) hide show
  1. package/dist/animator.cjs.js +1 -1
  2. package/dist/animator.esm.js +1 -1
  3. package/dist/audionew.cjs.js +1 -1
  4. package/dist/audionew.esm.js +1 -1
  5. package/dist/beta-desktop-bar.cjs.js +1 -1
  6. package/dist/beta-desktop-bar.esm.js +1 -1
  7. package/dist/beta-mobile-bar.cjs.js +1 -1
  8. package/dist/beta-mobile-bar.esm.js +1 -1
  9. package/dist/bundle.umd.js +1 -1
  10. package/dist/button.cjs.js +1 -1
  11. package/dist/button.esm.js +1 -1
  12. package/dist/center.cjs.js +1 -1
  13. package/dist/center.esm.js +1 -1
  14. package/dist/checkbox.cjs.js +1 -1
  15. package/dist/checkbox.esm.js +1 -1
  16. package/dist/code.cjs.js +1 -1
  17. package/dist/code.esm.js +1 -1
  18. package/dist/container.cjs.js +1 -1
  19. package/dist/container.esm.js +1 -1
  20. package/dist/designer.cjs.js +1 -1
  21. package/dist/designer.esm.js +1 -1
  22. package/dist/dropdown.cjs.js +1 -1
  23. package/dist/dropdown.esm.js +1 -1
  24. package/dist/element-mapper.cjs.js +1 -1
  25. package/dist/element-mapper.esm.js +1 -1
  26. package/dist/finalresult.esm.js +1 -1
  27. package/dist/flex-card.cjs.js +1 -1
  28. package/dist/flex-card.esm.js +1 -1
  29. package/dist/flex-grid.cjs.js +1 -1
  30. package/dist/flex-grid.esm.js +1 -1
  31. package/dist/flex-row.cjs.js +1 -1
  32. package/dist/flex-row.esm.js +1 -1
  33. package/dist/floating-input.cjs.js +1 -1
  34. package/dist/floating-input.esm.js +1 -1
  35. package/dist/free.cjs.js +1 -1
  36. package/dist/free.esm.js +1 -1
  37. package/dist/image-picker.cjs.js +1 -1
  38. package/dist/image-picker.esm.js +1 -1
  39. package/dist/image.cjs.js +1 -1
  40. package/dist/image.esm.js +1 -1
  41. package/dist/index.cjs.js +1 -1
  42. package/dist/index.esm.js +1 -1
  43. package/dist/link-getter.cjs.js +1 -1
  44. package/dist/link-getter.esm.js +1 -1
  45. package/dist/link.cjs.js +1 -1
  46. package/dist/link.esm.js +1 -1
  47. package/dist/multiswitcher.cjs.js +1 -1
  48. package/dist/multiswitcher.esm.js +1 -1
  49. package/dist/new-nav-bar.cjs.js +1 -1
  50. package/dist/new-nav-bar.esm.js +1 -1
  51. package/dist/picker.cjs.js +1 -1
  52. package/dist/picker.esm.js +1 -1
  53. package/dist/side-nav-bar.cjs.js +1 -1
  54. package/dist/side-nav-bar.esm.js +1 -1
  55. package/dist/simple-bar.cjs.js +1 -1
  56. package/dist/simple-bar.esm.js +1 -1
  57. package/dist/slider-2025.cjs.js +1 -1
  58. package/dist/slider-2025.esm.js +1 -1
  59. package/dist/table.cjs.js +1 -1
  60. package/dist/table.esm.js +1 -1
  61. package/dist/text-field.cjs.js +1 -1
  62. package/dist/text-field.esm.js +1 -1
  63. package/dist/text.cjs.js +1 -1
  64. package/dist/text.esm.js +1 -1
  65. package/dist/ulist.cjs.js +1 -1
  66. package/dist/ulist.esm.js +1 -1
  67. package/dist/video.cjs.js +1 -1
  68. package/dist/video.esm.js +1 -1
  69. package/dist/zoom-card.cjs.js +1 -1
  70. package/dist/zoom-card.esm.js +1 -1
  71. package/layout/animator.js +1 -1
  72. package/layout/audio.js +1 -1
  73. package/layout/audionew.js +1 -1
  74. package/layout/base-2.js +1 -1
  75. package/layout/base.js +1 -1
  76. package/layout/beta-desktop-bar.js +1 -1
  77. package/layout/beta-mobile-bar.js +1 -1
  78. package/layout/box.js +1 -1
  79. package/layout/button.js +1 -1
  80. package/layout/cards.js +1 -1
  81. package/layout/center.js +1 -1
  82. package/layout/checkbox.js +1 -1
  83. package/layout/circle.js +1 -1
  84. package/layout/clean-row.js +1 -1
  85. package/layout/code.js +1 -1
  86. package/layout/container.js +1 -1
  87. package/layout/custom.js +1 -1
  88. package/layout/div-image.js +1 -1
  89. package/layout/dropdown-2025.js +1 -1
  90. package/layout/dropdown.js +1 -1
  91. package/layout/empty-element.js +1 -1
  92. package/layout/external-stylesheet.js +1 -1
  93. package/layout/flex-card.js +1 -1
  94. package/layout/flex-grid.js +1 -1
  95. package/layout/flex-row.js +1 -1
  96. package/layout/footer.js +1 -1
  97. package/layout/form-components/custom.js +1 -1
  98. package/layout/form-components/data-list.js +1 -1
  99. package/layout/form-components/floating-input.js +1 -1
  100. package/layout/form-components/form-all.js +1 -1
  101. package/layout/form-components/form.js +1 -1
  102. package/layout/form-components/image-picker.js +1 -1
  103. package/layout/form-components/picker.js +1 -1
  104. package/layout/form-components/radio.js +1 -1
  105. package/layout/form-components/radiogroup.js +1 -1
  106. package/layout/form-components/range.js +1 -1
  107. package/layout/free.js +1 -1
  108. package/layout/grid-new.js +1 -1
  109. package/layout/grid-switcher.js +1 -1
  110. package/layout/grid.js +1 -1
  111. package/layout/group.js +1 -1
  112. package/layout/header.js +1 -1
  113. package/layout/horizontal-scroller.js +1 -1
  114. package/layout/image-old.js +1 -1
  115. package/layout/image.js +1 -1
  116. package/layout/index.js +1 -1
  117. package/layout/label.js +1 -1
  118. package/layout/link.js +1 -1
  119. package/layout/list-OLD.js +1 -1
  120. package/layout/list.js +1 -1
  121. package/layout/meta-adder.js +1 -1
  122. package/layout/modal-2025.js +1 -1
  123. package/layout/modernwrap.js +1 -1
  124. package/layout/multiswitcher.js +1 -1
  125. package/layout/multiswitcherBeta.js +1 -1
  126. package/layout/nav-bar.js +1 -1
  127. package/layout/nav-factor/custom-div.js +1 -1
  128. package/layout/navBar-OLD.js +1 -1
  129. package/layout/new-flat-adder.js +1 -1
  130. package/layout/new-nav-bar.js +1 -1
  131. package/layout/offset-container.js +1 -1
  132. package/layout/polygon.js +1 -1
  133. package/layout/prerender-site.js +1 -1
  134. package/layout/prerender.js +1 -1
  135. package/layout/progress.js +1 -1
  136. package/layout/row.js +1 -1
  137. package/layout/saved-new-nav-bar.js +1 -1
  138. package/layout/scroll-video.js +1 -1
  139. package/layout/side-bar.js +1 -1
  140. package/layout/side-nav-bar.js +1 -1
  141. package/layout/simple-bar.js +1 -1
  142. package/layout/slider-2025.js +1 -1
  143. package/layout/spacer.js +1 -1
  144. package/layout/stack.js +1 -1
  145. package/layout/styler.js +1 -1
  146. package/layout/svg.js +1 -1
  147. package/layout/switcher.js +1 -1
  148. package/layout/table.js +1 -1
  149. package/layout/text-field.js +1 -1
  150. package/layout/text.js +1 -1
  151. package/layout/ulist.js +1 -1
  152. package/layout/video.js +1 -1
  153. package/layout/without-new.js +1 -1
  154. package/layout/wrap.js +1 -1
  155. package/layout/zoom-card.js +1 -1
  156. package/lib/card-getter.js +1 -1
  157. package/lib/data.js +1 -1
  158. package/lib/designer.js +1 -1
  159. package/lib/element-mapper.js +1 -1
  160. package/lib/keyframe-animation.js +1 -1
  161. package/lib/link-getter.js +1 -1
  162. package/lib/raster-ops.js +71 -9
  163. package/lib/scroll-video.js +1 -1
  164. package/lib/seo.js +1 -1
  165. package/lib/stacker.js +1 -1
  166. package/lib/theme.js +1 -1
  167. package/lib/transform-anim.js +1 -1
  168. package/package.json +1 -1
package/lib/raster-ops.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.192
2
+ * nodality v1.0.194
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -181,7 +181,11 @@ const REGISTRY = {
181
181
  // inject divergence energy the field stays stable with no pressure
182
182
  // projection at all — the whole simulation is a single pass.
183
183
  //
184
- // { op: "stir", strength: 26, swirl: 2.4, decay: 0.985 }
184
+ // { op: "stir", strength: 26, curl: 2.4, decay: 0.985 }
185
+ //
186
+ // The swirliness knob is `curl` (vorticity confinement). An earlier
187
+ // version of this line said `swirl`, which the solver never reads — it
188
+ // is accepted silently and leaves curl at its default.
185
189
  // Halftone: the print dot screen. Tone is carried by dot AREA on a
186
190
  // rotated grid rather than by intensity, the way offset lithography
187
191
  // reproduces a continuous-tone image with a single ink.
@@ -1950,12 +1954,20 @@ function applyRasterPipeline(el, rasterNodes) {
1950
1954
  const px = mouse[0] / canvas.width;
1951
1955
  const py = 1 - mouse[1] / canvas.height;
1952
1956
  let dx = 0, dy = 0;
1953
- if (s.primed) {
1957
+ // Only a real pointer event counts as motion. `mouse` is stored in
1958
+ // canvas pixels, so this normalised position also shifts whenever the
1959
+ // canvas itself resizes or moves — an element being animated (a
1960
+ // scroll-driven hero expanding) would otherwise inject phantom
1961
+ // velocity every frame and stir itself with the pointer sitting
1962
+ // still, or with the pointer nowhere near it.
1963
+ if (s.primed && pointerMoved) {
1954
1964
  dx = (px - s.prevX) / Math.max(dt, 1e-3);
1955
1965
  dy = (py - s.prevY) / Math.max(dt, 1e-3);
1956
1966
  }
1967
+ // Re-baseline regardless, so the frame after a resize does not
1968
+ // measure its delta against a position from a different geometry.
1957
1969
  s.prevX = px; s.prevY = py; s.primed = true;
1958
- const moving = Math.abs(dx) + Math.abs(dy) > 1e-3;
1970
+ const moving = pointerMoved && Math.abs(dx) + Math.abs(dy) > 1e-3;
1959
1971
 
1960
1972
  s.def.solver.step(S, s.node, {
1961
1973
  dt, px, py, dx, dy, moving,
@@ -2187,10 +2199,17 @@ function applyRasterPipeline(el, rasterNodes) {
2187
2199
  // Pointer -> u_mouse (listen on the host so the overlay stays
2188
2200
  // pointer-events: none).
2189
2201
  let mouse = [canvas.width * 0.5, canvas.height * 0.5];
2202
+ // Set by a real pointer event, cleared once the solvers have consumed
2203
+ // it. Stateful ops splat only while this is true, so nothing is stirred
2204
+ // by the element resizing or scrolling under a stationary pointer.
2205
+ let pointerMoved = false;
2190
2206
  const onMove = (e) => {
2191
2207
  const r = canvas.getBoundingClientRect();
2192
2208
  const pt = e.touches ? e.touches[0] : e;
2193
- mouse = [(pt.clientX - r.left) * dpr, (pt.clientY - r.top) * dpr];
2209
+ const next = [(pt.clientX - r.left) * dpr, (pt.clientY - r.top) * dpr];
2210
+ // Guard against move events that report the same position.
2211
+ if (next[0] !== mouse[0] || next[1] !== mouse[1]) pointerMoved = true;
2212
+ mouse = next;
2194
2213
  };
2195
2214
  el.addEventListener("mousemove", onMove, { passive: true });
2196
2215
  el.addEventListener("touchmove", onMove, { passive: true });
@@ -2236,6 +2255,10 @@ function applyRasterPipeline(el, rasterNodes) {
2236
2255
  // 1. Advance stateful fluid solvers into their own off-screen
2237
2256
  // targets (this rebinds framebuffer/program/textures).
2238
2257
  for (const s of solverOps) stepSolver(s, dt);
2258
+ // Consumed for this frame: a splat needs a fresh pointer event,
2259
+ // not merely a pointer position that happens to differ because
2260
+ // the canvas moved or resized beneath it.
2261
+ pointerMoved = false;
2239
2262
 
2240
2263
  // 2. Composite pass, back on the visible framebuffer.
2241
2264
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
@@ -2302,19 +2325,58 @@ function applyRasterPipeline(el, rasterNodes) {
2302
2325
  // ResizeObserver, the window-resize fallback and the font-loading
2303
2326
  // recapture, so all three agree on what "resize the canvas" means.
2304
2327
  const remeasureAndCapture = () => {
2305
- if (destroyed || mode !== "snapshot") return;
2328
+ if (destroyed) return;
2306
2329
  const m = measure();
2330
+ if (m.width < 2 || m.height < 2) return;
2331
+ const bw = Math.round(m.width * dpr);
2332
+ const bh = Math.round(m.height * dpr);
2333
+ rect.width = m.width;
2334
+ rect.height = m.height;
2335
+ canvas.style.width = m.width + "px";
2336
+ canvas.style.height = m.height + "px";
2337
+ // Re-allocating the buffer clears it, so skip when it already matches
2338
+ // — syncCanvasBox may have kept the CSS box in step without needing a
2339
+ // new buffer at all.
2340
+ const bufferStale = canvas.width !== bw || canvas.height !== bh;
2341
+ if (bufferStale) {
2342
+ canvas.width = bw;
2343
+ canvas.height = bh;
2344
+ }
2345
+ if (mode === "snapshot") {
2346
+ snapshotCapture();
2347
+ } else if (bufferStale) {
2348
+ // Live mode re-uploads from the DOM every paint, so it needs no
2349
+ // recapture — only a fresh upload at the new buffer size.
2350
+ onPaint();
2351
+ }
2352
+ };
2353
+
2354
+ // Match the canvas box to the host immediately, without recapturing.
2355
+ // Re-uploading the texture is the expensive half and stays debounced;
2356
+ // resizing the element is cheap and must not be, because a host that is
2357
+ // being animated (a scroll-driven hero expanding every frame) would
2358
+ // otherwise render up to a debounce-interval behind its own layout —
2359
+ // the canvas visibly trailing the content it is drawn over.
2360
+ // CSS size only. Assigning canvas.width/height re-allocates the drawing
2361
+ // buffer and CLEARS it, so doing that per frame while an element is being
2362
+ // animated makes the whole effect flash on every scroll step. The buffer
2363
+ // is left to the debounced recapture below; stretching the existing one
2364
+ // for a few frames costs a little sharpness and nothing else.
2365
+ const syncCanvasBox = () => {
2366
+ if (destroyed) return;
2367
+ const m = measure();
2368
+ if (m.width < 2 || m.height < 2) return;
2369
+ if (Math.round(m.width) === Math.round(rect.width) &&
2370
+ Math.round(m.height) === Math.round(rect.height)) return;
2307
2371
  rect.width = m.width;
2308
2372
  rect.height = m.height;
2309
- canvas.width = Math.round(m.width * dpr);
2310
- canvas.height = Math.round(m.height * dpr);
2311
2373
  canvas.style.width = m.width + "px";
2312
2374
  canvas.style.height = m.height + "px";
2313
- snapshotCapture();
2314
2375
  };
2315
2376
 
2316
2377
  if (typeof ResizeObserver !== "undefined") {
2317
2378
  ro = new ResizeObserver(() => {
2379
+ syncCanvasBox();
2318
2380
  clearTimeout(resizeTimer);
2319
2381
  resizeTimer = setTimeout(remeasureAndCapture, 150);
2320
2382
  });
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.192
2
+ * nodality v1.0.194
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/seo.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.192
2
+ * nodality v1.0.194
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/stacker.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.192
2
+ * nodality v1.0.194
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/lib/theme.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.192
2
+ * nodality v1.0.194
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * nodality v1.0.192
2
+ * nodality v1.0.194
3
3
  * (c) 2026 Filip Vabrousek
4
4
  * License: MIT
5
5
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodality",
3
- "version": "1.0.192",
3
+ "version": "1.0.194",
4
4
  "description": "A lightweight library for declarative UI elements.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",