nodality 1.0.182 → 1.0.185
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.
- package/dist/animator.cjs.js +1 -1
- package/dist/animator.esm.js +1 -1
- package/dist/audionew.cjs.js +1 -1
- package/dist/audionew.esm.js +1 -1
- package/dist/base.cjs.js +1 -1
- package/dist/base.esm.js +1 -1
- package/dist/beta-desktop-bar.cjs.js +1 -1
- package/dist/beta-desktop-bar.esm.js +1 -1
- package/dist/beta-mobile-bar.cjs.js +1 -1
- package/dist/beta-mobile-bar.esm.js +1 -1
- package/dist/bundle.umd.js +1 -1
- package/dist/button.cjs.js +1 -1
- package/dist/button.esm.js +1 -1
- package/dist/center.cjs.js +1 -1
- package/dist/center.esm.js +1 -1
- package/dist/checkbox.cjs.js +1 -1
- package/dist/checkbox.esm.js +1 -1
- package/dist/code.cjs.js +1 -1
- package/dist/code.esm.js +1 -1
- package/dist/container.cjs.js +1 -1
- package/dist/container.esm.js +1 -1
- package/dist/data-list.cjs.js +1 -1
- package/dist/data-list.esm.js +1 -1
- package/dist/designer.cjs.js +1 -1
- package/dist/designer.esm.js +1 -1
- package/dist/dropdown.cjs.js +1 -1
- package/dist/dropdown.esm.js +1 -1
- package/dist/element-mapper.cjs.js +1 -1
- package/dist/element-mapper.esm.js +1 -1
- package/dist/finalresult.esm.js +1 -1
- package/dist/flex-card.cjs.js +1 -1
- package/dist/flex-card.esm.js +1 -1
- package/dist/flex-grid.cjs.js +1 -1
- package/dist/flex-grid.esm.js +1 -1
- package/dist/flex-row.cjs.js +1 -1
- package/dist/flex-row.esm.js +1 -1
- package/dist/floating-input.cjs.js +1 -1
- package/dist/floating-input.esm.js +1 -1
- package/dist/free.cjs.js +1 -1
- package/dist/free.esm.js +1 -1
- package/dist/horizontal-scroller.cjs.js +1 -1
- package/dist/horizontal-scroller.esm.js +1 -1
- package/dist/image-picker.cjs.js +1 -1
- package/dist/image-picker.esm.js +1 -1
- package/dist/image.cjs.js +1 -1
- package/dist/image.esm.js +1 -1
- package/dist/index.cjs.js +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/link-getter.cjs.js +1 -1
- package/dist/link-getter.esm.js +1 -1
- package/dist/link.cjs.js +1 -1
- package/dist/link.esm.js +1 -1
- package/dist/meta-adder.cjs.js +1 -1
- package/dist/meta-adder.esm.js +1 -1
- package/dist/modal-2025.cjs.js +1 -1
- package/dist/modal-2025.esm.js +1 -1
- package/dist/multiswitcher.cjs.js +1 -1
- package/dist/multiswitcher.esm.js +1 -1
- package/dist/new-nav-bar.cjs.js +1 -1
- package/dist/new-nav-bar.esm.js +1 -1
- package/dist/picker.cjs.js +1 -1
- package/dist/picker.esm.js +1 -1
- package/dist/progress.cjs.js +1 -1
- package/dist/progress.esm.js +1 -1
- package/dist/radio.cjs.js +1 -1
- package/dist/radio.esm.js +1 -1
- package/dist/range.cjs.js +1 -1
- package/dist/range.esm.js +1 -1
- package/dist/side-bar.cjs.js +1 -1
- package/dist/side-bar.esm.js +1 -1
- package/dist/side-nav-bar.cjs.js +1 -1
- package/dist/side-nav-bar.esm.js +1 -1
- package/dist/simple-bar.cjs.js +1 -1
- package/dist/simple-bar.esm.js +1 -1
- package/dist/slider-2025.cjs.js +1 -1
- package/dist/slider-2025.esm.js +1 -1
- package/dist/spacer.cjs.js +1 -1
- package/dist/spacer.esm.js +1 -1
- package/dist/stack.cjs.js +1 -1
- package/dist/stack.esm.js +1 -1
- package/dist/table.cjs.js +1 -1
- package/dist/table.esm.js +1 -1
- package/dist/text-field.cjs.js +1 -1
- package/dist/text-field.esm.js +1 -1
- package/dist/text.cjs.js +1 -1
- package/dist/text.esm.js +1 -1
- package/dist/ulist.cjs.js +1 -1
- package/dist/ulist.esm.js +1 -1
- package/dist/video.cjs.js +1 -1
- package/dist/video.esm.js +1 -1
- package/dist/wrap.cjs.js +1 -1
- package/dist/wrap.esm.js +1 -1
- package/dist/zoom-card.cjs.js +1 -1
- package/dist/zoom-card.esm.js +1 -1
- package/layout/animator.js +1 -1
- package/layout/audio.js +1 -1
- package/layout/audionew.js +1 -1
- package/layout/base-2.js +1 -1
- package/layout/base.js +1 -1
- package/layout/beta-desktop-bar.js +1 -1
- package/layout/beta-mobile-bar.js +1 -1
- package/layout/box.js +1 -1
- package/layout/button.js +1 -1
- package/layout/cards.js +1 -1
- package/layout/center.js +1 -1
- package/layout/checkbox.js +1 -1
- package/layout/circle.js +1 -1
- package/layout/clean-row.js +1 -1
- package/layout/code.js +1 -1
- package/layout/container.js +1 -1
- package/layout/custom.js +1 -1
- package/layout/div-image.js +1 -1
- package/layout/dropdown-2025.js +1 -1
- package/layout/dropdown.js +1 -1
- package/layout/empty-element.js +1 -1
- package/layout/external-stylesheet.js +1 -1
- package/layout/flex-card.js +1 -1
- package/layout/flex-grid.js +1 -1
- package/layout/flex-row.js +1 -1
- package/layout/footer.js +1 -1
- package/layout/form-components/custom.js +1 -1
- package/layout/form-components/data-list.js +1 -1
- package/layout/form-components/floating-input.js +1 -1
- package/layout/form-components/form-all.js +1 -1
- package/layout/form-components/form.js +1 -1
- package/layout/form-components/image-picker.js +1 -1
- package/layout/form-components/picker.js +1 -1
- package/layout/form-components/radio.js +1 -1
- package/layout/form-components/radiogroup.js +1 -1
- package/layout/form-components/range.js +1 -1
- package/layout/free.js +1 -1
- package/layout/grid-new.js +1 -1
- package/layout/grid-switcher.js +1 -1
- package/layout/grid.js +1 -1
- package/layout/group.js +1 -1
- package/layout/header.js +1 -1
- package/layout/horizontal-scroller.js +1 -1
- package/layout/image-old.js +1 -1
- package/layout/image.js +1 -1
- package/layout/index.js +1 -1
- package/layout/label.js +1 -1
- package/layout/link.js +1 -1
- package/layout/list-OLD.js +1 -1
- package/layout/list.js +1 -1
- package/layout/meta-adder.js +1 -1
- package/layout/modal-2025.js +1 -1
- package/layout/modernwrap.js +1 -1
- package/layout/multiswitcher.js +1 -1
- package/layout/multiswitcherBeta.js +1 -1
- package/layout/nav-bar.js +1 -1
- package/layout/nav-factor/custom-div.js +1 -1
- package/layout/navBar-OLD.js +1 -1
- package/layout/new-flat-adder.js +1 -1
- package/layout/new-nav-bar.js +1 -1
- package/layout/offset-container.js +1 -1
- package/layout/polygon.js +1 -1
- package/layout/prerender-site.js +1 -1
- package/layout/prerender.js +1 -1
- package/layout/progress.js +1 -1
- package/layout/row.js +1 -1
- package/layout/saved-new-nav-bar.js +1 -1
- package/layout/scroll-video.js +1 -1
- package/layout/side-bar.js +1 -1
- package/layout/side-nav-bar.js +1 -1
- package/layout/simple-bar.js +1 -1
- package/layout/slider-2025.js +1 -1
- package/layout/spacer.js +1 -1
- package/layout/stack.js +1 -1
- package/layout/styler.js +1 -1
- package/layout/svg.js +1 -1
- package/layout/switcher.js +1 -1
- package/layout/table.js +1 -1
- package/layout/text-field.js +1 -1
- package/layout/text.js +1 -1
- package/layout/ulist.js +1 -1
- package/layout/video.js +1 -1
- package/layout/without-new.js +1 -1
- package/layout/wrap.js +1 -1
- package/layout/zoom-card.js +1 -1
- package/lib/card-getter.js +1 -1
- package/lib/data.js +1 -1
- package/lib/designer.js +1 -1
- package/lib/element-mapper.js +1 -1
- package/lib/keyframe-animation.js +1 -1
- package/lib/link-getter.js +1 -1
- package/lib/raster-ops.js +179 -10
- package/lib/scroll-video.js +1 -1
- package/lib/seo.js +1 -1
- package/lib/stacker.js +1 -1
- package/lib/theme.js +1 -1
- package/lib/transform-anim.js +1 -1
- package/package.json +2 -1
package/lib/raster-ops.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* nodality v1.0.
|
|
2
|
+
* nodality v1.0.185
|
|
3
3
|
* (c) 2026 Filip Vabrousek
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -46,6 +46,32 @@
|
|
|
46
46
|
|
|
47
47
|
const MAX_BLOBS = 12;
|
|
48
48
|
|
|
49
|
+
// ── Drivers ──────────────────────────────────────────────────────────
|
|
50
|
+
// What steers a reactive op. Previously "react to the pointer" was
|
|
51
|
+
// hardcoded into offset and duotone; a driver makes the input a value in
|
|
52
|
+
// the node data, so the same op can be aimed at different signals:
|
|
53
|
+
//
|
|
54
|
+
// { op: "offset", by: "mouse" } { op: "offset", by: "scroll" }
|
|
55
|
+
//
|
|
56
|
+
// Each driver returns a focus point in device pixels plus an amount in
|
|
57
|
+
// 0..1 that the op scales its effect by. Ops read them as u<i>_dpos and
|
|
58
|
+
// u<i>_damt; the pipeline evaluates and uploads them once per frame.
|
|
59
|
+
const DRIVERS = {
|
|
60
|
+
mouse: (c) => ({ x: c.mouseX, y: c.mouseY, amt: 1 }),
|
|
61
|
+
// Same focus as mouse, but faded in and out with the hover state, so
|
|
62
|
+
// the effect resolves away when the pointer leaves.
|
|
63
|
+
hover: (c) => ({ x: c.mouseX, y: c.mouseY, amt: c.hover }),
|
|
64
|
+
// A band that travels up the element as it crosses the viewport.
|
|
65
|
+
scroll: (c) => ({ x: c.w * 0.5, y: c.h * c.scroll, amt: 1 }),
|
|
66
|
+
// Hands-free: the focus drifts on a Lissajous path.
|
|
67
|
+
time: (c) => ({
|
|
68
|
+
x: c.w * (0.5 + 0.34 * Math.cos(c.t * 0.6)),
|
|
69
|
+
y: c.h * (0.5 + 0.34 * Math.sin(c.t * 0.8)),
|
|
70
|
+
amt: 1,
|
|
71
|
+
}),
|
|
72
|
+
};
|
|
73
|
+
const DRIVER_NAMES = Object.keys(DRIVERS);
|
|
74
|
+
|
|
49
75
|
const REGISTRY = {
|
|
50
76
|
hexalize: {
|
|
51
77
|
stage: "cell",
|
|
@@ -71,13 +97,17 @@ const REGISTRY = {
|
|
|
71
97
|
// version shifted only the texture lookup, which left grid
|
|
72
98
|
// edges frozen in screen space.)
|
|
73
99
|
stage: "warp",
|
|
74
|
-
|
|
100
|
+
// Steered by the pointer unless the node says otherwise, which is
|
|
101
|
+
// what this op did before drivers existed.
|
|
102
|
+
defaultDriver: "mouse",
|
|
103
|
+
decl: (p) => `uniform float ${p}strength; uniform float ${p}radius;
|
|
104
|
+
uniform vec2 ${p}dpos; uniform float ${p}damt;`,
|
|
75
105
|
code: (p) => `
|
|
76
106
|
{
|
|
77
|
-
float d = length(warped -
|
|
107
|
+
float d = length(warped - ${p}dpos);
|
|
78
108
|
float fall = 1.0 - smoothstep(0.0, ${p}radius, d);
|
|
79
|
-
vec2 dir = d > 0.5 ? (warped -
|
|
80
|
-
warped -= dir * ${p}strength * fall;
|
|
109
|
+
vec2 dir = d > 0.5 ? (warped - ${p}dpos) / d : vec2(0.0);
|
|
110
|
+
warped -= dir * ${p}strength * fall * ${p}damt;
|
|
81
111
|
}`,
|
|
82
112
|
uniforms: (node, dpr) => ({
|
|
83
113
|
strength: ["1f", (node.strength || 20) * dpr],
|
|
@@ -87,13 +117,15 @@ const REGISTRY = {
|
|
|
87
117
|
|
|
88
118
|
duotone: {
|
|
89
119
|
stage: "color",
|
|
90
|
-
decl: (p) => `uniform vec3 ${p}a; uniform vec3 ${p}b; uniform float ${p}radius
|
|
120
|
+
decl: (p) => `uniform vec3 ${p}a; uniform vec3 ${p}b; uniform float ${p}radius;
|
|
121
|
+
uniform vec2 ${p}dpos; uniform float ${p}damt;`,
|
|
91
122
|
code: (p, node) => `
|
|
92
123
|
{
|
|
93
124
|
float lum = dot(col, vec3(0.299, 0.587, 0.114));
|
|
94
125
|
vec3 duo = mix(${p}a, ${p}b, lum);
|
|
95
|
-
${node.by
|
|
96
|
-
? `float mask = 1.0 - smoothstep(${p}radius * 0.35, ${p}radius,
|
|
126
|
+
${node.by
|
|
127
|
+
? `float mask = (1.0 - smoothstep(${p}radius * 0.35, ${p}radius,
|
|
128
|
+
length(center - ${p}dpos))) * ${p}damt;`
|
|
97
129
|
: `float mask = 1.0;`}
|
|
98
130
|
col = mix(col, duo, mask);
|
|
99
131
|
}`,
|
|
@@ -146,6 +178,87 @@ const REGISTRY = {
|
|
|
146
178
|
// projection at all — the whole simulation is a single pass.
|
|
147
179
|
//
|
|
148
180
|
// { op: "stir", strength: 26, swirl: 2.4, decay: 0.985 }
|
|
181
|
+
// Halftone: the print dot screen. Tone is carried by dot AREA on a
|
|
182
|
+
// rotated grid rather than by intensity, the way offset lithography
|
|
183
|
+
// reproduces a continuous-tone image with a single ink.
|
|
184
|
+
//
|
|
185
|
+
// { op: "halftone", size: 6, angle: 15, ink: "#0B1B2B" }
|
|
186
|
+
//
|
|
187
|
+
// With a driver the screen coarsens toward the focus, like holding a
|
|
188
|
+
// loupe over the sheet.
|
|
189
|
+
halftone: {
|
|
190
|
+
stage: "color",
|
|
191
|
+
decl: (p) => `
|
|
192
|
+
uniform float ${p}size;
|
|
193
|
+
uniform float ${p}angle;
|
|
194
|
+
uniform vec3 ${p}ink;
|
|
195
|
+
uniform vec3 ${p}paper;
|
|
196
|
+
uniform float ${p}soft;
|
|
197
|
+
uniform float ${p}radius;
|
|
198
|
+
uniform vec2 ${p}dpos;
|
|
199
|
+
uniform float ${p}damt;`,
|
|
200
|
+
code: (p, node) => `
|
|
201
|
+
{
|
|
202
|
+
float lum = dot(col, vec3(0.299, 0.587, 0.114));
|
|
203
|
+
float sz = ${p}size;${node.by ? `
|
|
204
|
+
float fd = 1.0 - smoothstep(0.0, ${p}radius, length(frag - ${p}dpos));
|
|
205
|
+
sz *= 1.0 + fd * ${p}damt * 1.8;` : ``}
|
|
206
|
+
// Screen angle: rotating the grid is what stops the dots
|
|
207
|
+
// reading as a horizontal/vertical texture.
|
|
208
|
+
float ca = cos(${p}angle), sa = sin(${p}angle);
|
|
209
|
+
vec2 rp = vec2(ca * frag.x - sa * frag.y,
|
|
210
|
+
sa * frag.x + ca * frag.y) / max(sz, 1.0);
|
|
211
|
+
vec2 cell = fract(rp) - 0.5;
|
|
212
|
+
// Dot radius from tone: darker tone prints a bigger dot.
|
|
213
|
+
// sqrt because ink coverage goes as area, not radius.
|
|
214
|
+
float rr = sqrt(clamp(1.0 - lum, 0.0, 1.0)) * 0.55;
|
|
215
|
+
float dm = smoothstep(rr, rr - ${p}soft, length(cell));
|
|
216
|
+
col = mix(${p}paper, ${p}ink, dm);
|
|
217
|
+
}`,
|
|
218
|
+
uniforms: (node, dpr) => ({
|
|
219
|
+
size: ["1f", (node.size || 6) * dpr],
|
|
220
|
+
angle: ["1f", ((node.angle != null ? node.angle : 15) * Math.PI) / 180],
|
|
221
|
+
ink: ["3fv", hexToRgb(node.ink || "#0B1B2B")],
|
|
222
|
+
paper: ["3fv", hexToRgb(node.paper || "#FFFFFF")],
|
|
223
|
+
soft: ["1f", node.softness != null ? node.softness : 0.08],
|
|
224
|
+
radius: ["1f", (node.radius || 220) * dpr],
|
|
225
|
+
}),
|
|
226
|
+
},
|
|
227
|
+
|
|
228
|
+
// Chromatic aberration: the only op that uses the displace stage. It
|
|
229
|
+
// does not move the sample position itself, it sets `chroma`, the
|
|
230
|
+
// per-channel split the sampler applies - red and blue are fetched
|
|
231
|
+
// either side of green along the radial direction, the way a simple
|
|
232
|
+
// lens disperses wavelengths toward its edges.
|
|
233
|
+
//
|
|
234
|
+
// { op: "aberration", amount: 6 } // radial, lens-like
|
|
235
|
+
// { op: "aberration", amount: 14, by: "mouse" } // focused at the pointer
|
|
236
|
+
aberration: {
|
|
237
|
+
stage: "displace",
|
|
238
|
+
chroma: true,
|
|
239
|
+
decl: (p) => `
|
|
240
|
+
uniform float ${p}amount;
|
|
241
|
+
uniform float ${p}radius;
|
|
242
|
+
uniform vec2 ${p}dpos;
|
|
243
|
+
uniform float ${p}damt;`,
|
|
244
|
+
code: (p, node) => `
|
|
245
|
+
{
|
|
246
|
+
vec2 ctr = ${node.by ? `${p}dpos` : `u_res * 0.5`};
|
|
247
|
+
vec2 dv = sampleP - ctr;
|
|
248
|
+
float dl = length(dv);
|
|
249
|
+
vec2 dir = dl > 0.5 ? dv / dl : vec2(0.0);
|
|
250
|
+
${node.by
|
|
251
|
+
? `float amt = ${p}amount * ${p}damt *
|
|
252
|
+
(1.0 - smoothstep(0.0, ${p}radius, dl));`
|
|
253
|
+
: `float amt = ${p}amount * (dl / max(length(u_res) * 0.5, 1.0));`}
|
|
254
|
+
chroma += dir * amt;
|
|
255
|
+
}`,
|
|
256
|
+
uniforms: (node, dpr) => ({
|
|
257
|
+
amount: ["1f", (node.amount != null ? node.amount : 6) * dpr],
|
|
258
|
+
radius: ["1f", (node.radius || 240) * dpr],
|
|
259
|
+
}),
|
|
260
|
+
},
|
|
261
|
+
|
|
149
262
|
// Stirred liquid: an incompressible fluid whose velocity field warps
|
|
150
263
|
// the content and whose dye field colours it.
|
|
151
264
|
//
|
|
@@ -797,6 +910,13 @@ function buildFragmentShader(nodes) {
|
|
|
797
910
|
// darkening only applies when a cell op runs without an edges op.
|
|
798
911
|
const hasEdges = nodes.some((n) => n.op === "edges");
|
|
799
912
|
const defaultSeam = hasEdges ? "" : " col *= 1.0 - edge * 0.55;";
|
|
913
|
+
// Per-channel resampling costs two extra fetches, so it is only
|
|
914
|
+
// emitted when a displace-stage op actually asks for dispersion.
|
|
915
|
+
const hasChroma = nodes.some((n) => (REGISTRY[n.op] || {}).chroma);
|
|
916
|
+
const chromaFetch = hasChroma ? `
|
|
917
|
+
vec2 cpx = vec2(chroma.x, -chroma.y) / u_res;
|
|
918
|
+
col.r = texture2D(u_tex, clamp(uv + cpx, 0.001, 0.999)).r;
|
|
919
|
+
col.b = texture2D(u_tex, clamp(uv - cpx, 0.001, 0.999)).b;` : "";
|
|
800
920
|
return `
|
|
801
921
|
precision highp float;
|
|
802
922
|
uniform sampler2D u_tex;
|
|
@@ -812,10 +932,11 @@ ${warp}
|
|
|
812
932
|
float edge = 0.0;
|
|
813
933
|
${cell}
|
|
814
934
|
vec2 sampleP = warped;
|
|
935
|
+
vec2 chroma = vec2(0.0);
|
|
815
936
|
${displace}
|
|
816
937
|
vec2 uv = vec2(sampleP.x / u_res.x, 1.0 - sampleP.y / u_res.y);
|
|
817
938
|
vec4 tex = texture2D(u_tex, clamp(uv, 0.001, 0.999));
|
|
818
|
-
vec3 col = tex.rgb
|
|
939
|
+
vec3 col = tex.rgb;${chromaFetch}
|
|
819
940
|
vec3 edgeCol = vec3(1.0);
|
|
820
941
|
float edgeCov = 0.0;
|
|
821
942
|
vec3 ovCol = vec3(0.0);
|
|
@@ -1358,6 +1479,35 @@ function applyRasterPipeline(el, rasterNodes) {
|
|
|
1358
1479
|
el.addEventListener("mousemove", onMove, { passive: true });
|
|
1359
1480
|
el.addEventListener("touchmove", onMove, { passive: true });
|
|
1360
1481
|
|
|
1482
|
+
// Driver inputs beyond the pointer. hoverTarget flips on enter/leave
|
|
1483
|
+
// and `hover` eases toward it, so a hover-driven op resolves away
|
|
1484
|
+
// smoothly instead of snapping off.
|
|
1485
|
+
let hoverTarget = 0, hover = 0;
|
|
1486
|
+
const onEnter = () => { hoverTarget = 1; };
|
|
1487
|
+
const onLeave = () => { hoverTarget = 0; };
|
|
1488
|
+
el.addEventListener("mouseenter", onEnter, { passive: true });
|
|
1489
|
+
el.addEventListener("mouseleave", onLeave, { passive: true });
|
|
1490
|
+
|
|
1491
|
+
// Which nodes need a driver evaluated, and with what.
|
|
1492
|
+
const driverNodes = [];
|
|
1493
|
+
rasterNodes.forEach((node, i) => {
|
|
1494
|
+
const def = REGISTRY[node.op] || {};
|
|
1495
|
+
const name = node.by || def.defaultDriver;
|
|
1496
|
+
if (name && DRIVERS[name]) driverNodes.push({ i, fn: DRIVERS[name] });
|
|
1497
|
+
else if (node.by) {
|
|
1498
|
+
console.warn("[nodality] unknown driver '" + node.by + "' on op '" +
|
|
1499
|
+
node.op + "' - known drivers: " + DRIVER_NAMES.join(", "));
|
|
1500
|
+
}
|
|
1501
|
+
});
|
|
1502
|
+
|
|
1503
|
+
// How far the element has travelled across the viewport, 0..1.
|
|
1504
|
+
const scrollProgress = () => {
|
|
1505
|
+
if (typeof window === "undefined") return 0.5;
|
|
1506
|
+
const r = el.getBoundingClientRect();
|
|
1507
|
+
const vh = window.innerHeight || 1;
|
|
1508
|
+
return Math.max(0, Math.min(1, (vh - r.top) / (vh + r.height)));
|
|
1509
|
+
};
|
|
1510
|
+
|
|
1361
1511
|
// Render loop — paused while off-screen.
|
|
1362
1512
|
let raf = 0;
|
|
1363
1513
|
let visible = true;
|
|
@@ -1380,6 +1530,20 @@ function applyRasterPipeline(el, rasterNodes) {
|
|
|
1380
1530
|
gl.uniform2f(U("u_res"), canvas.width, canvas.height);
|
|
1381
1531
|
gl.uniform2f(U("u_mouse"), mouse[0], mouse[1]);
|
|
1382
1532
|
gl.uniform1f(U("u_time"), now / 1000);
|
|
1533
|
+
// Evaluate each reactive op's driver and upload its focus.
|
|
1534
|
+
if (driverNodes.length > 0) {
|
|
1535
|
+
hover += (hoverTarget - hover) * (1 - Math.exp(-dt * 8));
|
|
1536
|
+
const dctx = {
|
|
1537
|
+
mouseX: mouse[0], mouseY: mouse[1],
|
|
1538
|
+
w: canvas.width, h: canvas.height,
|
|
1539
|
+
t: now / 1000, hover, scroll: scrollProgress(),
|
|
1540
|
+
};
|
|
1541
|
+
for (const d of driverNodes) {
|
|
1542
|
+
const v = d.fn(dctx);
|
|
1543
|
+
gl.uniform2f(U(`u${d.i}_dpos`), v.x, v.y);
|
|
1544
|
+
gl.uniform1f(U(`u${d.i}_damt`), v.amt);
|
|
1545
|
+
}
|
|
1546
|
+
}
|
|
1383
1547
|
// Advance and upload per-frame CPU simulations.
|
|
1384
1548
|
if (dynamicOps.length > 0) {
|
|
1385
1549
|
const ctx = { w: canvas.width, h: canvas.height, mouseX: mouse[0], mouseY: mouse[1], dt: dt, t: now / 1000 };
|
|
@@ -1498,6 +1662,8 @@ function applyRasterPipeline(el, rasterNodes) {
|
|
|
1498
1662
|
if (typeof window !== "undefined") window.removeEventListener("resize", onWinResize);
|
|
1499
1663
|
el.removeEventListener("mousemove", onMove);
|
|
1500
1664
|
el.removeEventListener("touchmove", onMove);
|
|
1665
|
+
el.removeEventListener("mouseenter", onEnter);
|
|
1666
|
+
el.removeEventListener("mouseleave", onLeave);
|
|
1501
1667
|
canvas.removeEventListener("paint", onPaint);
|
|
1502
1668
|
for (const s of solverOps) {
|
|
1503
1669
|
s.cleanup();
|
|
@@ -1511,4 +1677,7 @@ function applyRasterPipeline(el, rasterNodes) {
|
|
|
1511
1677
|
};
|
|
1512
1678
|
}
|
|
1513
1679
|
|
|
1514
|
-
export {
|
|
1680
|
+
export {
|
|
1681
|
+
applyRasterPipeline, registerRasterOp, RASTER_OP_NAMES,
|
|
1682
|
+
isHTMLInCanvasAvailable, DRIVER_NAMES,
|
|
1683
|
+
};
|
package/lib/scroll-video.js
CHANGED
package/lib/seo.js
CHANGED
package/lib/stacker.js
CHANGED
package/lib/theme.js
CHANGED
package/lib/transform-anim.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodality",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.185",
|
|
4
4
|
"description": "A lightweight library for declarative UI elements.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
"jest": "^29.7.0",
|
|
81
81
|
"jest-environment-jsdom": "^29.7.0",
|
|
82
82
|
"playwright": "^1.54.1",
|
|
83
|
+
"serve": "^14.2.6",
|
|
83
84
|
"webpack-cli": "^6.0.1"
|
|
84
85
|
}
|
|
85
86
|
}
|