nodality 1.0.194 → 1.0.196
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/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/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/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/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/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/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/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 +120 -21
- 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 +1 -1
package/lib/raster-ops.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* nodality v1.0.
|
|
2
|
+
* nodality v1.0.196
|
|
3
3
|
* (c) 2026 Filip Vabrousek
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -170,16 +170,17 @@ const REGISTRY = {
|
|
|
170
170
|
// samples the finished field. See the `field` descriptor below and
|
|
171
171
|
// the field-simulation block in applyRasterPipeline().
|
|
172
172
|
//
|
|
173
|
-
// Formulation
|
|
174
|
-
//
|
|
175
|
-
// a
|
|
176
|
-
//
|
|
177
|
-
//
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
//
|
|
181
|
-
//
|
|
182
|
-
//
|
|
173
|
+
// Formulation: the classic GPU Stable-Fluids pipeline (Stam 1999;
|
|
174
|
+
// Harris, GPU Gems 2003) — splat, curl, vorticity confinement,
|
|
175
|
+
// divergence, a Jacobi pressure solve, gradient subtraction, then
|
|
176
|
+
// semi-Lagrangian advection of velocity and dye. See the provenance
|
|
177
|
+
// note on the `stir` field descriptor below for the citations and
|
|
178
|
+
// for what this op inherits from existing implementations.
|
|
179
|
+
//
|
|
180
|
+
// An earlier version of this comment claimed the op was a single
|
|
181
|
+
// pass with no pressure projection. It never was — the solver has
|
|
182
|
+
// always run the full projection, which is what makes the flow roll
|
|
183
|
+
// into persistent vortices rather than smear.
|
|
183
184
|
//
|
|
184
185
|
// { op: "stir", strength: 26, curl: 2.4, decay: 0.985 }
|
|
185
186
|
//
|
|
@@ -544,8 +545,31 @@ void main() {
|
|
|
544
545
|
// Stirred liquid: an incompressible fluid whose velocity field warps
|
|
545
546
|
// the content and whose dye field colours it.
|
|
546
547
|
//
|
|
547
|
-
//
|
|
548
|
-
// existing
|
|
548
|
+
// Provenance. The solver was written from the published papers, and
|
|
549
|
+
// no code was copied from an existing implementation — the neighbour
|
|
550
|
+
// taps are computed in-fragment from gl_FragCoord rather than passed
|
|
551
|
+
// down as vL/vR/vT/vB varyings, advection samples directly instead of
|
|
552
|
+
// through a hand-rolled bilerp(), and the rainbow hue comes from the
|
|
553
|
+
// stroke direction rather than a random HSV pick. But it is not
|
|
554
|
+
// independent of that lineage either, and two things are inherited
|
|
555
|
+
// rather than derived from the papers:
|
|
556
|
+
//
|
|
557
|
+
// - The option vocabulary and several defaults (curl, pressure,
|
|
558
|
+
// pressureIterations, radius, force, intensity, rainbow,
|
|
559
|
+
// dyeResolution; resolution 128, dyeResolution 512, pressure 0.8)
|
|
560
|
+
// follow the conventions of Pavel Dobryakov's
|
|
561
|
+
// WebGL-Fluid-Simulation (MIT) and its many descendants.
|
|
562
|
+
// - The free-slip boundary handling — four inline conditionals in
|
|
563
|
+
// the divergence shader that mirror the centre velocity at the
|
|
564
|
+
// walls — is that codebase's approach. Stam and Harris both use a
|
|
565
|
+
// separate boundary pass over border geometry instead.
|
|
566
|
+
//
|
|
567
|
+
// Everything below that looks identical to other implementations
|
|
568
|
+
// beyond those two points is identical because the mathematics admits
|
|
569
|
+
// one spelling: (r+l+t+b-d)*0.25 is the Jacobi iteration as printed
|
|
570
|
+
// in GPU Gems 38, and the divergence, curl and confinement kernels
|
|
571
|
+
// are the standard central differences.
|
|
572
|
+
//
|
|
549
573
|
// J. Stam, "Stable Fluids", SIGGRAPH '99, 121-128 - the
|
|
550
574
|
// unconditionally stable operator splitting used here: add
|
|
551
575
|
// forces, advect by a backward particle trace, then project the
|
|
@@ -1425,11 +1449,18 @@ function freezeViewportUnits(original, clone) {
|
|
|
1425
1449
|
*/
|
|
1426
1450
|
function soleImageOf(el) {
|
|
1427
1451
|
if (!el) return null;
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1452
|
+
let img = null;
|
|
1453
|
+
if (el.tagName === "IMG") {
|
|
1454
|
+
img = el;
|
|
1455
|
+
} else if (el.children) {
|
|
1456
|
+
// Ignore the pipeline's own canvas: by the time a capture runs it has
|
|
1457
|
+
// already been appended to the host, so a strict one-child test never
|
|
1458
|
+
// matches and a wrapped photo falls back to the foreignObject path —
|
|
1459
|
+
// which cannot fetch the image and captures blank.
|
|
1460
|
+
const content = Array.prototype.filter.call(
|
|
1461
|
+
el.children, (n) => !n.hasAttribute || !n.hasAttribute("data-nodality-raster"));
|
|
1462
|
+
if (content.length === 1 && content[0].tagName === "IMG") img = content[0];
|
|
1463
|
+
}
|
|
1433
1464
|
if (!img || !img.complete || !img.naturalWidth) return null;
|
|
1434
1465
|
try {
|
|
1435
1466
|
// Relative and same-origin absolute srcs both resolve clean here.
|
|
@@ -1442,9 +1473,70 @@ function soleImageOf(el) {
|
|
|
1442
1473
|
return img;
|
|
1443
1474
|
}
|
|
1444
1475
|
|
|
1476
|
+
/**
|
|
1477
|
+
* Draw `img` into an offscreen canvas at the host's box, honouring the
|
|
1478
|
+
* element's own `object-fit` / `object-position`.
|
|
1479
|
+
*
|
|
1480
|
+
* The pipeline samples its texture as `fragCoord / u_res`, i.e. stretched
|
|
1481
|
+
* across the whole quad. That is right for a DOM snapshot, which is captured
|
|
1482
|
+
* at the canvas aspect — but the direct-image path uploads the source at its
|
|
1483
|
+
* NATURAL aspect, so any host whose box is a different shape rendered the
|
|
1484
|
+
* photo distorted, and `object-fit: cover` no longer had any say because the
|
|
1485
|
+
* image was no longer being laid out by CSS at all.
|
|
1486
|
+
*
|
|
1487
|
+
* Baking the fit in here keeps it out of the shader and means the texture
|
|
1488
|
+
* always arrives pre-cropped to the box the quad expects.
|
|
1489
|
+
*/
|
|
1490
|
+
function fitImageToBox(img, w, h, dpr) {
|
|
1491
|
+
const cw = Math.max(1, Math.round(w * dpr));
|
|
1492
|
+
const ch = Math.max(1, Math.round(h * dpr));
|
|
1493
|
+
const iw = img.naturalWidth, ih = img.naturalHeight;
|
|
1494
|
+
if (!iw || !ih) return img;
|
|
1495
|
+
|
|
1496
|
+
let fit = "fill", pos = "50% 50%";
|
|
1497
|
+
if (typeof getComputedStyle === "function") {
|
|
1498
|
+
const cs = getComputedStyle(img);
|
|
1499
|
+
fit = cs.objectFit || "fill";
|
|
1500
|
+
pos = cs.objectPosition || "50% 50%";
|
|
1501
|
+
}
|
|
1502
|
+
// `fill` is the CSS default and matches the old stretch behaviour, so
|
|
1503
|
+
// leave those callers on the cheap path.
|
|
1504
|
+
if (fit === "fill") return img;
|
|
1505
|
+
|
|
1506
|
+
const sx = cw / iw, sy = ch / ih;
|
|
1507
|
+
const scale = fit === "cover" ? Math.max(sx, sy)
|
|
1508
|
+
: fit === "contain" ? Math.min(sx, sy)
|
|
1509
|
+
: fit === "none" ? 1
|
|
1510
|
+
: fit === "scale-down" ? Math.min(1, Math.min(sx, sy))
|
|
1511
|
+
: Math.max(sx, sy);
|
|
1512
|
+
|
|
1513
|
+
const dw = iw * scale, dh = ih * scale;
|
|
1514
|
+
// object-position: percentages position the overflow, so 0% pins the
|
|
1515
|
+
// near edge and 100% the far edge.
|
|
1516
|
+
const parts = String(pos).trim().split(/\s+/);
|
|
1517
|
+
const frac = (v, i) => {
|
|
1518
|
+
if (v == null) return 0.5;
|
|
1519
|
+
if (v.endsWith("%")) return parseFloat(v) / 100;
|
|
1520
|
+
if (v === "left" || v === "top") return 0;
|
|
1521
|
+
if (v === "right" || v === "bottom") return 1;
|
|
1522
|
+
if (v === "center") return 0.5;
|
|
1523
|
+
const px = parseFloat(v);
|
|
1524
|
+
return isNaN(px) ? 0.5 : px / (i === 0 ? Math.max(cw - dw, 1) : Math.max(ch - dh, 1));
|
|
1525
|
+
};
|
|
1526
|
+
const fx = frac(parts[0], 0);
|
|
1527
|
+
const fy = frac(parts.length > 1 ? parts[1] : parts[0], 1);
|
|
1528
|
+
|
|
1529
|
+
const c = document.createElement("canvas");
|
|
1530
|
+
c.width = cw; c.height = ch;
|
|
1531
|
+
const ctx = c.getContext("2d");
|
|
1532
|
+
if (!ctx) return img;
|
|
1533
|
+
ctx.drawImage(img, (cw - dw) * fx, (ch - dh) * fy, dw, dh);
|
|
1534
|
+
return c;
|
|
1535
|
+
}
|
|
1536
|
+
|
|
1445
1537
|
function snapshotToImage(el, w, h, dpr) {
|
|
1446
1538
|
const direct = soleImageOf(el);
|
|
1447
|
-
if (direct) return Promise.resolve(direct);
|
|
1539
|
+
if (direct) return Promise.resolve(fitImageToBox(direct, w, h, dpr));
|
|
1448
1540
|
|
|
1449
1541
|
return new Promise((resolve, reject) => {
|
|
1450
1542
|
const serialized = new XMLSerializer()
|
|
@@ -1622,11 +1714,18 @@ function applyRasterPipeline(el, rasterNodes) {
|
|
|
1622
1714
|
// Content-box measurement: some elements (fluid-sized Text) keep a
|
|
1623
1715
|
// collapsed layout box while their glyphs overflow it, so fall back
|
|
1624
1716
|
// to scroll dimensions when the rect is degenerate.
|
|
1717
|
+
//
|
|
1718
|
+
// The fallback is per-axis and only for a genuinely collapsed box. It
|
|
1719
|
+
// used to be an unconditional max(rect, scroll), which cannot shrink:
|
|
1720
|
+
// the canvas is a CHILD of the measured element, so once it has been
|
|
1721
|
+
// sized up its own width holds scrollWidth at the old value, the max
|
|
1722
|
+
// never comes down, and a host that is animating smaller (a hero
|
|
1723
|
+
// collapsing as you scroll back up) leaves the canvas stuck wide.
|
|
1625
1724
|
const measure = () => {
|
|
1626
1725
|
const r = el.getBoundingClientRect();
|
|
1627
1726
|
return {
|
|
1628
|
-
width:
|
|
1629
|
-
height:
|
|
1727
|
+
width: r.width >= 2 ? r.width : (el.scrollWidth || 0),
|
|
1728
|
+
height: r.height >= 2 ? r.height : (el.scrollHeight || 0),
|
|
1630
1729
|
};
|
|
1631
1730
|
};
|
|
1632
1731
|
const rect = measure();
|
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