fancy-ui-react 0.2.1 → 0.4.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 +56 -20
- package/dist/components/animated-beam/AnimatedBeam.d.ts +47 -11
- package/dist/components/animated-beam/AnimatedBeam.js +293 -118
- package/dist/components/animated-tooltip/AnimatedTooltip.d.ts +10 -1
- package/dist/components/animated-tooltip/AnimatedTooltip.js +170 -101
- package/dist/components/bento-grid/BentoFrame.d.ts +16 -0
- package/dist/components/bento-grid/BentoFrame.js +28 -0
- package/dist/components/bento-grid/BentoGrid.d.ts +5 -1
- package/dist/components/bento-grid/BentoGrid.js +71 -2
- package/dist/components/bento-grid/BentoGridCard.js +34 -26
- package/dist/components/bento-grid/BentoGridItem.js +10 -10
- package/dist/components/border-beam/BorderBeam.d.ts +55 -10
- package/dist/components/border-beam/BorderBeam.js +93 -16
- package/dist/components/button/Button.js +5 -1
- package/dist/components/compare/Compare.d.ts +32 -8
- package/dist/components/compare/Compare.js +213 -95
- package/dist/components/container-scroll/ContainerScroll.d.ts +26 -4
- package/dist/components/container-scroll/ContainerScroll.js +88 -49
- 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/dock/Dock.d.ts +10 -7
- package/dist/components/dock/Dock.js +76 -31
- package/dist/components/dock/DockIcon.d.ts +14 -3
- package/dist/components/dock/DockIcon.js +23 -19
- package/dist/components/dock/DockSeparator.d.ts +4 -1
- package/dist/components/dock/DockSeparator.js +5 -2
- package/dist/components/dock/types.d.ts +13 -6
- package/dist/components/dropdown-menu/menu-shared.d.ts +11 -8
- package/dist/components/editorial-engine/engine.js +1 -14
- package/dist/components/fireworks-hdr/webgl2-renderer.js +0 -19
- package/dist/components/fireworks-hdr/webgpu-renderer.js +3 -22
- package/dist/components/flip-card/FlipCard.d.ts +42 -1
- package/dist/components/flip-card/FlipCard.js +178 -25
- package/dist/components/flip-card/index.d.ts +1 -1
- package/dist/components/fluid-cursor/FluidCursor.js +5 -4
- package/dist/components/fluid-cursor/dev.d.ts +1 -0
- package/dist/components/fluid-cursor/dev.js +8 -0
- package/dist/components/fluid-cursor/fluid-shared.d.ts +0 -2
- package/dist/components/fluid-cursor/fluid-shared.js +0 -2
- package/dist/components/fluid-cursor/webgpu-engine.js +10 -24
- package/dist/components/glow-border/GlowBorder.d.ts +41 -1
- package/dist/components/glow-border/GlowBorder.js +96 -16
- package/dist/components/glow-border/index.d.ts +2 -2
- package/dist/components/gradient-button/GradientButton.d.ts +10 -5
- package/dist/components/gradient-button/GradientButton.js +25 -18
- package/dist/components/image-trail-cursor/ImageTrailCursor.js +1 -0
- package/dist/components/image-trail-cursor/trail-variants.d.ts +37 -1
- package/dist/components/image-trail-cursor/trail-variants.js +331 -8
- package/dist/components/interactive-hover-button/InteractiveHoverButton.js +30 -35
- package/dist/components/marquee/Marquee.d.ts +7 -3
- package/dist/components/marquee/Marquee.js +134 -2
- package/dist/components/marquee/ReviewCard.d.ts +2 -1
- package/dist/components/marquee/ReviewCard.js +20 -9
- package/dist/components/meteors/Meteors.d.ts +32 -10
- package/dist/components/meteors/Meteors.js +53 -20
- package/dist/components/mosaic-glow/mosaic-glow-core.d.ts +98 -10
- package/dist/components/neon-border/NeonBorder.d.ts +24 -5
- package/dist/components/neon-border/NeonBorder.js +37 -7
- package/dist/components/pagination/Pagination.js +220 -82
- package/dist/components/rainbow-button/RainbowButton.js +13 -5
- package/dist/components/ripple-button/RippleButton.d.ts +20 -1
- package/dist/components/ripple-button/RippleButton.js +44 -21
- package/dist/components/shimmer-button/ShimmerButton.d.ts +5 -5
- package/dist/components/shimmer-button/ShimmerButton.js +17 -19
- package/dist/components/smooth-cursor/SmoothCursor.d.ts +13 -9
- package/dist/components/smooth-cursor/SmoothCursor.js +114 -163
- package/dist/components/smooth-cursor/smooth-cursor-core.d.ts +85 -0
- package/dist/components/smooth-cursor/smooth-cursor-core.js +327 -0
- package/dist/components/stepper/Step.js +32 -19
- package/dist/components/stepper/Stepper.js +18 -2
- package/dist/components/stepper/types.d.ts +13 -0
- package/dist/components/timeline/Timeline.d.ts +8 -1
- package/dist/components/timeline/Timeline.js +165 -76
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -1
- package/dist/internals/markdown.d.ts +5 -0
- package/dist/internals/motion/haptics.d.ts +0 -4
- package/dist/internals/motion/presence-core.d.ts +59 -0
- package/dist/internals/motion/presence-core.js +162 -0
- package/dist/internals/motion/presence.d.ts +2 -4
- package/dist/internals/motion/presence.js +1 -156
- package/dist/internals/motion/raf.d.ts +1 -1
- package/dist/internals/motion/stagger.d.ts +3 -4
- package/dist/internals/motion/tokens.js +4 -0
- package/dist/internals/motion/transitions.d.ts +17 -17
- package/dist/internals/motion/types.d.ts +6 -7
- package/dist/internals/relative-time.d.ts +1 -1
- package/dist/styles.css +3545 -204
- package/package.json +18 -2
- package/dist/components/fireworks-hdr/webgpu-types.d.ts +0 -159
|
@@ -4,25 +4,29 @@ import { forwardRef } from "react";
|
|
|
4
4
|
import { cn } from "../../utils.js";
|
|
5
5
|
import { useSoundCue } from "../../sound/use-sound.js";
|
|
6
6
|
/* empty css */
|
|
7
|
-
|
|
8
|
-
"#
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
];
|
|
7
|
+
function beamGradient(colors) {
|
|
8
|
+
const list = colors.length ? colors : ["#ffffff"];
|
|
9
|
+
const arc = (from, to, strength) => {
|
|
10
|
+
const span = to - from;
|
|
11
|
+
const stops = list.map((c, i) => {
|
|
12
|
+
const at = from + span * ((i + 1) / (list.length + 1));
|
|
13
|
+
const color = strength < 100 ? `color-mix(in srgb, ${c} ${strength}%, transparent)` : c;
|
|
14
|
+
return `${color} ${at.toFixed(1)}%`;
|
|
15
|
+
});
|
|
16
|
+
return [`transparent ${from}%`, ...stops, `transparent ${to}%`].join(", ");
|
|
17
|
+
};
|
|
18
|
+
return `conic-gradient(from var(--gb-angle), ${arc(0, 42, 100)}, ${arc(50, 78, 45)}, transparent 100%)`;
|
|
19
|
+
}
|
|
20
|
+
const DEFAULT_COLORS = ["#34d399", "#22d3ee", "#6366f1", "#d946ef", "#f43f5e", "#f59e0b"];
|
|
17
21
|
const GradientButton = forwardRef(
|
|
18
22
|
({
|
|
19
23
|
className,
|
|
20
24
|
colors = DEFAULT_COLORS,
|
|
21
|
-
duration =
|
|
22
|
-
borderWidth =
|
|
23
|
-
borderRadius =
|
|
25
|
+
duration = 3e3,
|
|
26
|
+
borderWidth = 1.5,
|
|
27
|
+
borderRadius = 12,
|
|
24
28
|
blur = 4,
|
|
25
|
-
bgColor = "#
|
|
29
|
+
bgColor = "#161616",
|
|
26
30
|
children,
|
|
27
31
|
onClick,
|
|
28
32
|
sound = false,
|
|
@@ -35,6 +39,7 @@ const GradientButton = forwardRef(
|
|
|
35
39
|
}
|
|
36
40
|
const styleVars = {
|
|
37
41
|
"--gb-colors": colors.join(", "),
|
|
42
|
+
"--gb-beam": beamGradient(colors),
|
|
38
43
|
"--gb-duration": `${duration}ms`,
|
|
39
44
|
"--gb-border-width": `${borderWidth}px`,
|
|
40
45
|
"--gb-border-radius": `${borderRadius}px`,
|
|
@@ -46,15 +51,16 @@ const GradientButton = forwardRef(
|
|
|
46
51
|
{
|
|
47
52
|
ref,
|
|
48
53
|
className: cn(
|
|
49
|
-
"gradient-button relative flex min-h-10 min-w-28 cursor-pointer items-center justify-center overflow-hidden",
|
|
54
|
+
"gradient-button relative flex min-h-10 min-w-28 cursor-pointer items-center justify-center overflow-hidden text-white",
|
|
50
55
|
className
|
|
51
56
|
),
|
|
52
57
|
style: styleVars,
|
|
53
58
|
onClick: handleClick,
|
|
54
59
|
...restProps,
|
|
55
60
|
children: [
|
|
56
|
-
/* @__PURE__ */ jsx("span", { className: "gradient-
|
|
57
|
-
/* @__PURE__ */ jsx("span", { className: "gradient-
|
|
61
|
+
/* @__PURE__ */ jsx("span", { className: "gradient-content inline-flex size-full items-center justify-center px-5 py-2.5", children }),
|
|
62
|
+
/* @__PURE__ */ jsx("span", { className: "gradient-glow", "aria-hidden": "true", children: /* @__PURE__ */ jsx("span", {}) }),
|
|
63
|
+
/* @__PURE__ */ jsx("span", { className: "gradient-border", "aria-hidden": "true" })
|
|
58
64
|
]
|
|
59
65
|
}
|
|
60
66
|
);
|
|
@@ -62,5 +68,6 @@ const GradientButton = forwardRef(
|
|
|
62
68
|
);
|
|
63
69
|
GradientButton.displayName = "GradientButton";
|
|
64
70
|
export {
|
|
65
|
-
GradientButton
|
|
71
|
+
GradientButton,
|
|
72
|
+
beamGradient
|
|
66
73
|
};
|
|
@@ -7,6 +7,7 @@ function resetImageStyles(container) {
|
|
|
7
7
|
const imgEls = container.querySelectorAll(".content__img");
|
|
8
8
|
for (const el of imgEls) {
|
|
9
9
|
el.style.cssText = "";
|
|
10
|
+
for (const frag of el.querySelectorAll(".content__img-frag")) frag.remove();
|
|
10
11
|
const inner = el.querySelector(".content__img-inner");
|
|
11
12
|
if (inner) {
|
|
12
13
|
const bgImage = inner.style.backgroundImage;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type VariantType = "type1" | "type2" | "type3" | "type4" | "type5" | "type6" | "type7" | "type8" | "pixelated";
|
|
1
|
+
export type VariantType = "type1" | "type2" | "type3" | "type4" | "type5" | "type6" | "type7" | "type8" | "pixelated" | "scale" | "fall" | "gravity" | "flame" | "venetian" | "curtain" | "hexagon" | "liquid" | "zoom-split";
|
|
2
2
|
export interface ImageTrailVariant {
|
|
3
3
|
destroy(): void;
|
|
4
4
|
}
|
|
@@ -60,6 +60,8 @@ declare abstract class BaseVariant implements ImageTrailVariant {
|
|
|
60
60
|
protected render(): void;
|
|
61
61
|
protected updateCache(): void;
|
|
62
62
|
protected abstract showNextImage(): void;
|
|
63
|
+
/** Advance to the next image in the ring. */
|
|
64
|
+
protected nextImage(): ImageItem | undefined;
|
|
63
65
|
protected onImageActivated(): void;
|
|
64
66
|
protected onImageDeactivated(): void;
|
|
65
67
|
destroy(): void;
|
|
@@ -108,5 +110,39 @@ export declare class ImageTrailVariantPixelated extends BaseVariant {
|
|
|
108
110
|
constructor(container: HTMLDivElement);
|
|
109
111
|
protected showNextImage(): void;
|
|
110
112
|
}
|
|
113
|
+
export declare class ImageTrailVariantScale extends BaseVariant {
|
|
114
|
+
protected showNextImage(): void;
|
|
115
|
+
}
|
|
116
|
+
export declare class ImageTrailVariantFall extends BaseVariant {
|
|
117
|
+
protected showNextImage(): void;
|
|
118
|
+
}
|
|
119
|
+
export declare class ImageTrailVariantGravity extends BaseVariant {
|
|
120
|
+
protected showNextImage(): void;
|
|
121
|
+
}
|
|
122
|
+
export declare class ImageTrailVariantFlame extends BaseVariant {
|
|
123
|
+
protected showNextImage(): void;
|
|
124
|
+
}
|
|
125
|
+
export type RevealPattern = "venetian" | "curtain" | "hexagon" | "liquid" | "zoom-split";
|
|
126
|
+
export interface RevealFragment {
|
|
127
|
+
/** clip-path while hidden */
|
|
128
|
+
closed: string;
|
|
129
|
+
/** clip-path once revealed */
|
|
130
|
+
open: string;
|
|
131
|
+
/** 0 (first) … 1 (last): when the fragment opens within the stagger */
|
|
132
|
+
order: number;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* The fragments of each reveal, as clip-paths in the image's own box.
|
|
136
|
+
* `closed` and `open` always have the same shape and point count, so the
|
|
137
|
+
* tween between them is a straight interpolation.
|
|
138
|
+
*/
|
|
139
|
+
export declare function revealFragments(pattern: RevealPattern): RevealFragment[];
|
|
140
|
+
export declare class ImageTrailVariantReveal extends BaseVariant {
|
|
141
|
+
private static readonly STAGGER;
|
|
142
|
+
private readonly fragments;
|
|
143
|
+
constructor(container: HTMLDivElement, pattern: RevealPattern);
|
|
144
|
+
protected showNextImage(): void;
|
|
145
|
+
destroy(): void;
|
|
146
|
+
}
|
|
111
147
|
export declare const variantMap: Record<VariantType, new (container: HTMLDivElement) => ImageTrailVariant>;
|
|
112
148
|
export {};
|
|
@@ -37,12 +37,12 @@ class ImageItem {
|
|
|
37
37
|
el: null,
|
|
38
38
|
inner: null
|
|
39
39
|
};
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
40
|
+
// `private`, not `public`: the animation library declares `TweenVars` inside a
|
|
41
|
+
// GLOBAL namespace with no module-level export, so a public `gsap.TweenVars`
|
|
42
|
+
// member emits a bare `gsap.` reference into the shipped .d.ts while tsc drops
|
|
43
|
+
// the value-only `import { gsap }` — deep-importing consumers then hit TS2503
|
|
44
|
+
// "Cannot find namespace 'gsap'". A private member emits no type at all, and it
|
|
45
|
+
// is read only by initEvents() below, so nothing outside this class loses access.
|
|
46
46
|
defaultStyle = { scale: 1, x: 0, y: 0, opacity: 0 };
|
|
47
47
|
rect = null;
|
|
48
48
|
resizeHandler = null;
|
|
@@ -164,7 +164,8 @@ class BaseVariant {
|
|
|
164
164
|
const now = performance.now();
|
|
165
165
|
this.positionHistory.push({ x, y, t: now });
|
|
166
166
|
const cutoff = now - BaseVariant.HISTORY_MAX_AGE;
|
|
167
|
-
while (this.positionHistory.length > BaseVariant.HISTORY_MAX_LEN ||
|
|
167
|
+
while (this.positionHistory.length > BaseVariant.HISTORY_MAX_LEN || // Non-null: `length > 1` on this same clause proves index 0 exists.
|
|
168
|
+
this.positionHistory.length > 1 && this.positionHistory[0].t < cutoff) {
|
|
168
169
|
this.positionHistory.shift();
|
|
169
170
|
}
|
|
170
171
|
}
|
|
@@ -203,6 +204,11 @@ class BaseVariant {
|
|
|
203
204
|
this.cacheMousePos.x = lerp(this.cacheMousePos.x, this.mousePos.x, 0.1);
|
|
204
205
|
this.cacheMousePos.y = lerp(this.cacheMousePos.y, this.mousePos.y, 0.1);
|
|
205
206
|
}
|
|
207
|
+
/** Advance to the next image in the ring. */
|
|
208
|
+
nextImage() {
|
|
209
|
+
this.imgPosition = this.imgPosition < this.imagesTotal - 1 ? this.imgPosition + 1 : 0;
|
|
210
|
+
return this.images[this.imgPosition];
|
|
211
|
+
}
|
|
206
212
|
onImageActivated() {
|
|
207
213
|
this.activeImagesCount++;
|
|
208
214
|
this.isIdle = false;
|
|
@@ -761,6 +767,308 @@ class ImageTrailVariantPixelated extends BaseVariant {
|
|
|
761
767
|
).set(img.DOM.el, { opacity: 0, scale: 0.2 }, ImageTrailVariantPixelated.HOLD);
|
|
762
768
|
}
|
|
763
769
|
}
|
|
770
|
+
function randomBetween(min, max) {
|
|
771
|
+
return min + Math.random() * (max - min);
|
|
772
|
+
}
|
|
773
|
+
class ImageTrailVariantScale extends BaseVariant {
|
|
774
|
+
showNextImage() {
|
|
775
|
+
++this.zIndexVal;
|
|
776
|
+
const img = this.nextImage();
|
|
777
|
+
if (!img) return;
|
|
778
|
+
const w = img.rect?.width ?? 0;
|
|
779
|
+
const h = img.rect?.height ?? 0;
|
|
780
|
+
gsap.killTweensOf(img.DOM.el);
|
|
781
|
+
gsap.timeline({
|
|
782
|
+
onStart: () => this.onImageActivated(),
|
|
783
|
+
onComplete: () => this.onImageDeactivated()
|
|
784
|
+
}).set(img.DOM.el, {
|
|
785
|
+
opacity: 1,
|
|
786
|
+
scale: 0,
|
|
787
|
+
rotation: randomBetween(-20, 20),
|
|
788
|
+
zIndex: this.zIndexVal,
|
|
789
|
+
x: this.mousePos.x - w / 2,
|
|
790
|
+
y: this.mousePos.y - h / 2
|
|
791
|
+
}).to(img.DOM.el, { scale: 1, duration: 0.6, ease: "back.out(2)" }, 0).to(img.DOM.el, { scale: 0, duration: 0.6, ease: "power2.in" }, 0.75).set(img.DOM.el, { opacity: 0 });
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
class ImageTrailVariantFall extends BaseVariant {
|
|
795
|
+
showNextImage() {
|
|
796
|
+
++this.zIndexVal;
|
|
797
|
+
const img = this.nextImage();
|
|
798
|
+
if (!img) return;
|
|
799
|
+
const w = img.rect?.width ?? 0;
|
|
800
|
+
const h = img.rect?.height ?? 0;
|
|
801
|
+
const floor = this.container.getBoundingClientRect().height;
|
|
802
|
+
gsap.killTweensOf(img.DOM.el);
|
|
803
|
+
gsap.timeline({
|
|
804
|
+
onStart: () => this.onImageActivated(),
|
|
805
|
+
onComplete: () => this.onImageDeactivated()
|
|
806
|
+
}).set(img.DOM.el, {
|
|
807
|
+
opacity: 1,
|
|
808
|
+
scale: 0,
|
|
809
|
+
rotation: 0,
|
|
810
|
+
zIndex: this.zIndexVal,
|
|
811
|
+
x: this.mousePos.x - w / 2,
|
|
812
|
+
y: this.mousePos.y - h / 2
|
|
813
|
+
}).to(img.DOM.el, { scale: 1, duration: 0.8, ease: "elastic.out(1, 0.3)" }, 0).to(img.DOM.el, { rotation: randomBetween(-360, 360), duration: 1.1, ease: "power1.out" }, 0).to(img.DOM.el, { y: floor * 1.2 + h, duration: 1, ease: "back.in(0.4)" }, 0).set(img.DOM.el, { opacity: 0 });
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
class ImageTrailVariantGravity extends BaseVariant {
|
|
817
|
+
showNextImage() {
|
|
818
|
+
++this.zIndexVal;
|
|
819
|
+
const img = this.nextImage();
|
|
820
|
+
if (!img) return;
|
|
821
|
+
const w = img.rect?.width ?? 0;
|
|
822
|
+
const h = img.rect?.height ?? 0;
|
|
823
|
+
const height = this.container.getBoundingClientRect().height;
|
|
824
|
+
const startY = this.mousePos.y - h / 2;
|
|
825
|
+
const floorY = Math.max(startY, height - h);
|
|
826
|
+
const drop = floorY - startY;
|
|
827
|
+
const push = Math.max(-140, Math.min(140, (this.mousePos.x - this.lastMousePos.x) * 1.4));
|
|
828
|
+
const fall = 0.3 + 0.35 * Math.sqrt(drop / Math.max(1, height));
|
|
829
|
+
const bounce = drop * 0.32;
|
|
830
|
+
gsap.killTweensOf(img.DOM.el);
|
|
831
|
+
const el = img.DOM.el;
|
|
832
|
+
gsap.timeline({
|
|
833
|
+
onStart: () => this.onImageActivated(),
|
|
834
|
+
onComplete: () => this.onImageDeactivated()
|
|
835
|
+
}).set(el, {
|
|
836
|
+
opacity: 1,
|
|
837
|
+
scale: 0,
|
|
838
|
+
rotation: randomBetween(-10, 10),
|
|
839
|
+
zIndex: this.zIndexVal,
|
|
840
|
+
x: this.mousePos.x - w / 2,
|
|
841
|
+
y: startY
|
|
842
|
+
}).to(el, { scale: 1, duration: 0.4, ease: "elastic.out(2, 0.6)" }, 0).to(
|
|
843
|
+
el,
|
|
844
|
+
{
|
|
845
|
+
x: `+=${push}`,
|
|
846
|
+
rotation: randomBetween(-30, 30),
|
|
847
|
+
duration: fall + 0.9,
|
|
848
|
+
ease: "power1.out"
|
|
849
|
+
},
|
|
850
|
+
0.1
|
|
851
|
+
).to(el, { y: floorY, duration: fall, ease: "power2.in" }, 0.15).to(el, { y: floorY - bounce, duration: 0.28, ease: "power2.out" }).to(el, { y: floorY, duration: 0.28, ease: "power2.in" }).to(el, { y: floorY - bounce * 0.3, duration: 0.16, ease: "power2.out" }).to(el, { y: floorY, duration: 0.16, ease: "power2.in" }).to(el, { opacity: 0, scale: 0.7, duration: 0.3, ease: "power2.in" }, "+=0.15");
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
class ImageTrailVariantFlame extends BaseVariant {
|
|
855
|
+
showNextImage() {
|
|
856
|
+
++this.zIndexVal;
|
|
857
|
+
const img = this.nextImage();
|
|
858
|
+
if (!img) return;
|
|
859
|
+
const w = img.rect?.width ?? 0;
|
|
860
|
+
const h = img.rect?.height ?? 0;
|
|
861
|
+
const { dx, dy } = this.getTouchVelocity();
|
|
862
|
+
const speed = Math.min(1, Math.hypot(dx, dy) / 160);
|
|
863
|
+
const rotation = (Math.random() - 0.5) * 30 * (1 + speed * 2);
|
|
864
|
+
gsap.killTweensOf(img.DOM.el);
|
|
865
|
+
gsap.timeline({
|
|
866
|
+
onStart: () => this.onImageActivated(),
|
|
867
|
+
onComplete: () => this.onImageDeactivated()
|
|
868
|
+
}).set(img.DOM.el, {
|
|
869
|
+
opacity: 1,
|
|
870
|
+
scale: 0,
|
|
871
|
+
rotation,
|
|
872
|
+
zIndex: this.zIndexVal,
|
|
873
|
+
x: this.mousePos.x - w / 2,
|
|
874
|
+
y: this.mousePos.y - h / 2
|
|
875
|
+
}).to(img.DOM.el, { scale: 1, duration: 0.35, ease: "back.out(1.6)" }, 0).to(
|
|
876
|
+
img.DOM.el,
|
|
877
|
+
{
|
|
878
|
+
y: `-=${40 + speed * 40}`,
|
|
879
|
+
scale: 0,
|
|
880
|
+
opacity: 0,
|
|
881
|
+
rotation: rotation * 1.6,
|
|
882
|
+
duration: 0.55,
|
|
883
|
+
ease: "power2.in"
|
|
884
|
+
},
|
|
885
|
+
0.55
|
|
886
|
+
);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
const SEAM = 0.6;
|
|
890
|
+
const lo = (n) => Math.max(0, n - SEAM);
|
|
891
|
+
const hi = (n) => Math.min(100, n + SEAM);
|
|
892
|
+
const pc = (n) => `${Math.round(n * 100) / 100}%`;
|
|
893
|
+
const poly = (pts) => `polygon(${pts.map(([x, y]) => `${pc(x)} ${pc(y)}`).join(", ")})`;
|
|
894
|
+
function revealFragments(pattern) {
|
|
895
|
+
switch (pattern) {
|
|
896
|
+
case "venetian": {
|
|
897
|
+
const n = 6;
|
|
898
|
+
return Array.from({ length: n }, (_, i) => {
|
|
899
|
+
const y0 = lo(i * 100 / n);
|
|
900
|
+
const y1 = hi((i + 1) * 100 / n);
|
|
901
|
+
return {
|
|
902
|
+
closed: poly([
|
|
903
|
+
[0, y0],
|
|
904
|
+
[100, y0],
|
|
905
|
+
[100, y0],
|
|
906
|
+
[0, y0]
|
|
907
|
+
]),
|
|
908
|
+
open: poly([
|
|
909
|
+
[0, y0],
|
|
910
|
+
[100, y0],
|
|
911
|
+
[100, y1],
|
|
912
|
+
[0, y1]
|
|
913
|
+
]),
|
|
914
|
+
order: i / (n - 1)
|
|
915
|
+
};
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
case "curtain": {
|
|
919
|
+
const n = 6;
|
|
920
|
+
const mid = (n - 1) / 2;
|
|
921
|
+
return Array.from({ length: n }, (_, i) => {
|
|
922
|
+
const x0 = lo(i * 100 / n);
|
|
923
|
+
const x1 = hi((i + 1) * 100 / n);
|
|
924
|
+
const cx = (x0 + x1) / 2;
|
|
925
|
+
return {
|
|
926
|
+
closed: poly([
|
|
927
|
+
[cx, 0],
|
|
928
|
+
[cx, 0],
|
|
929
|
+
[cx, 100],
|
|
930
|
+
[cx, 100]
|
|
931
|
+
]),
|
|
932
|
+
open: poly([
|
|
933
|
+
[x0, 0],
|
|
934
|
+
[x1, 0],
|
|
935
|
+
[x1, 100],
|
|
936
|
+
[x0, 100]
|
|
937
|
+
]),
|
|
938
|
+
order: Math.abs(i - mid) / mid
|
|
939
|
+
};
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
case "hexagon": {
|
|
943
|
+
const centres = [16.67, 50, 83.33];
|
|
944
|
+
const r = 31;
|
|
945
|
+
const cells = [];
|
|
946
|
+
for (const cy of centres) {
|
|
947
|
+
for (const cx of centres) {
|
|
948
|
+
const hex = Array.from({ length: 6 }, (_, k) => {
|
|
949
|
+
const a = Math.PI / 3 * k + Math.PI / 6;
|
|
950
|
+
return [cx + r * Math.cos(a), cy + r * Math.sin(a)];
|
|
951
|
+
});
|
|
952
|
+
cells.push({
|
|
953
|
+
closed: poly(hex.map(() => [cx, cy])),
|
|
954
|
+
open: poly(hex),
|
|
955
|
+
order: Math.hypot(cx - 50, cy - 50) / Math.hypot(33.33, 33.33)
|
|
956
|
+
});
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
return cells;
|
|
960
|
+
}
|
|
961
|
+
case "liquid": {
|
|
962
|
+
const blobs = [
|
|
963
|
+
[50, 50, 48],
|
|
964
|
+
[22, 26, 36],
|
|
965
|
+
[80, 24, 36],
|
|
966
|
+
[26, 80, 36],
|
|
967
|
+
[78, 78, 38]
|
|
968
|
+
];
|
|
969
|
+
return blobs.map(([x, y, r], i) => ({
|
|
970
|
+
closed: `circle(0% at ${pc(x)} ${pc(y)})`,
|
|
971
|
+
open: `circle(${pc(r)} at ${pc(x)} ${pc(y)})`,
|
|
972
|
+
order: i / (blobs.length - 1)
|
|
973
|
+
}));
|
|
974
|
+
}
|
|
975
|
+
case "zoom-split": {
|
|
976
|
+
const quads = [
|
|
977
|
+
[0, 0],
|
|
978
|
+
[50, 0],
|
|
979
|
+
[0, 50],
|
|
980
|
+
[50, 50]
|
|
981
|
+
];
|
|
982
|
+
return quads.map(([x, y], i) => ({
|
|
983
|
+
closed: poly([
|
|
984
|
+
[50, 50],
|
|
985
|
+
[50, 50],
|
|
986
|
+
[50, 50],
|
|
987
|
+
[50, 50]
|
|
988
|
+
]),
|
|
989
|
+
open: poly([
|
|
990
|
+
[lo(x), lo(y)],
|
|
991
|
+
[hi(x + 50), lo(y)],
|
|
992
|
+
[hi(x + 50), hi(y + 50)],
|
|
993
|
+
[lo(x), hi(y + 50)]
|
|
994
|
+
]),
|
|
995
|
+
order: i / 3
|
|
996
|
+
}));
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
const FRAG_CLASS = "content__img-frag";
|
|
1001
|
+
class ImageTrailVariantReveal extends BaseVariant {
|
|
1002
|
+
static STAGGER = 0.22;
|
|
1003
|
+
// seconds from first to last fragment
|
|
1004
|
+
fragments;
|
|
1005
|
+
constructor(container, pattern) {
|
|
1006
|
+
super(container);
|
|
1007
|
+
this.fragments = revealFragments(pattern);
|
|
1008
|
+
for (const img of this.images) {
|
|
1009
|
+
const bg = img.DOM.inner?.style.backgroundImage ?? "";
|
|
1010
|
+
for (const f of this.fragments) {
|
|
1011
|
+
const frag = document.createElement("div");
|
|
1012
|
+
frag.className = FRAG_CLASS;
|
|
1013
|
+
frag.style.cssText = `position:absolute;inset:0;background-image:${bg};background-size:cover;background-position:center;clip-path:${f.closed};`;
|
|
1014
|
+
img.DOM.el.appendChild(frag);
|
|
1015
|
+
}
|
|
1016
|
+
if (img.DOM.inner) img.DOM.inner.style.opacity = "0";
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
showNextImage() {
|
|
1020
|
+
++this.zIndexVal;
|
|
1021
|
+
const img = this.nextImage();
|
|
1022
|
+
if (!img) return;
|
|
1023
|
+
const w = img.rect?.width ?? 0;
|
|
1024
|
+
const h = img.rect?.height ?? 0;
|
|
1025
|
+
const frags = [...img.DOM.el.querySelectorAll(`.${FRAG_CLASS}`)];
|
|
1026
|
+
const stagger = ImageTrailVariantReveal.STAGGER;
|
|
1027
|
+
gsap.killTweensOf([img.DOM.el, ...frags]);
|
|
1028
|
+
const tl = gsap.timeline({
|
|
1029
|
+
onStart: () => this.onImageActivated(),
|
|
1030
|
+
onComplete: () => this.onImageDeactivated()
|
|
1031
|
+
}).set(img.DOM.el, {
|
|
1032
|
+
opacity: 1,
|
|
1033
|
+
scale: 0.85,
|
|
1034
|
+
rotation: 0,
|
|
1035
|
+
zIndex: this.zIndexVal,
|
|
1036
|
+
x: this.mousePos.x - w / 2,
|
|
1037
|
+
y: this.mousePos.y - h / 2
|
|
1038
|
+
}).to(img.DOM.el, { scale: 1, duration: 0.5, ease: "power3.out" }, 0);
|
|
1039
|
+
frags.forEach((frag, i) => {
|
|
1040
|
+
const f = this.fragments[i];
|
|
1041
|
+
tl.fromTo(
|
|
1042
|
+
frag,
|
|
1043
|
+
{ clipPath: f.closed },
|
|
1044
|
+
{ clipPath: f.open, duration: 0.45, ease: "power3.out" },
|
|
1045
|
+
f.order * stagger
|
|
1046
|
+
);
|
|
1047
|
+
tl.to(
|
|
1048
|
+
frag,
|
|
1049
|
+
{ clipPath: f.closed, duration: 0.35, ease: "power3.in" },
|
|
1050
|
+
0.95 + (1 - f.order) * stagger
|
|
1051
|
+
);
|
|
1052
|
+
});
|
|
1053
|
+
tl.set(img.DOM.el, { opacity: 0 });
|
|
1054
|
+
}
|
|
1055
|
+
destroy() {
|
|
1056
|
+
for (const img of this.images) {
|
|
1057
|
+
const frags = img.DOM.el.querySelectorAll(`.${FRAG_CLASS}`);
|
|
1058
|
+
gsap.killTweensOf([...frags]);
|
|
1059
|
+
frags.forEach((f) => f.remove());
|
|
1060
|
+
if (img.DOM.inner) img.DOM.inner.style.opacity = "";
|
|
1061
|
+
}
|
|
1062
|
+
super.destroy();
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
function revealVariant(pattern) {
|
|
1066
|
+
return class extends ImageTrailVariantReveal {
|
|
1067
|
+
constructor(container) {
|
|
1068
|
+
super(container, pattern);
|
|
1069
|
+
}
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
764
1072
|
const variantMap = {
|
|
765
1073
|
type1: ImageTrailVariant1,
|
|
766
1074
|
type2: ImageTrailVariant2,
|
|
@@ -770,7 +1078,16 @@ const variantMap = {
|
|
|
770
1078
|
type6: ImageTrailVariant6,
|
|
771
1079
|
type7: ImageTrailVariant7,
|
|
772
1080
|
type8: ImageTrailVariant8,
|
|
773
|
-
pixelated: ImageTrailVariantPixelated
|
|
1081
|
+
pixelated: ImageTrailVariantPixelated,
|
|
1082
|
+
scale: ImageTrailVariantScale,
|
|
1083
|
+
fall: ImageTrailVariantFall,
|
|
1084
|
+
gravity: ImageTrailVariantGravity,
|
|
1085
|
+
flame: ImageTrailVariantFlame,
|
|
1086
|
+
venetian: revealVariant("venetian"),
|
|
1087
|
+
curtain: revealVariant("curtain"),
|
|
1088
|
+
hexagon: revealVariant("hexagon"),
|
|
1089
|
+
liquid: revealVariant("liquid"),
|
|
1090
|
+
"zoom-split": revealVariant("zoom-split")
|
|
774
1091
|
};
|
|
775
1092
|
export {
|
|
776
1093
|
ImageItem,
|
|
@@ -782,6 +1099,12 @@ export {
|
|
|
782
1099
|
ImageTrailVariant6,
|
|
783
1100
|
ImageTrailVariant7,
|
|
784
1101
|
ImageTrailVariant8,
|
|
1102
|
+
ImageTrailVariantFall,
|
|
1103
|
+
ImageTrailVariantFlame,
|
|
1104
|
+
ImageTrailVariantGravity,
|
|
785
1105
|
ImageTrailVariantPixelated,
|
|
1106
|
+
ImageTrailVariantReveal,
|
|
1107
|
+
ImageTrailVariantScale,
|
|
1108
|
+
revealFragments,
|
|
786
1109
|
variantMap
|
|
787
1110
|
};
|
|
@@ -3,12 +3,13 @@ import { jsxs, jsx } from "react/jsx-runtime";
|
|
|
3
3
|
import { forwardRef } from "react";
|
|
4
4
|
import { cn } from "../../utils.js";
|
|
5
5
|
import { useSoundCue } from "../../sound/use-sound.js";
|
|
6
|
+
/* empty css */
|
|
6
7
|
const InteractiveHoverButton = forwardRef(
|
|
7
|
-
({ text = "Button", className, children, sound = false,
|
|
8
|
+
({ text = "Button", className, children, onClick, sound = false, ...restProps }, ref) => {
|
|
8
9
|
const label = children ?? text;
|
|
9
10
|
const playCue = useSoundCue(sound);
|
|
10
11
|
function handleClick(event) {
|
|
11
|
-
if (sound && !disabled) playCue("press");
|
|
12
|
+
if (sound && !restProps.disabled) playCue("press");
|
|
12
13
|
onClick?.(event);
|
|
13
14
|
}
|
|
14
15
|
return /* @__PURE__ */ jsxs(
|
|
@@ -16,45 +17,39 @@ const InteractiveHoverButton = forwardRef(
|
|
|
16
17
|
{
|
|
17
18
|
ref,
|
|
18
19
|
className: cn(
|
|
19
|
-
"group bg-background relative w-auto cursor-pointer overflow-hidden rounded-full border
|
|
20
|
+
"ihb group bg-background relative isolate w-auto cursor-pointer overflow-hidden rounded-full border px-6 py-2.5 text-center font-semibold",
|
|
20
21
|
className
|
|
21
22
|
),
|
|
22
23
|
onClick: handleClick,
|
|
23
|
-
disabled,
|
|
24
24
|
...restProps,
|
|
25
25
|
children: [
|
|
26
|
-
/* @__PURE__ */
|
|
27
|
-
|
|
28
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
26
|
+
/* @__PURE__ */ jsx("span", { className: "ihb-fill", "aria-hidden": "true" }),
|
|
27
|
+
/* @__PURE__ */ jsxs("span", { className: "ihb-rest", children: [
|
|
28
|
+
/* @__PURE__ */ jsx("span", { className: "ihb-dot-space", "aria-hidden": "true" }),
|
|
29
|
+
/* @__PURE__ */ jsx("span", { className: "ihb-label", children: label })
|
|
29
30
|
] }),
|
|
30
|
-
/* @__PURE__ */ jsxs(
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
]
|
|
53
|
-
}
|
|
54
|
-
)
|
|
55
|
-
]
|
|
56
|
-
}
|
|
57
|
-
)
|
|
31
|
+
/* @__PURE__ */ jsxs("span", { "aria-hidden": "true", className: "ihb-hover", children: [
|
|
32
|
+
/* @__PURE__ */ jsx("span", { className: "ihb-hover-label", children: label }),
|
|
33
|
+
/* @__PURE__ */ jsxs(
|
|
34
|
+
"svg",
|
|
35
|
+
{
|
|
36
|
+
className: "ihb-arrow",
|
|
37
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
38
|
+
width: "18",
|
|
39
|
+
height: "18",
|
|
40
|
+
viewBox: "0 0 24 24",
|
|
41
|
+
fill: "none",
|
|
42
|
+
stroke: "currentColor",
|
|
43
|
+
strokeWidth: "2",
|
|
44
|
+
strokeLinecap: "round",
|
|
45
|
+
strokeLinejoin: "round",
|
|
46
|
+
children: [
|
|
47
|
+
/* @__PURE__ */ jsx("path", { d: "M5 12h14" }),
|
|
48
|
+
/* @__PURE__ */ jsx("path", { d: "m12 5 7 7-7 7" })
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
] })
|
|
58
53
|
]
|
|
59
54
|
}
|
|
60
55
|
);
|
|
@@ -4,13 +4,17 @@ export interface MarqueeProps {
|
|
|
4
4
|
className?: string;
|
|
5
5
|
/** Reverse the scroll direction */
|
|
6
6
|
reverse?: boolean;
|
|
7
|
-
/**
|
|
7
|
+
/** Ease the conveyor to a stop while the pointer (or focus) is inside */
|
|
8
8
|
pauseOnHover?: boolean;
|
|
9
9
|
/** Scroll vertically instead of horizontally */
|
|
10
10
|
vertical?: boolean;
|
|
11
|
-
/** Number of
|
|
11
|
+
/** Number of copies of the children rendered on the track */
|
|
12
12
|
repeat?: number;
|
|
13
|
+
/** Dissolve items at both edges with a gradient mask */
|
|
14
|
+
fade?: boolean;
|
|
15
|
+
/** Speed multiplier applied on top of `--duration` (2 = twice as fast) */
|
|
16
|
+
speed?: number;
|
|
13
17
|
/** Content to repeat and scroll */
|
|
14
18
|
children?: ReactNode;
|
|
15
19
|
}
|
|
16
|
-
export declare function Marquee({ className, reverse, pauseOnHover, vertical, repeat, children, }: MarqueeProps): import("react").JSX.Element;
|
|
20
|
+
export declare function Marquee({ className, reverse, pauseOnHover, vertical, repeat, fade, speed, children, }: MarqueeProps): import("react").JSX.Element;
|