fancy-ui-react 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/dist/components/button/Button.js +5 -1
- package/dist/components/datamosh-transition/DatamoshTransition.d.ts +76 -0
- package/dist/components/datamosh-transition/DatamoshTransition.js +368 -0
- package/dist/components/datamosh-transition/datamosh-transition-core.d.ts +180 -0
- package/dist/components/datamosh-transition/datamosh-transition-core.js +370 -0
- package/dist/components/datamosh-transition/index.d.ts +3 -0
- package/dist/components/fluid-cursor/FluidCursor.js +48 -18
- package/dist/components/fluid-cursor/fluid-shared.d.ts +18 -0
- package/dist/components/fluid-cursor/fluid-shared.js +7 -0
- package/dist/components/fluid-cursor/webgpu-engine.d.ts +6 -0
- package/dist/components/fluid-cursor/webgpu-engine.js +24 -9
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -0
- package/dist/styles.css +75 -1
- package/package.json +1 -1
|
@@ -52,7 +52,11 @@ fn fs_splat(in: VSOut) -> @location(0) vec4f {
|
|
|
52
52
|
p.x = p.x * u.aspect;
|
|
53
53
|
let splat = exp(-dot(p, p) / u.radius) * u.color.rgb;
|
|
54
54
|
let base = textureSample(tex0, smpLinear, in.uv).rgb;
|
|
55
|
-
|
|
55
|
+
// color.a is the click flag: a click splat lifts each texel to its own
|
|
56
|
+
// profile instead of adding to it, so a burst of clicks paints the same
|
|
57
|
+
// disc once instead of summing towards white and widening every click.
|
|
58
|
+
let sum = select(base + splat, max(base, splat), u.color.a > 0.5);
|
|
59
|
+
return vec4f(sum, 1.0);
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
@fragment
|
|
@@ -233,7 +237,7 @@ async function createWebGpuFluid(canvas, opts) {
|
|
|
233
237
|
scratch[OFF_COLOR] = v.color[0];
|
|
234
238
|
scratch[OFF_COLOR + 1] = v.color[1];
|
|
235
239
|
scratch[OFF_COLOR + 2] = v.color[2];
|
|
236
|
-
scratch[OFF_COLOR + 3] =
|
|
240
|
+
scratch[OFF_COLOR + 3] = v.color[3] ?? 0;
|
|
237
241
|
}
|
|
238
242
|
scratch[OFF_DT] = v.dt ?? 0;
|
|
239
243
|
scratch[OFF_DISSIPATION] = v.dissipation ?? 0;
|
|
@@ -368,7 +372,7 @@ async function createWebGpuFluid(canvas, opts) {
|
|
|
368
372
|
canvas.height = height;
|
|
369
373
|
initTextures();
|
|
370
374
|
}
|
|
371
|
-
}, splat = function(x, y, dx, dy, color) {
|
|
375
|
+
}, splat = function(x, y, dx, dy, color, saturate = false) {
|
|
372
376
|
if (destroyed || lost || !velocity || !dye) return;
|
|
373
377
|
let radius = correctRadius(opts.splatRadius / 100, canvas.width, canvas.height);
|
|
374
378
|
if (opts.contained) {
|
|
@@ -383,7 +387,7 @@ async function createWebGpuFluid(canvas, opts) {
|
|
|
383
387
|
});
|
|
384
388
|
writeUniforms(uSplatDye, {
|
|
385
389
|
point: [x, y],
|
|
386
|
-
color: [color.r, color.g, color.b],
|
|
390
|
+
color: [color.r, color.g, color.b, saturate ? 1 : 0],
|
|
387
391
|
aspect,
|
|
388
392
|
radius
|
|
389
393
|
});
|
|
@@ -716,13 +720,15 @@ async function startWebGpuFluid(canvas, opts) {
|
|
|
716
720
|
engine.splat(pointer.texcoordX, pointer.texcoordY, dx, dy, pointer.color);
|
|
717
721
|
}
|
|
718
722
|
function clickSplat(pointer) {
|
|
719
|
-
const
|
|
720
|
-
color
|
|
721
|
-
|
|
722
|
-
|
|
723
|
+
const base = opts.generateColor();
|
|
724
|
+
const color = {
|
|
725
|
+
r: base.r * opts.clickBoost,
|
|
726
|
+
g: base.g * opts.clickBoost,
|
|
727
|
+
b: base.b * opts.clickBoost
|
|
728
|
+
};
|
|
723
729
|
const dx = 10 * (Math.random() - 0.5);
|
|
724
730
|
const dy = 30 * (Math.random() - 0.5);
|
|
725
|
-
engine.splat(pointer.texcoordX, pointer.texcoordY, dx, dy, color);
|
|
731
|
+
engine.splat(pointer.texcoordX, pointer.texcoordY, dx, dy, color, true);
|
|
726
732
|
}
|
|
727
733
|
function multipleSplats(steps) {
|
|
728
734
|
const angle = Math.random() * Math.PI * 2;
|
|
@@ -780,6 +786,9 @@ async function startWebGpuFluid(canvas, opts) {
|
|
|
780
786
|
updatePointerDownData(pointer, -1, posX, posY);
|
|
781
787
|
clickSplat(pointer);
|
|
782
788
|
}
|
|
789
|
+
function handlePointerUp() {
|
|
790
|
+
pointers[0].down = false;
|
|
791
|
+
}
|
|
783
792
|
function handleFirstMouseMove(e) {
|
|
784
793
|
const pointer = pointers[0];
|
|
785
794
|
const { x: posX, y: posY } = getCanvasPos(e.clientX, e.clientY);
|
|
@@ -826,11 +835,14 @@ async function startWebGpuFluid(canvas, opts) {
|
|
|
826
835
|
}
|
|
827
836
|
if (opts.interactive) {
|
|
828
837
|
window.addEventListener("mousedown", handleMouseDown);
|
|
838
|
+
window.addEventListener("mouseup", handlePointerUp);
|
|
829
839
|
document.body.addEventListener("mousemove", handleFirstMouseMove);
|
|
830
840
|
window.addEventListener("mousemove", handleMouseMove);
|
|
831
841
|
document.body.addEventListener("touchstart", handleFirstTouchStart);
|
|
832
842
|
window.addEventListener("touchstart", handleTouchStart, false);
|
|
833
843
|
window.addEventListener("touchmove", handleTouchMove, false);
|
|
844
|
+
window.addEventListener("touchend", handlePointerUp);
|
|
845
|
+
window.addEventListener("touchcancel", handlePointerUp);
|
|
834
846
|
}
|
|
835
847
|
let observer = null;
|
|
836
848
|
if (opts.pauseWhenHidden) {
|
|
@@ -903,11 +915,14 @@ async function startWebGpuFluid(canvas, opts) {
|
|
|
903
915
|
if (autoSplatTimer) clearInterval(autoSplatTimer);
|
|
904
916
|
if (opts.interactive) {
|
|
905
917
|
window.removeEventListener("mousedown", handleMouseDown);
|
|
918
|
+
window.removeEventListener("mouseup", handlePointerUp);
|
|
906
919
|
document.body.removeEventListener("mousemove", handleFirstMouseMove);
|
|
907
920
|
window.removeEventListener("mousemove", handleMouseMove);
|
|
908
921
|
document.body.removeEventListener("touchstart", handleFirstTouchStart);
|
|
909
922
|
window.removeEventListener("touchstart", handleTouchStart);
|
|
910
923
|
window.removeEventListener("touchmove", handleTouchMove);
|
|
924
|
+
window.removeEventListener("touchend", handlePointerUp);
|
|
925
|
+
window.removeEventListener("touchcancel", handlePointerUp);
|
|
911
926
|
}
|
|
912
927
|
if (opts.contained) {
|
|
913
928
|
window.removeEventListener("resize", updateCanvasRectCache);
|
package/dist/index.d.ts
CHANGED
|
@@ -85,6 +85,7 @@ export * from "./components/marquee/index.js";
|
|
|
85
85
|
export * from "./components/matrix-rain/index.js";
|
|
86
86
|
export * from "./components/meteors/index.js";
|
|
87
87
|
export * from "./components/mosaic-glow/index.js";
|
|
88
|
+
export * from "./components/datamosh-transition/index.js";
|
|
88
89
|
export * from "./components/navbar/index.js";
|
|
89
90
|
export * from "./components/navigation-menu/index.js";
|
|
90
91
|
export * from "./components/neon-border/index.js";
|
package/dist/index.js
CHANGED
|
@@ -134,6 +134,8 @@ import { ReviewCard } from "./components/marquee/ReviewCard.js";
|
|
|
134
134
|
import { MatrixRain } from "./components/matrix-rain/MatrixRain.js";
|
|
135
135
|
import { Meteors } from "./components/meteors/Meteors.js";
|
|
136
136
|
import { MosaicGlow } from "./components/mosaic-glow/MosaicGlow.js";
|
|
137
|
+
import { DatamoshTransition } from "./components/datamosh-transition/DatamoshTransition.js";
|
|
138
|
+
import { DATAMOSH_PALETTES } from "./components/datamosh-transition/datamosh-transition-core.js";
|
|
137
139
|
import { Navbar } from "./components/navbar/Navbar.js";
|
|
138
140
|
import { NavbarLink } from "./components/navbar/NavbarLink.js";
|
|
139
141
|
import { NavigationMenu } from "./components/navigation-menu/NavigationMenu.js";
|
|
@@ -302,9 +304,11 @@ export {
|
|
|
302
304
|
ContextMenuTrigger,
|
|
303
305
|
ContextRing,
|
|
304
306
|
CopyButton,
|
|
307
|
+
DATAMOSH_PALETTES,
|
|
305
308
|
DEFAULT_SOUND_FEEDBACK_ON,
|
|
306
309
|
DEFAULT_SOUND_PREFERENCES,
|
|
307
310
|
DROPDOWN_MENU_KEY,
|
|
311
|
+
DatamoshTransition,
|
|
308
312
|
DatePicker,
|
|
309
313
|
Dialog,
|
|
310
314
|
DimSiblings,
|
package/dist/styles.css
CHANGED
|
@@ -313,7 +313,81 @@
|
|
|
313
313
|
* scales the panel about its own centre without touching the centring.
|
|
314
314
|
*/
|
|
315
315
|
.ft-btn {
|
|
316
|
-
--ft-btn-accent: var(
|
|
316
|
+
--ft-btn-accent: var(
|
|
317
|
+
--ft-accent,
|
|
318
|
+
light-dark(oklch(0.5432 0.2528 300.22), oklch(0.604 0.2606 301.75))
|
|
319
|
+
);
|
|
320
|
+
/* 150ms = tokens.DURATIONS.fast, cubic-bezier(0.4, 0, 0.2, 1) =
|
|
321
|
+
tokens.EASINGS.inout — the reversible-state pair. It runs the colour
|
|
322
|
+
channel, and the release half of the press: letting go settles, it does
|
|
323
|
+
not snap back. */
|
|
324
|
+
--ft-btn-motion: var(--ft-duration-fast, 150ms) var(--ft-ease-inout, cubic-bezier(0.4, 0, 0.2, 1));
|
|
325
|
+
/* The down-stroke only. 150ms = tokens.DURATIONS.fast,
|
|
326
|
+
cubic-bezier(0.16, 1, 0.3, 1) = tokens.EASINGS.out — the arrival curve,
|
|
327
|
+
which spends most of the scale in the first frames, so the press bites
|
|
328
|
+
instead of easing in. Pressing is an arrival; releasing is what resolves
|
|
329
|
+
either way. */
|
|
330
|
+
--ft-btn-press: var(--ft-duration-fast, 150ms) var(--ft-ease-out, cubic-bezier(0.16, 1, 0.3, 1));
|
|
331
|
+
/*
|
|
332
|
+
* Replaces the `transition-colors` utility removed from the class string,
|
|
333
|
+
* at exactly the values that utility already resolved to. Colour is a state
|
|
334
|
+
* change, not motion, so it stays OUTSIDE the reduced-motion query — gating
|
|
335
|
+
* it would only make a theme flip look broken for the people who asked for
|
|
336
|
+
* less movement.
|
|
337
|
+
*
|
|
338
|
+
* `box-shadow` is deliberately absent, and must stay absent: this button's
|
|
339
|
+
* focus ring is `focus-visible:ring-*`, which compiles to a `box-shadow`,
|
|
340
|
+
* and a focus ring must never animate.
|
|
341
|
+
*/
|
|
342
|
+
transition:
|
|
343
|
+
color var(--ft-btn-motion),
|
|
344
|
+
background-color var(--ft-btn-motion),
|
|
345
|
+
border-color var(--ft-btn-motion);
|
|
346
|
+
/* Kills the ~300ms tap delay without blocking scroll. A press that answers
|
|
347
|
+
a third of a second late is not press feedback. */
|
|
348
|
+
touch-action: manipulation;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/*
|
|
352
|
+
* The press. Pressable's contract inlined as a plain rule on the native
|
|
353
|
+
* control rather than wrapping a `<button>` in a `<Pressable>` div — same
|
|
354
|
+
* `0.97`, same clock, one element instead of two.
|
|
355
|
+
*
|
|
356
|
+
* Only the property list is re-declared in here: `transform` joins the colour
|
|
357
|
+
* channel under `no-preference` and nowhere else, so with motion reduced the
|
|
358
|
+
* colours still cross and the button simply does not move. The resting state
|
|
359
|
+
* (no `transform` at all) is the ungated fallback.
|
|
360
|
+
*
|
|
361
|
+
* The two strokes are timed apart. The rule below carries the release curve,
|
|
362
|
+
* because that is the transition the button runs on its way back to rest;
|
|
363
|
+
* `:active` overrides `transform` with the arrival curve for the way down.
|
|
364
|
+
*/
|
|
365
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
366
|
+
.ft-btn {
|
|
367
|
+
transition:
|
|
368
|
+
color var(--ft-btn-motion),
|
|
369
|
+
background-color var(--ft-btn-motion),
|
|
370
|
+
border-color var(--ft-btn-motion),
|
|
371
|
+
transform var(--ft-btn-motion);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/* Both inert states are excluded so a press that does nothing does not
|
|
375
|
+
pretend to. `[data-disabled]` is the anchor branch, which has no native
|
|
376
|
+
`:disabled` to hang this off; `[aria-busy]` is the loading one, on both
|
|
377
|
+
branches. A native disabled `<button>` never matches `:active` anyway —
|
|
378
|
+
the attribute selectors are what make the anchor behave like it. */
|
|
379
|
+
.ft-btn:not([data-disabled="true"]):not([aria-busy="true"]):active {
|
|
380
|
+
transform: scale(0.97);
|
|
381
|
+
/* The whole list is re-declared rather than just
|
|
382
|
+
`transition-timing-function`, which has no per-property form here: a
|
|
383
|
+
single value would retime the colour channel too. Only `transform`
|
|
384
|
+
differs from the rule above. */
|
|
385
|
+
transition:
|
|
386
|
+
color var(--ft-btn-motion),
|
|
387
|
+
background-color var(--ft-btn-motion),
|
|
388
|
+
border-color var(--ft-btn-motion),
|
|
389
|
+
transform var(--ft-btn-press);
|
|
390
|
+
}
|
|
317
391
|
}
|
|
318
392
|
|
|
319
393
|
.ft-btn--accent {
|
package/package.json
CHANGED