@moontra/moonui-pro 3.3.29 → 3.4.2

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/index.mjs CHANGED
@@ -86692,7 +86692,7 @@ var Meteors = (props) => {
86692
86692
  Meteors.displayName = "Meteors";
86693
86693
 
86694
86694
  // src/components/backgrounds/aurora-background.css
86695
- styleInject("@keyframes aurora-wave-1 {\n 0%, 100% {\n transform: translateX(-50%) translateY(-50%) rotate(0deg) scale(1);\n }\n 33% {\n transform: translateX(-45%) translateY(-55%) rotate(60deg) scale(1.1);\n }\n 66% {\n transform: translateX(-55%) translateY(-45%) rotate(-60deg) scale(0.9);\n }\n}\n@keyframes aurora-wave-2 {\n 0%, 100% {\n transform: translateX(-50%) translateY(-50%) rotate(45deg) scale(1.2);\n }\n 33% {\n transform: translateX(-55%) translateY(-45%) rotate(105deg) scale(1);\n }\n 66% {\n transform: translateX(-45%) translateY(-55%) rotate(-15deg) scale(1.3);\n }\n}\n@keyframes aurora-wave-3 {\n 0%, 100% {\n transform: translateX(-50%) translateY(-50%) rotate(-45deg) scale(0.8);\n }\n 33% {\n transform: translateX(-40%) translateY(-50%) rotate(15deg) scale(1.2);\n }\n 66% {\n transform: translateX(-60%) translateY(-50%) rotate(-105deg) scale(1);\n }\n}\n@keyframes aurora-shimmer {\n 0%, 100% {\n opacity: 0.3;\n }\n 50% {\n opacity: 0.8;\n }\n}\n.aurora-layer {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 200%;\n height: 200%;\n filter: blur(80px);\n mix-blend-mode: screen;\n pointer-events: none;\n}\n.aurora-layer-1 {\n background: radial-gradient(ellipse at center, var(--aurora-color-1) 0%, transparent 60%);\n animation: aurora-wave-1 15s ease-in-out infinite;\n}\n.aurora-layer-2 {\n background: radial-gradient(ellipse at center, var(--aurora-color-2) 0%, transparent 50%);\n animation: aurora-wave-2 20s ease-in-out infinite;\n}\n.aurora-layer-3 {\n background: radial-gradient(ellipse at center, var(--aurora-color-3) 0%, transparent 70%);\n animation: aurora-wave-3 25s ease-in-out infinite;\n}\n.aurora-layer-shimmer {\n background: radial-gradient(ellipse at center, rgba(255, 255, 255, 0.1) 0%, transparent 60%);\n animation: aurora-shimmer 3s ease-in-out infinite;\n}\n.aurora-interactive .aurora-layer {\n transition: transform 0.3s ease-out;\n}\n.aurora-paused .aurora-layer {\n animation-play-state: paused !important;\n}\n");
86695
+ styleInject("@keyframes aurora-wave-1 {\n 0%, 100% {\n transform: translateX(-50%) translateY(-50%) rotate(0deg) scale(1);\n }\n 33% {\n transform: translateX(-45%) translateY(-55%) rotate(60deg) scale(1.1);\n }\n 66% {\n transform: translateX(-55%) translateY(-45%) rotate(-60deg) scale(0.9);\n }\n}\n@keyframes aurora-wave-2 {\n 0%, 100% {\n transform: translateX(-50%) translateY(-50%) rotate(45deg) scale(1.2);\n }\n 33% {\n transform: translateX(-55%) translateY(-45%) rotate(105deg) scale(1);\n }\n 66% {\n transform: translateX(-45%) translateY(-55%) rotate(-15deg) scale(1.3);\n }\n}\n@keyframes aurora-wave-3 {\n 0%, 100% {\n transform: translateX(-50%) translateY(-50%) rotate(-45deg) scale(0.8);\n }\n 33% {\n transform: translateX(-40%) translateY(-50%) rotate(15deg) scale(1.2);\n }\n 66% {\n transform: translateX(-60%) translateY(-50%) rotate(-105deg) scale(1);\n }\n}\n@keyframes aurora-shimmer {\n 0%, 100% {\n opacity: 0.3;\n }\n 50% {\n opacity: 0.8;\n }\n}\n.aurora-layer {\n position: absolute;\n top: 50%;\n left: 50%;\n width: 200%;\n height: 200%;\n filter: blur(80px);\n mix-blend-mode: screen;\n pointer-events: none;\n will-change: transform, opacity;\n transform: translate3d(0, 0, 0);\n backface-visibility: hidden;\n}\n.aurora-layer-1 {\n background: radial-gradient(ellipse at center, var(--aurora-color-1) 0%, transparent 60%);\n animation: aurora-wave-1 15s ease-in-out infinite;\n}\n.aurora-layer-2 {\n background: radial-gradient(ellipse at center, var(--aurora-color-2) 0%, transparent 50%);\n animation: aurora-wave-2 20s ease-in-out infinite;\n}\n.aurora-layer-3 {\n background: radial-gradient(ellipse at center, var(--aurora-color-3) 0%, transparent 70%);\n animation: aurora-wave-3 25s ease-in-out infinite;\n}\n.aurora-layer-shimmer {\n background: radial-gradient(ellipse at center, rgba(255, 255, 255, 0.1) 0%, transparent 60%);\n animation: aurora-shimmer 3s ease-in-out infinite;\n}\n.aurora-interactive .aurora-layer {\n transition: transform 0.3s ease-out, opacity 0.3s ease-out;\n}\n.aurora-paused .aurora-layer {\n opacity: 0;\n transition: opacity 0.3s ease-out;\n}\n");
86696
86696
  var AuroraBackgroundInternal = ({
86697
86697
  children,
86698
86698
  className,
@@ -86710,12 +86710,13 @@ var AuroraBackgroundInternal = ({
86710
86710
  blendMode = "screen",
86711
86711
  variant = "default",
86712
86712
  fixed = false,
86713
- pauseWhenHidden = true
86713
+ pauseWhenHidden = false
86714
86714
  }) => {
86715
86715
  const [mousePosition, setMousePosition] = useState({ x: 50, y: 50 });
86716
86716
  const [isVisible, setIsVisible] = useState(true);
86717
- const containerRef = React71__default.useRef(null);
86718
- const getAnimationDuration = () => {
86717
+ const containerRef = useRef(null);
86718
+ const observerTimeoutRef = useRef(null);
86719
+ const duration = useMemo(() => {
86719
86720
  switch (speed) {
86720
86721
  case "slow":
86721
86722
  return { layer1: "30s", layer2: "40s", layer3: "50s" };
@@ -86724,8 +86725,8 @@ var AuroraBackgroundInternal = ({
86724
86725
  default:
86725
86726
  return { layer1: "15s", layer2: "20s", layer3: "25s" };
86726
86727
  }
86727
- };
86728
- const getVariantColors = () => {
86728
+ }, [speed]);
86729
+ const variantColors = useMemo(() => {
86729
86730
  switch (variant) {
86730
86731
  case "subtle":
86731
86732
  return {
@@ -86748,17 +86749,15 @@ var AuroraBackgroundInternal = ({
86748
86749
  default:
86749
86750
  return colors;
86750
86751
  }
86751
- };
86752
- const handleMouseMove2 = (e) => {
86752
+ }, [variant, colors]);
86753
+ const handleMouseMove2 = useCallback((e) => {
86753
86754
  if (!interactive)
86754
86755
  return;
86755
86756
  const rect = e.currentTarget.getBoundingClientRect();
86756
86757
  const x2 = (e.clientX - rect.left) / rect.width * 100;
86757
86758
  const y = (e.clientY - rect.top) / rect.height * 100;
86758
86759
  setMousePosition({ x: x2, y });
86759
- };
86760
- const duration = getAnimationDuration();
86761
- const variantColors = getVariantColors();
86760
+ }, [interactive]);
86762
86761
  useEffect(() => {
86763
86762
  if (!pauseWhenHidden)
86764
86763
  return;
@@ -86768,19 +86767,60 @@ var AuroraBackgroundInternal = ({
86768
86767
  const observer = new IntersectionObserver(
86769
86768
  (entries) => {
86770
86769
  entries.forEach((entry) => {
86771
- setIsVisible(entry.isIntersecting);
86770
+ if (observerTimeoutRef.current) {
86771
+ clearTimeout(observerTimeoutRef.current);
86772
+ }
86773
+ observerTimeoutRef.current = setTimeout(() => {
86774
+ setIsVisible(entry.isIntersecting);
86775
+ }, 150);
86772
86776
  });
86773
86777
  },
86774
86778
  {
86775
- threshold: 0.1,
86776
- rootMargin: "50px"
86779
+ threshold: 0.5
86780
+ // Component must be 50% visible (was 0.1)
86781
+ // Removed rootMargin to prevent premature triggering
86777
86782
  }
86778
86783
  );
86779
86784
  observer.observe(container);
86780
86785
  return () => {
86781
86786
  observer.disconnect();
86787
+ if (observerTimeoutRef.current) {
86788
+ clearTimeout(observerTimeoutRef.current);
86789
+ }
86782
86790
  };
86783
86791
  }, [pauseWhenHidden]);
86792
+ const containerStyle = useMemo(() => ({
86793
+ "--aurora-color-1": variantColors.primary,
86794
+ "--aurora-color-2": variantColors.secondary,
86795
+ "--aurora-color-3": variantColors.tertiary,
86796
+ "--aurora-opacity": opacity.toString(),
86797
+ "--aurora-blur": `${blur2}px`
86798
+ }), [variantColors, opacity, blur2]);
86799
+ const backgroundStyle = useMemo(() => ({
86800
+ background: variant === "dark" ? "linear-gradient(to bottom, #0f172a, #020617)" : "linear-gradient(to bottom, #ffffff, #f8fafc)"
86801
+ }), [variant]);
86802
+ const layer1Style = useMemo(() => ({
86803
+ animationDuration: duration.layer1,
86804
+ filter: `blur(${blur2}px)`,
86805
+ mixBlendMode: blendMode,
86806
+ transform: interactive ? `translateX(${-50 + (mousePosition.x - 50) * 0.1}%) translateY(${-50 + (mousePosition.y - 50) * 0.1}%) rotate(0deg) scale(1)` : void 0
86807
+ }), [duration.layer1, blur2, blendMode, interactive, mousePosition]);
86808
+ const layer2Style = useMemo(() => ({
86809
+ animationDuration: duration.layer2,
86810
+ filter: `blur(${blur2 * 1.2}px)`,
86811
+ mixBlendMode: blendMode,
86812
+ transform: interactive ? `translateX(${-50 + (mousePosition.x - 50) * 0.2}%) translateY(${-50 + (mousePosition.y - 50) * 0.2}%) rotate(45deg) scale(1.2)` : void 0
86813
+ }), [duration.layer2, blur2, blendMode, interactive, mousePosition]);
86814
+ const layer3Style = useMemo(() => ({
86815
+ animationDuration: duration.layer3,
86816
+ filter: `blur(${blur2 * 0.8}px)`,
86817
+ mixBlendMode: blendMode,
86818
+ transform: interactive ? `translateX(${-50 + (mousePosition.x - 50) * 0.15}%) translateY(${-50 + (mousePosition.y - 50) * 0.15}%) rotate(-45deg) scale(0.8)` : void 0
86819
+ }), [duration.layer3, blur2, blendMode, interactive, mousePosition]);
86820
+ const shimmerStyle = useMemo(() => ({
86821
+ filter: `blur(${blur2 * 0.5}px)`,
86822
+ mixBlendMode: "overlay"
86823
+ }), [blur2]);
86784
86824
  return /* @__PURE__ */ jsxs(
86785
86825
  "div",
86786
86826
  {
@@ -86793,70 +86833,14 @@ var AuroraBackgroundInternal = ({
86793
86833
  containerClassName
86794
86834
  ),
86795
86835
  onMouseMove: handleMouseMove2,
86796
- style: {
86797
- "--aurora-color-1": variantColors.primary,
86798
- "--aurora-color-2": variantColors.secondary,
86799
- "--aurora-color-3": variantColors.tertiary,
86800
- "--aurora-opacity": opacity.toString(),
86801
- "--aurora-blur": `${blur2}px`
86802
- },
86836
+ style: containerStyle,
86803
86837
  children: [
86804
- /* @__PURE__ */ jsx(
86805
- "div",
86806
- {
86807
- className: "absolute inset-0",
86808
- style: {
86809
- background: variant === "dark" ? "linear-gradient(to bottom, #0f172a, #020617)" : "linear-gradient(to bottom, #ffffff, #f8fafc)"
86810
- }
86811
- }
86812
- ),
86838
+ /* @__PURE__ */ jsx("div", { className: "absolute inset-0", style: backgroundStyle }),
86813
86839
  /* @__PURE__ */ jsxs("div", { className: "absolute inset-0", style: { opacity }, children: [
86814
- /* @__PURE__ */ jsx(
86815
- "div",
86816
- {
86817
- className: "aurora-layer aurora-layer-1",
86818
- style: {
86819
- animationDuration: duration.layer1,
86820
- filter: `blur(${blur2}px)`,
86821
- mixBlendMode: blendMode,
86822
- transform: interactive ? `translateX(${-50 + (mousePosition.x - 50) * 0.1}%) translateY(${-50 + (mousePosition.y - 50) * 0.1}%) rotate(0deg) scale(1)` : void 0
86823
- }
86824
- }
86825
- ),
86826
- /* @__PURE__ */ jsx(
86827
- "div",
86828
- {
86829
- className: "aurora-layer aurora-layer-2",
86830
- style: {
86831
- animationDuration: duration.layer2,
86832
- filter: `blur(${blur2 * 1.2}px)`,
86833
- mixBlendMode: blendMode,
86834
- transform: interactive ? `translateX(${-50 + (mousePosition.x - 50) * 0.2}%) translateY(${-50 + (mousePosition.y - 50) * 0.2}%) rotate(45deg) scale(1.2)` : void 0
86835
- }
86836
- }
86837
- ),
86838
- /* @__PURE__ */ jsx(
86839
- "div",
86840
- {
86841
- className: "aurora-layer aurora-layer-3",
86842
- style: {
86843
- animationDuration: duration.layer3,
86844
- filter: `blur(${blur2 * 0.8}px)`,
86845
- mixBlendMode: blendMode,
86846
- transform: interactive ? `translateX(${-50 + (mousePosition.x - 50) * 0.15}%) translateY(${-50 + (mousePosition.y - 50) * 0.15}%) rotate(-45deg) scale(0.8)` : void 0
86847
- }
86848
- }
86849
- ),
86850
- shimmer && /* @__PURE__ */ jsx(
86851
- "div",
86852
- {
86853
- className: "aurora-layer aurora-layer-shimmer",
86854
- style: {
86855
- filter: `blur(${blur2 * 0.5}px)`,
86856
- mixBlendMode: "overlay"
86857
- }
86858
- }
86859
- )
86840
+ /* @__PURE__ */ jsx("div", { className: "aurora-layer aurora-layer-1", style: layer1Style }),
86841
+ /* @__PURE__ */ jsx("div", { className: "aurora-layer aurora-layer-2", style: layer2Style }),
86842
+ /* @__PURE__ */ jsx("div", { className: "aurora-layer aurora-layer-3", style: layer3Style }),
86843
+ shimmer && /* @__PURE__ */ jsx("div", { className: "aurora-layer aurora-layer-shimmer", style: shimmerStyle })
86860
86844
  ] }),
86861
86845
  children && /* @__PURE__ */ jsx("div", { className: cn("relative z-10", className), children })
86862
86846
  ]
@@ -86904,15 +86888,19 @@ var ParticlesInternal = ({
86904
86888
  movement = "random",
86905
86889
  gravity = 0.1,
86906
86890
  bounce = true,
86907
- opacity = { min: 0.3, max: 1 }
86891
+ opacity = { min: 0.3, max: 1 },
86892
+ pauseWhenHidden = false
86908
86893
  }) => {
86909
86894
  const canvasRef = useRef(null);
86895
+ const containerRef = useRef(null);
86910
86896
  const animationRef = useRef(void 0);
86911
86897
  const particlesRef = useRef([]);
86912
86898
  const mouseRef = useRef({ x: 0, y: 0 });
86913
86899
  const lastFrameTimeRef = useRef(0);
86914
86900
  const frameInterval = 1e3 / fps;
86915
- const drawParticle = (ctx, particle) => {
86901
+ const [isVisible, setIsVisible] = useState(true);
86902
+ const observerTimeoutRef = useRef(null);
86903
+ const drawParticle = useCallback((ctx, particle) => {
86916
86904
  ctx.save();
86917
86905
  ctx.translate(particle.x, particle.y);
86918
86906
  if (particle.angle && shape !== "circle") {
@@ -86967,8 +86955,8 @@ var ParticlesInternal = ({
86967
86955
  break;
86968
86956
  }
86969
86957
  ctx.restore();
86970
- };
86971
- const updateParticle = (particle, canvas) => {
86958
+ }, [shape, glow, performanceMode, glowIntensity]);
86959
+ const updateParticle = useCallback((particle, canvas) => {
86972
86960
  switch (movement) {
86973
86961
  case "linear":
86974
86962
  particle.x += particle.vx;
@@ -87031,8 +87019,8 @@ var ParticlesInternal = ({
87031
87019
  particle.life = 0;
87032
87020
  }
87033
87021
  }
87034
- };
87035
- const drawConnections = (ctx) => {
87022
+ }, [movement, speed, gravity, shape, interactive, mouseRadius, bounce]);
87023
+ const drawConnections = useCallback((ctx) => {
87036
87024
  const particles = particlesRef.current;
87037
87025
  for (let i = 0; i < particles.length; i++) {
87038
87026
  for (let j = i + 1; j < particles.length; j++) {
@@ -87050,7 +87038,7 @@ var ParticlesInternal = ({
87050
87038
  }
87051
87039
  }
87052
87040
  }
87053
- };
87041
+ }, [connectDistance, lineOpacity, lineWidth]);
87054
87042
  const animate4 = useCallback((currentTime) => {
87055
87043
  const canvas = canvasRef.current;
87056
87044
  const ctx = canvas?.getContext("2d", {
@@ -87066,20 +87054,22 @@ var ParticlesInternal = ({
87066
87054
  return;
87067
87055
  }
87068
87056
  lastFrameTimeRef.current = currentTime;
87069
- ctx.clearRect(0, 0, canvas.width, canvas.height);
87070
- if (blur2 > 0) {
87071
- ctx.filter = `blur(${blur2}px)`;
87072
- }
87073
- if (showConnections && !performanceMode) {
87074
- drawConnections(ctx);
87057
+ if (!pauseWhenHidden || isVisible) {
87058
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
87059
+ if (blur2 > 0) {
87060
+ ctx.filter = `blur(${blur2}px)`;
87061
+ }
87062
+ if (showConnections && !performanceMode) {
87063
+ drawConnections(ctx);
87064
+ }
87065
+ const particles = particlesRef.current;
87066
+ particles.forEach((particle) => {
87067
+ updateParticle(particle, canvas);
87068
+ drawParticle(ctx, particle);
87069
+ });
87075
87070
  }
87076
- const particles = particlesRef.current;
87077
- particles.forEach((particle) => {
87078
- updateParticle(particle, canvas);
87079
- drawParticle(ctx, particle);
87080
- });
87081
87071
  animationRef.current = requestAnimationFrame(animate4);
87082
- }, [showConnections, connectDistance, lineWidth, lineOpacity, performanceMode, blur2, frameInterval]);
87072
+ }, [showConnections, performanceMode, blur2, frameInterval, drawConnections, updateParticle, drawParticle, pauseWhenHidden, isVisible]);
87083
87073
  const handleResize = useCallback(() => {
87084
87074
  const canvas = canvasRef.current;
87085
87075
  if (!canvas)
@@ -87116,6 +87106,37 @@ var ParticlesInternal = ({
87116
87106
  y: e.clientY - rect.top
87117
87107
  };
87118
87108
  }, []);
87109
+ useEffect(() => {
87110
+ if (!pauseWhenHidden)
87111
+ return;
87112
+ const container = containerRef.current;
87113
+ if (!container)
87114
+ return;
87115
+ const observer = new IntersectionObserver(
87116
+ (entries) => {
87117
+ entries.forEach((entry) => {
87118
+ if (observerTimeoutRef.current) {
87119
+ clearTimeout(observerTimeoutRef.current);
87120
+ }
87121
+ observerTimeoutRef.current = setTimeout(() => {
87122
+ setIsVisible(entry.isIntersecting);
87123
+ }, 150);
87124
+ });
87125
+ },
87126
+ {
87127
+ threshold: 0.5
87128
+ // Component must be 50% visible
87129
+ // No rootMargin to prevent premature triggering
87130
+ }
87131
+ );
87132
+ observer.observe(container);
87133
+ return () => {
87134
+ observer.disconnect();
87135
+ if (observerTimeoutRef.current) {
87136
+ clearTimeout(observerTimeoutRef.current);
87137
+ }
87138
+ };
87139
+ }, [pauseWhenHidden]);
87119
87140
  useEffect(() => {
87120
87141
  const canvas = canvasRef.current;
87121
87142
  if (canvas) {
@@ -87154,9 +87175,17 @@ var ParticlesInternal = ({
87154
87175
  }
87155
87176
  };
87156
87177
  }, [handleResize, handleMouseMove2, animate4, interactive, count3, size4, colors, speed, opacity]);
87178
+ const canvasStyle = useMemo(() => ({
87179
+ willChange: "transform",
87180
+ transform: "translate3d(0, 0, 0)",
87181
+ backfaceVisibility: "hidden",
87182
+ opacity: !pauseWhenHidden || isVisible ? 1 : 0,
87183
+ transition: pauseWhenHidden ? "opacity 0.3s ease-out" : "none"
87184
+ }), [pauseWhenHidden, isVisible]);
87157
87185
  return /* @__PURE__ */ jsxs(
87158
87186
  "div",
87159
87187
  {
87188
+ ref: containerRef,
87160
87189
  className: cn(
87161
87190
  "relative w-full h-full overflow-hidden",
87162
87191
  containerClassName
@@ -87173,9 +87202,7 @@ var ParticlesInternal = ({
87173
87202
  "absolute inset-0 w-full h-full",
87174
87203
  className
87175
87204
  ),
87176
- style: {
87177
- opacity: 1
87178
- }
87205
+ style: canvasStyle
87179
87206
  }
87180
87207
  ),
87181
87208
  children && /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
@@ -87238,7 +87265,8 @@ var StarfieldInternal = ({
87238
87265
  const needsSortRef = useRef(true);
87239
87266
  const sortTimeRef = useRef(0);
87240
87267
  const resizeTimeoutRef = useRef(void 0);
87241
- const isVisibleRef = useRef(true);
87268
+ const [isVisible, setIsVisible] = useState(true);
87269
+ const observerTimeoutRef = useRef(null);
87242
87270
  const containerRef = useRef(null);
87243
87271
  const starColors = Array.isArray(starColor) ? starColor : [starColor];
87244
87272
  const initializeShootingStars = useCallback(() => {
@@ -87422,7 +87450,7 @@ var StarfieldInternal = ({
87422
87450
  });
87423
87451
  };
87424
87452
  const animate4 = useCallback((currentTime) => {
87425
- if (!isVisibleRef.current) {
87453
+ if (!isVisible) {
87426
87454
  animationRef.current = requestAnimationFrame(animate4);
87427
87455
  return;
87428
87456
  }
@@ -87539,17 +87567,26 @@ var StarfieldInternal = ({
87539
87567
  const observer = new IntersectionObserver(
87540
87568
  (entries) => {
87541
87569
  entries.forEach((entry) => {
87542
- isVisibleRef.current = entry.isIntersecting;
87570
+ if (observerTimeoutRef.current) {
87571
+ clearTimeout(observerTimeoutRef.current);
87572
+ }
87573
+ observerTimeoutRef.current = setTimeout(() => {
87574
+ setIsVisible(entry.isIntersecting);
87575
+ }, 150);
87543
87576
  });
87544
87577
  },
87545
87578
  {
87546
- threshold: 0.1,
87547
- rootMargin: "50px"
87579
+ threshold: 0.5
87580
+ // Component must be 50% visible (was 0.1)
87581
+ // Removed rootMargin to prevent premature triggering
87548
87582
  }
87549
87583
  );
87550
87584
  observer.observe(container);
87551
87585
  return () => {
87552
87586
  observer.disconnect();
87587
+ if (observerTimeoutRef.current) {
87588
+ clearTimeout(observerTimeoutRef.current);
87589
+ }
87553
87590
  };
87554
87591
  }, []);
87555
87592
  useEffect(() => {
@@ -87594,6 +87631,11 @@ var StarfieldInternal = ({
87594
87631
  }
87595
87632
  };
87596
87633
  }, [handleResize, handleMouseMove2, animate4, mouseParallax, initializeShootingStars, starCount, starSize, starColors, twinkleSpeed]);
87634
+ const canvasStyle = useMemo(() => ({
87635
+ willChange: "transform",
87636
+ transform: "translate3d(0, 0, 0)",
87637
+ backfaceVisibility: "hidden"
87638
+ }), []);
87597
87639
  return /* @__PURE__ */ jsxs(
87598
87640
  "div",
87599
87641
  {
@@ -87611,7 +87653,8 @@ var StarfieldInternal = ({
87611
87653
  className: cn(
87612
87654
  "absolute inset-0 w-full h-full",
87613
87655
  className
87614
- )
87656
+ ),
87657
+ style: canvasStyle
87615
87658
  }
87616
87659
  ),
87617
87660
  children && /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
@@ -88051,7 +88094,8 @@ var GridDistortionInternal = ({
88051
88094
  const mouseRef = useRef({ x: -1e3, y: -1e3 });
88052
88095
  const timeRef = useRef(0);
88053
88096
  const lastFrameTimeRef = useRef(0);
88054
- const isVisibleRef = useRef(true);
88097
+ const [isVisible, setIsVisible] = useState(true);
88098
+ const observerTimeoutRef = useRef(null);
88055
88099
  const frameInterval = 1e3 / fps;
88056
88100
  const initializeGrid = useCallback(() => {
88057
88101
  const points = [];
@@ -88230,7 +88274,7 @@ var GridDistortionInternal = ({
88230
88274
  const animate4 = useCallback((timestamp) => {
88231
88275
  const canvas = canvasRef.current;
88232
88276
  const ctx = canvas?.getContext("2d");
88233
- if (!canvas || !ctx || !isVisibleRef.current) {
88277
+ if (!canvas || !ctx) {
88234
88278
  animationRef.current = requestAnimationFrame(animate4);
88235
88279
  return;
88236
88280
  }
@@ -88240,11 +88284,13 @@ var GridDistortionInternal = ({
88240
88284
  return;
88241
88285
  }
88242
88286
  lastFrameTimeRef.current = timestamp - elapsed % frameInterval;
88243
- timeRef.current += speed * 0.016;
88244
- applyDistortion(canvas);
88245
- drawGrid(ctx, canvas);
88287
+ if (isVisible) {
88288
+ timeRef.current += speed * 0.016;
88289
+ applyDistortion(canvas);
88290
+ drawGrid(ctx, canvas);
88291
+ }
88246
88292
  animationRef.current = requestAnimationFrame(animate4);
88247
- }, [applyDistortion, drawGrid, speed, frameInterval]);
88293
+ }, [applyDistortion, drawGrid, speed, frameInterval, isVisible]);
88248
88294
  const setupCanvas = useCallback(() => {
88249
88295
  const canvas = canvasRef.current;
88250
88296
  const container = containerRef.current;
@@ -88293,13 +88339,25 @@ var GridDistortionInternal = ({
88293
88339
  if (!container)
88294
88340
  return;
88295
88341
  const intersectionObserver = new IntersectionObserver(
88296
- ([entry]) => {
88297
- isVisibleRef.current = entry.isIntersecting;
88342
+ (entries) => {
88343
+ entries.forEach((entry) => {
88344
+ if (observerTimeoutRef.current) {
88345
+ clearTimeout(observerTimeoutRef.current);
88346
+ }
88347
+ observerTimeoutRef.current = setTimeout(() => {
88348
+ setIsVisible(entry.isIntersecting);
88349
+ }, 150);
88350
+ });
88298
88351
  },
88299
- { threshold: 0.1 }
88352
+ { threshold: 0.5 }
88300
88353
  );
88301
88354
  intersectionObserver.observe(container);
88302
- return () => intersectionObserver.disconnect();
88355
+ return () => {
88356
+ intersectionObserver.disconnect();
88357
+ if (observerTimeoutRef.current) {
88358
+ clearTimeout(observerTimeoutRef.current);
88359
+ }
88360
+ };
88303
88361
  }, []);
88304
88362
  useEffect(() => {
88305
88363
  const canvas = canvasRef.current;
@@ -88322,6 +88380,14 @@ var GridDistortionInternal = ({
88322
88380
  }
88323
88381
  };
88324
88382
  }, [setupCanvas, handleMouseMove2, handleMouseLeave2, animate4, interactive]);
88383
+ const canvasStyle = useMemo(() => ({
88384
+ imageRendering: "crisp-edges",
88385
+ willChange: "transform",
88386
+ transform: "translate3d(0, 0, 0)",
88387
+ backfaceVisibility: "hidden",
88388
+ opacity: isVisible ? 1 : 0,
88389
+ transition: "opacity 0.3s ease-out"
88390
+ }), [isVisible]);
88325
88391
  return /* @__PURE__ */ jsxs(
88326
88392
  "div",
88327
88393
  {
@@ -88342,9 +88408,7 @@ var GridDistortionInternal = ({
88342
88408
  "absolute inset-0 w-full h-full",
88343
88409
  className
88344
88410
  ),
88345
- style: {
88346
- imageRendering: "crisp-edges"
88347
- }
88411
+ style: canvasStyle
88348
88412
  }
88349
88413
  ),
88350
88414
  children && /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
@@ -88388,15 +88452,19 @@ var WavesInternal = ({
88388
88452
  animationType = "continuous",
88389
88453
  interactive = false,
88390
88454
  mouseRadius = 150,
88391
- fps = 60
88455
+ fps = 60,
88456
+ pauseWhenHidden = false
88392
88457
  }) => {
88393
88458
  const canvasRef = useRef(null);
88459
+ const containerRef = useRef(null);
88394
88460
  const animationRef = useRef(void 0);
88395
88461
  const waveLayersRef = useRef([]);
88396
88462
  const mouseRef = useRef({ x: 0, y: 0 });
88397
88463
  const timeRef = useRef(0);
88398
88464
  const lastFrameTimeRef = useRef(0);
88399
88465
  const frameInterval = 1e3 / fps;
88466
+ const [isVisible, setIsVisible] = useState(true);
88467
+ const observerTimeoutRef = useRef(null);
88400
88468
  const initializeWaves = useCallback(() => {
88401
88469
  const waveLayers = [];
88402
88470
  for (let i = 0; i < layers; i++) {
@@ -88546,20 +88614,22 @@ var WavesInternal = ({
88546
88614
  return;
88547
88615
  }
88548
88616
  lastFrameTimeRef.current = currentTime;
88549
- if (animationType === "continuous") {
88550
- timeRef.current += 1;
88551
- } else if (animationType === "pulse") {
88552
- timeRef.current += 1 + Math.sin(currentTime * 1e-3) * 0.5;
88553
- } else if (animationType === "breathe") {
88554
- timeRef.current += 0.5 + Math.sin(currentTime * 5e-4) * 0.5;
88555
- }
88556
- ctx.clearRect(0, 0, canvas.width, canvas.height);
88557
- const waveLayers = waveLayersRef.current;
88558
- for (let i = waveLayers.length - 1; i >= 0; i--) {
88559
- drawWaveLayer(ctx, waveLayers[i], i, canvas);
88617
+ if (!pauseWhenHidden || isVisible) {
88618
+ if (animationType === "continuous") {
88619
+ timeRef.current += 1;
88620
+ } else if (animationType === "pulse") {
88621
+ timeRef.current += 1 + Math.sin(currentTime * 1e-3) * 0.5;
88622
+ } else if (animationType === "breathe") {
88623
+ timeRef.current += 0.5 + Math.sin(currentTime * 5e-4) * 0.5;
88624
+ }
88625
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
88626
+ const waveLayers = waveLayersRef.current;
88627
+ for (let i = waveLayers.length - 1; i >= 0; i--) {
88628
+ drawWaveLayer(ctx, waveLayers[i], i, canvas);
88629
+ }
88560
88630
  }
88561
88631
  animationRef.current = requestAnimationFrame(animate4);
88562
- }, [frameInterval, animationType]);
88632
+ }, [frameInterval, animationType, pauseWhenHidden, isVisible]);
88563
88633
  const handleResize = useCallback(() => {
88564
88634
  const canvas = canvasRef.current;
88565
88635
  if (!canvas)
@@ -88600,9 +88670,44 @@ var WavesInternal = ({
88600
88670
  }
88601
88671
  };
88602
88672
  }, [initializeWaves, handleResize, handleMouseMove2, animate4, interactive]);
88673
+ useEffect(() => {
88674
+ if (!pauseWhenHidden)
88675
+ return;
88676
+ const container = containerRef.current;
88677
+ if (!container)
88678
+ return;
88679
+ const observer = new IntersectionObserver(
88680
+ (entries) => {
88681
+ entries.forEach((entry) => {
88682
+ if (observerTimeoutRef.current) {
88683
+ clearTimeout(observerTimeoutRef.current);
88684
+ }
88685
+ observerTimeoutRef.current = setTimeout(() => {
88686
+ setIsVisible(entry.isIntersecting);
88687
+ }, 150);
88688
+ });
88689
+ },
88690
+ { threshold: 0.5 }
88691
+ );
88692
+ observer.observe(container);
88693
+ return () => {
88694
+ observer.disconnect();
88695
+ if (observerTimeoutRef.current) {
88696
+ clearTimeout(observerTimeoutRef.current);
88697
+ }
88698
+ };
88699
+ }, [pauseWhenHidden]);
88700
+ const canvasStyle = useMemo(() => ({
88701
+ willChange: "transform",
88702
+ transform: "translate3d(0, 0, 0)",
88703
+ backfaceVisibility: "hidden",
88704
+ opacity: !pauseWhenHidden || isVisible ? 1 : 0,
88705
+ transition: pauseWhenHidden ? "opacity 0.3s ease-out" : "none"
88706
+ }), [pauseWhenHidden, isVisible]);
88603
88707
  return /* @__PURE__ */ jsxs(
88604
88708
  "div",
88605
88709
  {
88710
+ ref: containerRef,
88606
88711
  className: cn(
88607
88712
  "relative w-full h-full overflow-hidden",
88608
88713
  containerClassName
@@ -88618,7 +88723,8 @@ var WavesInternal = ({
88618
88723
  className: cn(
88619
88724
  "absolute inset-0 w-full h-full",
88620
88725
  className
88621
- )
88726
+ ),
88727
+ style: canvasStyle
88622
88728
  }
88623
88729
  ),
88624
88730
  children && /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
@@ -88662,15 +88768,19 @@ var GradientFlowInternal = ({
88662
88768
  scale = 1,
88663
88769
  blendMode = "normal",
88664
88770
  smooth = true,
88665
- fps = 60
88771
+ fps = 60,
88772
+ pauseWhenHidden = false
88666
88773
  }) => {
88667
88774
  const canvasRef = useRef(null);
88775
+ const containerRef = useRef(null);
88668
88776
  const animationRef = useRef(void 0);
88669
88777
  const gradientPointsRef = useRef([]);
88670
88778
  const mouseRef = useRef({ x: 0, y: 0 });
88671
88779
  const timeRef = useRef(0);
88672
88780
  const lastFrameTimeRef = useRef(0);
88673
88781
  const frameInterval = 1e3 / fps;
88782
+ const [isVisible, setIsVisible] = useState(true);
88783
+ const observerTimeoutRef = useRef(null);
88674
88784
  const initializeGradientPoints = useCallback(() => {
88675
88785
  const canvas = canvasRef.current;
88676
88786
  if (!canvas)
@@ -88844,17 +88954,19 @@ var GradientFlowInternal = ({
88844
88954
  return;
88845
88955
  }
88846
88956
  lastFrameTimeRef.current = currentTime;
88847
- timeRef.current += 1;
88848
- ctx.clearRect(0, 0, canvas.width, canvas.height);
88849
- if (blur2 > 0) {
88850
- ctx.filter = `blur(${blur2}px)`;
88851
- }
88852
- if (type === "mesh") {
88853
- updateGradientPoints(canvas);
88957
+ if (!pauseWhenHidden || isVisible) {
88958
+ timeRef.current += 1;
88959
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
88960
+ if (blur2 > 0) {
88961
+ ctx.filter = `blur(${blur2}px)`;
88962
+ }
88963
+ if (type === "mesh") {
88964
+ updateGradientPoints(canvas);
88965
+ }
88966
+ drawGradient(ctx, canvas);
88854
88967
  }
88855
- drawGradient(ctx, canvas);
88856
88968
  animationRef.current = requestAnimationFrame(animate4);
88857
- }, [frameInterval, smooth, blur2, type, updateGradientPoints, drawGradient]);
88969
+ }, [frameInterval, smooth, blur2, type, updateGradientPoints, drawGradient, pauseWhenHidden, isVisible]);
88858
88970
  const handleResize = useCallback(() => {
88859
88971
  const canvas = canvasRef.current;
88860
88972
  if (!canvas)
@@ -88913,9 +89025,44 @@ var GradientFlowInternal = ({
88913
89025
  }
88914
89026
  };
88915
89027
  }, [type, initializeGradientPoints, handleResize, handleMouseMove2, animate4, interactive]);
89028
+ useEffect(() => {
89029
+ if (!pauseWhenHidden)
89030
+ return;
89031
+ const container = containerRef.current;
89032
+ if (!container)
89033
+ return;
89034
+ const observer = new IntersectionObserver(
89035
+ (entries) => {
89036
+ entries.forEach((entry) => {
89037
+ if (observerTimeoutRef.current) {
89038
+ clearTimeout(observerTimeoutRef.current);
89039
+ }
89040
+ observerTimeoutRef.current = setTimeout(() => {
89041
+ setIsVisible(entry.isIntersecting);
89042
+ }, 150);
89043
+ });
89044
+ },
89045
+ { threshold: 0.5 }
89046
+ );
89047
+ observer.observe(container);
89048
+ return () => {
89049
+ observer.disconnect();
89050
+ if (observerTimeoutRef.current) {
89051
+ clearTimeout(observerTimeoutRef.current);
89052
+ }
89053
+ };
89054
+ }, [pauseWhenHidden]);
89055
+ const canvasStyle = useMemo(() => ({
89056
+ willChange: "transform",
89057
+ transform: "translate3d(0, 0, 0)",
89058
+ backfaceVisibility: "hidden",
89059
+ opacity: !pauseWhenHidden || isVisible ? 1 : 0,
89060
+ transition: pauseWhenHidden ? "opacity 0.3s ease-out" : "none"
89061
+ }), [pauseWhenHidden, isVisible]);
88916
89062
  return /* @__PURE__ */ jsxs(
88917
89063
  "div",
88918
89064
  {
89065
+ ref: containerRef,
88919
89066
  className: cn(
88920
89067
  "relative w-full h-full overflow-hidden",
88921
89068
  containerClassName
@@ -88928,7 +89075,8 @@ var GradientFlowInternal = ({
88928
89075
  className: cn(
88929
89076
  "absolute inset-0 w-full h-full",
88930
89077
  className
88931
- )
89078
+ ),
89079
+ style: canvasStyle
88932
89080
  }
88933
89081
  ),
88934
89082
  children && /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
@@ -89006,10 +89154,13 @@ var MeshGradientInternal = ({
89006
89154
  grainOpacity = 0.03,
89007
89155
  saturation = 1,
89008
89156
  brightness = 1,
89009
- fps = 60
89157
+ fps = 60,
89158
+ pauseWhenHidden = false
89010
89159
  }) => {
89011
89160
  const { theme, resolvedTheme } = z();
89012
89161
  const currentTheme = theme === "system" ? resolvedTheme : theme;
89162
+ const [isVisible, setIsVisible] = useState(true);
89163
+ const observerTimeoutRef = useRef(null);
89013
89164
  const defaultLightColors = [
89014
89165
  "#fce7f3",
89015
89166
  // Light pink
@@ -89041,6 +89192,7 @@ var MeshGradientInternal = ({
89041
89192
  const finalBlur = blur2 ?? defaultBlur;
89042
89193
  const finalOpacity = opacity ?? defaultOpacity;
89043
89194
  const canvasRef = useRef(null);
89195
+ const containerRef = useRef(null);
89044
89196
  const animationRef = useRef(void 0);
89045
89197
  const meshPointsRef = useRef([]);
89046
89198
  const mouseRef = useRef({ x: 0, y: 0 });
@@ -89216,7 +89368,7 @@ var MeshGradientInternal = ({
89216
89368
  return;
89217
89369
  }
89218
89370
  lastFrameTimeRef.current = currentTime;
89219
- if (animate4) {
89371
+ if (animate4 && (!pauseWhenHidden || isVisible)) {
89220
89372
  timeRef.current += speed * 2.5;
89221
89373
  }
89222
89374
  updateMeshPoints(canvas);
@@ -89242,6 +89394,37 @@ var MeshGradientInternal = ({
89242
89394
  y: e.clientY - rect.top
89243
89395
  };
89244
89396
  }, []);
89397
+ useEffect(() => {
89398
+ if (!pauseWhenHidden)
89399
+ return;
89400
+ const container = containerRef.current;
89401
+ if (!container)
89402
+ return;
89403
+ const observer = new IntersectionObserver(
89404
+ (entries) => {
89405
+ entries.forEach((entry) => {
89406
+ if (observerTimeoutRef.current) {
89407
+ clearTimeout(observerTimeoutRef.current);
89408
+ }
89409
+ observerTimeoutRef.current = setTimeout(() => {
89410
+ setIsVisible(entry.isIntersecting);
89411
+ }, 150);
89412
+ });
89413
+ },
89414
+ {
89415
+ threshold: 0.5
89416
+ // Component must be 50% visible
89417
+ // No rootMargin to prevent premature triggering
89418
+ }
89419
+ );
89420
+ observer.observe(container);
89421
+ return () => {
89422
+ observer.disconnect();
89423
+ if (observerTimeoutRef.current) {
89424
+ clearTimeout(observerTimeoutRef.current);
89425
+ }
89426
+ };
89427
+ }, [pauseWhenHidden]);
89245
89428
  useEffect(() => {
89246
89429
  const canvas = canvasRef.current;
89247
89430
  if (!canvas)
@@ -89270,9 +89453,17 @@ var MeshGradientInternal = ({
89270
89453
  }
89271
89454
  };
89272
89455
  }, [initializeMeshPoints, handleResize, handleMouseMove2, animateLoop, drawMeshGradient, interactive, animate4]);
89456
+ const canvasStyle = useMemo(() => ({
89457
+ willChange: "transform",
89458
+ transform: "translate3d(0, 0, 0)",
89459
+ backfaceVisibility: "hidden",
89460
+ opacity: !pauseWhenHidden || isVisible ? 1 : 0,
89461
+ transition: pauseWhenHidden ? "opacity 0.3s ease-out" : "none"
89462
+ }), [pauseWhenHidden, isVisible]);
89273
89463
  return /* @__PURE__ */ jsxs(
89274
89464
  "div",
89275
89465
  {
89466
+ ref: containerRef,
89276
89467
  className: cn(
89277
89468
  "relative w-full h-full overflow-hidden",
89278
89469
  containerClassName
@@ -89285,7 +89476,8 @@ var MeshGradientInternal = ({
89285
89476
  className: cn(
89286
89477
  "absolute inset-0 w-full h-full",
89287
89478
  className
89288
- )
89479
+ ),
89480
+ style: canvasStyle
89289
89481
  }
89290
89482
  ),
89291
89483
  children && /* @__PURE__ */ jsx("div", { className: "relative z-10 h-full w-full", children })
@@ -89328,15 +89520,27 @@ var LiquidBackgroundInternal = ({
89328
89520
  backgroundColor = "transparent",
89329
89521
  animationStyle = "float",
89330
89522
  gradientOverlay = false,
89331
- fps = 60
89523
+ fps = 60,
89524
+ pauseWhenHidden = false
89332
89525
  }) => {
89333
89526
  const canvasRef = useRef(null);
89527
+ const containerRef = useRef(null);
89528
+ const offscreenCanvasRef = useRef(null);
89529
+ const offscreenCtxRef = useRef(null);
89334
89530
  const animationRef = useRef(void 0);
89335
89531
  const blobsRef = useRef([]);
89336
89532
  const mouseRef = useRef({ x: 0, y: 0, vx: 0, vy: 0 });
89337
89533
  const timeRef = useRef(0);
89338
89534
  const lastFrameTimeRef = useRef(0);
89339
89535
  const frameInterval = 1e3 / fps;
89536
+ const [isVisible, setIsVisible] = useState(true);
89537
+ const observerTimeoutRef = useRef(null);
89538
+ const filterString = useMemo(() => {
89539
+ if (blur2 > 0 && contrast > 0) {
89540
+ return `blur(${blur2}px) contrast(${contrast})`;
89541
+ }
89542
+ return "none";
89543
+ }, [blur2, contrast]);
89340
89544
  const initializeBlobs = useCallback(() => {
89341
89545
  const canvas = canvasRef.current;
89342
89546
  if (!canvas)
@@ -89441,9 +89645,7 @@ var LiquidBackgroundInternal = ({
89441
89645
  }, [animationStyle, speed, viscosity, tension, sizeRange, interactive, mouseRadius]);
89442
89646
  const drawLiquid = useCallback((ctx, canvas) => {
89443
89647
  ctx.clearRect(0, 0, canvas.width, canvas.height);
89444
- if (blur2 > 0 && contrast > 0) {
89445
- ctx.filter = `blur(${blur2}px) contrast(${contrast})`;
89446
- }
89648
+ ctx.filter = filterString;
89447
89649
  ctx.globalAlpha = opacity;
89448
89650
  const blobs = blobsRef.current;
89449
89651
  blobs.forEach((blob) => {
@@ -89489,14 +89691,17 @@ var LiquidBackgroundInternal = ({
89489
89691
  ctx.fillRect(0, 0, canvas.width, canvas.height);
89490
89692
  ctx.globalCompositeOperation = "source-over";
89491
89693
  }
89492
- }, [blur2, contrast, opacity, glow, glowIntensity, gradientOverlay]);
89694
+ }, [filterString, opacity, glow, glowIntensity, gradientOverlay]);
89493
89695
  const animate4 = useCallback((currentTime) => {
89494
89696
  const canvas = canvasRef.current;
89495
- if (!canvas)
89697
+ const offscreenCanvas = offscreenCanvasRef.current;
89698
+ const offscreenCtx = offscreenCtxRef.current;
89699
+ if (!canvas || !offscreenCanvas || !offscreenCtx)
89496
89700
  return;
89497
89701
  const ctx = canvas.getContext("2d", {
89498
89702
  alpha: true,
89499
- desynchronized: true
89703
+ desynchronized: true,
89704
+ willReadFrequently: false
89500
89705
  });
89501
89706
  if (!ctx)
89502
89707
  return;
@@ -89506,18 +89711,25 @@ var LiquidBackgroundInternal = ({
89506
89711
  return;
89507
89712
  }
89508
89713
  lastFrameTimeRef.current = currentTime;
89509
- timeRef.current += 1;
89510
- updateBlobs(canvas);
89511
- drawLiquid(ctx, canvas);
89714
+ if (!pauseWhenHidden || isVisible) {
89715
+ timeRef.current += 1;
89716
+ updateBlobs(offscreenCanvas);
89717
+ drawLiquid(offscreenCtx, offscreenCanvas);
89718
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
89719
+ ctx.drawImage(offscreenCanvas, 0, 0);
89720
+ }
89512
89721
  animationRef.current = requestAnimationFrame(animate4);
89513
- }, [frameInterval, updateBlobs, drawLiquid]);
89722
+ }, [frameInterval, updateBlobs, drawLiquid, pauseWhenHidden, isVisible]);
89514
89723
  const handleResize = useCallback(() => {
89515
89724
  const canvas = canvasRef.current;
89516
- if (!canvas)
89725
+ const offscreenCanvas = offscreenCanvasRef.current;
89726
+ if (!canvas || !offscreenCanvas)
89517
89727
  return;
89518
89728
  const rect = canvas.getBoundingClientRect();
89519
89729
  canvas.width = rect.width;
89520
89730
  canvas.height = rect.height;
89731
+ offscreenCanvas.width = rect.width;
89732
+ offscreenCanvas.height = rect.height;
89521
89733
  initializeBlobs();
89522
89734
  }, [initializeBlobs]);
89523
89735
  const handleMouseMove2 = useCallback((e) => {
@@ -89536,9 +89748,22 @@ var LiquidBackgroundInternal = ({
89536
89748
  const canvas = canvasRef.current;
89537
89749
  if (!canvas)
89538
89750
  return;
89751
+ timeRef.current = Math.random() * 100;
89752
+ const offscreenCanvas = document.createElement("canvas");
89753
+ const offscreenCtx = offscreenCanvas.getContext("2d", {
89754
+ alpha: true,
89755
+ desynchronized: true,
89756
+ willReadFrequently: false
89757
+ });
89758
+ if (!offscreenCtx)
89759
+ return;
89760
+ offscreenCanvasRef.current = offscreenCanvas;
89761
+ offscreenCtxRef.current = offscreenCtx;
89539
89762
  const rect = canvas.getBoundingClientRect();
89540
89763
  canvas.width = rect.width;
89541
89764
  canvas.height = rect.height;
89765
+ offscreenCanvas.width = rect.width;
89766
+ offscreenCanvas.height = rect.height;
89542
89767
  initializeBlobs();
89543
89768
  window.addEventListener("resize", handleResize);
89544
89769
  if (interactive) {
@@ -89551,17 +89776,58 @@ var LiquidBackgroundInternal = ({
89551
89776
  if (animationRef.current) {
89552
89777
  cancelAnimationFrame(animationRef.current);
89553
89778
  }
89779
+ offscreenCanvasRef.current = null;
89780
+ offscreenCtxRef.current = null;
89554
89781
  };
89555
89782
  }, [initializeBlobs, handleResize, handleMouseMove2, animate4, interactive]);
89783
+ useEffect(() => {
89784
+ if (!pauseWhenHidden)
89785
+ return;
89786
+ const container = containerRef.current;
89787
+ if (!container)
89788
+ return;
89789
+ const observer = new IntersectionObserver(
89790
+ (entries) => {
89791
+ entries.forEach((entry) => {
89792
+ if (observerTimeoutRef.current) {
89793
+ clearTimeout(observerTimeoutRef.current);
89794
+ }
89795
+ observerTimeoutRef.current = setTimeout(() => {
89796
+ setIsVisible(entry.isIntersecting);
89797
+ }, 150);
89798
+ });
89799
+ },
89800
+ { threshold: 0.5 }
89801
+ );
89802
+ observer.observe(container);
89803
+ return () => {
89804
+ observer.disconnect();
89805
+ if (observerTimeoutRef.current) {
89806
+ clearTimeout(observerTimeoutRef.current);
89807
+ }
89808
+ };
89809
+ }, [pauseWhenHidden]);
89810
+ const canvasStyle = useMemo(() => ({
89811
+ willChange: "transform, opacity",
89812
+ transform: "translate3d(0, 0, 0)",
89813
+ backfaceVisibility: "hidden",
89814
+ contain: "paint layout",
89815
+ isolation: "isolate",
89816
+ opacity: !pauseWhenHidden || isVisible ? 1 : 0,
89817
+ transition: pauseWhenHidden ? "opacity 0.3s ease-out" : "none"
89818
+ }), [pauseWhenHidden, isVisible]);
89556
89819
  return /* @__PURE__ */ jsxs(
89557
89820
  "div",
89558
89821
  {
89822
+ ref: containerRef,
89559
89823
  className: cn(
89560
89824
  "relative w-full h-full overflow-hidden",
89561
89825
  containerClassName
89562
89826
  ),
89563
89827
  style: {
89564
- backgroundColor
89828
+ backgroundColor,
89829
+ contain: "layout style paint",
89830
+ willChange: "contents"
89565
89831
  },
89566
89832
  children: [
89567
89833
  /* @__PURE__ */ jsx(
@@ -89571,7 +89837,8 @@ var LiquidBackgroundInternal = ({
89571
89837
  className: cn(
89572
89838
  "absolute inset-0 w-full h-full",
89573
89839
  className
89574
- )
89840
+ ),
89841
+ style: canvasStyle
89575
89842
  }
89576
89843
  ),
89577
89844
  children && /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
@@ -89612,14 +89879,18 @@ var MatrixRainInternal = ({
89612
89879
  fadeLength = 20,
89613
89880
  interactive = false,
89614
89881
  mouseRadius = 200,
89615
- fps = 30
89882
+ fps = 30,
89883
+ pauseWhenHidden = false
89616
89884
  }) => {
89617
89885
  const canvasRef = useRef(null);
89886
+ const containerRef = useRef(null);
89618
89887
  const animationRef = useRef(void 0);
89619
89888
  const columnsRef = useRef([]);
89620
89889
  const mouseRef = useRef({ x: 0, y: 0 });
89621
89890
  const lastFrameTimeRef = useRef(0);
89622
89891
  const frameInterval = 1e3 / fps;
89892
+ const [isVisible, setIsVisible] = useState(true);
89893
+ const observerTimeoutRef = useRef(null);
89623
89894
  const getCharacterSet = useCallback(() => {
89624
89895
  switch (charSet) {
89625
89896
  case "matrix":
@@ -89749,10 +90020,12 @@ var MatrixRainInternal = ({
89749
90020
  return;
89750
90021
  }
89751
90022
  lastFrameTimeRef.current = currentTime;
89752
- updateColumns2(canvas);
89753
- drawMatrix(ctx, canvas);
90023
+ if (!pauseWhenHidden || isVisible) {
90024
+ updateColumns2(canvas);
90025
+ drawMatrix(ctx, canvas);
90026
+ }
89754
90027
  animationRef.current = requestAnimationFrame(animate4);
89755
- }, [frameInterval, updateColumns2, drawMatrix]);
90028
+ }, [frameInterval, updateColumns2, drawMatrix, pauseWhenHidden, isVisible]);
89756
90029
  const handleResize = useCallback(() => {
89757
90030
  const canvas = canvasRef.current;
89758
90031
  if (!canvas)
@@ -89793,9 +90066,44 @@ var MatrixRainInternal = ({
89793
90066
  }
89794
90067
  };
89795
90068
  }, [initializeColumns, handleResize, handleMouseMove2, animate4, interactive]);
90069
+ useEffect(() => {
90070
+ if (!pauseWhenHidden)
90071
+ return;
90072
+ const container = containerRef.current;
90073
+ if (!container)
90074
+ return;
90075
+ const observer = new IntersectionObserver(
90076
+ (entries) => {
90077
+ entries.forEach((entry) => {
90078
+ if (observerTimeoutRef.current) {
90079
+ clearTimeout(observerTimeoutRef.current);
90080
+ }
90081
+ observerTimeoutRef.current = setTimeout(() => {
90082
+ setIsVisible(entry.isIntersecting);
90083
+ }, 150);
90084
+ });
90085
+ },
90086
+ { threshold: 0.5 }
90087
+ );
90088
+ observer.observe(container);
90089
+ return () => {
90090
+ observer.disconnect();
90091
+ if (observerTimeoutRef.current) {
90092
+ clearTimeout(observerTimeoutRef.current);
90093
+ }
90094
+ };
90095
+ }, [pauseWhenHidden]);
90096
+ const canvasStyle = useMemo(() => ({
90097
+ willChange: "transform",
90098
+ transform: "translate3d(0, 0, 0)",
90099
+ backfaceVisibility: "hidden",
90100
+ opacity: !pauseWhenHidden || isVisible ? backgroundOpacity : 0,
90101
+ transition: pauseWhenHidden ? "opacity 0.3s ease-out" : "none"
90102
+ }), [pauseWhenHidden, isVisible, backgroundOpacity]);
89796
90103
  return /* @__PURE__ */ jsxs(
89797
90104
  "div",
89798
90105
  {
90106
+ ref: containerRef,
89799
90107
  className: cn(
89800
90108
  "relative w-full h-full overflow-hidden bg-black",
89801
90109
  containerClassName
@@ -89809,9 +90117,7 @@ var MatrixRainInternal = ({
89809
90117
  "absolute inset-0 w-full h-full",
89810
90118
  className
89811
90119
  ),
89812
- style: {
89813
- opacity: backgroundOpacity
89814
- }
90120
+ style: canvasStyle
89815
90121
  }
89816
90122
  ),
89817
90123
  children && /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
@@ -89855,9 +90161,11 @@ var GlitchBackgroundInternal = ({
89855
90161
  speed = 1,
89856
90162
  interactive = false,
89857
90163
  mouseRadius = 200,
89858
- fps = 30
90164
+ fps = 30,
90165
+ pauseWhenHidden = false
89859
90166
  }) => {
89860
90167
  const canvasRef = useRef(null);
90168
+ const containerRef = useRef(null);
89861
90169
  const animationRef = useRef(void 0);
89862
90170
  const glitchSlicesRef = useRef([]);
89863
90171
  const mouseRef = useRef({ x: 0, y: 0 });
@@ -89865,6 +90173,8 @@ var GlitchBackgroundInternal = ({
89865
90173
  const frameInterval = 1e3 / fps;
89866
90174
  const timeRef = useRef(0);
89867
90175
  const isGlitchingRef = useRef(false);
90176
+ const [isVisible, setIsVisible] = useState(true);
90177
+ const observerTimeoutRef = useRef(null);
89868
90178
  const generateGlitchSlices = useCallback((canvas) => {
89869
90179
  const slices = [];
89870
90180
  const sliceCount = Math.floor(Math.random() * 10 * intensity) + 2;
@@ -89992,31 +90302,33 @@ var GlitchBackgroundInternal = ({
89992
90302
  return;
89993
90303
  }
89994
90304
  lastFrameTimeRef.current = currentTime;
89995
- timeRef.current += speed;
89996
- const glitchChance = frequency * 0.1;
89997
- if (!isGlitchingRef.current && Math.random() < glitchChance) {
89998
- isGlitchingRef.current = true;
89999
- generateGlitchSlices(canvas);
90000
- setTimeout(() => {
90001
- isGlitchingRef.current = false;
90002
- }, Math.random() * 200 * intensity + 50);
90003
- }
90004
- if (interactive) {
90005
- const dx = canvas.width / 2 - mouseRef.current.x;
90006
- const dy = canvas.height / 2 - mouseRef.current.y;
90007
- const distance = Math.sqrt(dx * dx + dy * dy);
90008
- if (distance < mouseRadius && !isGlitchingRef.current) {
90009
- const triggerChance = (1 - distance / mouseRadius) * frequency;
90010
- if (Math.random() < triggerChance * 0.05) {
90011
- isGlitchingRef.current = true;
90012
- generateGlitchSlices(canvas);
90013
- setTimeout(() => {
90014
- isGlitchingRef.current = false;
90015
- }, Math.random() * 100 + 50);
90305
+ if (!pauseWhenHidden || isVisible) {
90306
+ timeRef.current += speed;
90307
+ const glitchChance = frequency * 0.1;
90308
+ if (!isGlitchingRef.current && Math.random() < glitchChance) {
90309
+ isGlitchingRef.current = true;
90310
+ generateGlitchSlices(canvas);
90311
+ setTimeout(() => {
90312
+ isGlitchingRef.current = false;
90313
+ }, Math.random() * 200 * intensity + 50);
90314
+ }
90315
+ if (interactive) {
90316
+ const dx = canvas.width / 2 - mouseRef.current.x;
90317
+ const dy = canvas.height / 2 - mouseRef.current.y;
90318
+ const distance = Math.sqrt(dx * dx + dy * dy);
90319
+ if (distance < mouseRadius && !isGlitchingRef.current) {
90320
+ const triggerChance = (1 - distance / mouseRadius) * frequency;
90321
+ if (Math.random() < triggerChance * 0.05) {
90322
+ isGlitchingRef.current = true;
90323
+ generateGlitchSlices(canvas);
90324
+ setTimeout(() => {
90325
+ isGlitchingRef.current = false;
90326
+ }, Math.random() * 100 + 50);
90327
+ }
90016
90328
  }
90017
90329
  }
90330
+ drawGlitch(ctx, canvas);
90018
90331
  }
90019
- drawGlitch(ctx, canvas);
90020
90332
  animationRef.current = requestAnimationFrame(animate4);
90021
90333
  }, [
90022
90334
  frameInterval,
@@ -90026,7 +90338,9 @@ var GlitchBackgroundInternal = ({
90026
90338
  interactive,
90027
90339
  mouseRadius,
90028
90340
  generateGlitchSlices,
90029
- drawGlitch
90341
+ drawGlitch,
90342
+ pauseWhenHidden,
90343
+ isVisible
90030
90344
  ]);
90031
90345
  const handleResize = useCallback(() => {
90032
90346
  const canvas = canvasRef.current;
@@ -90079,9 +90393,45 @@ var GlitchBackgroundInternal = ({
90079
90393
  }
90080
90394
  };
90081
90395
  }, [handleResize, handleMouseMove2, animate4, interactive]);
90396
+ useEffect(() => {
90397
+ if (!pauseWhenHidden)
90398
+ return;
90399
+ const container = containerRef.current;
90400
+ if (!container)
90401
+ return;
90402
+ const observer = new IntersectionObserver(
90403
+ (entries) => {
90404
+ entries.forEach((entry) => {
90405
+ if (observerTimeoutRef.current) {
90406
+ clearTimeout(observerTimeoutRef.current);
90407
+ }
90408
+ observerTimeoutRef.current = setTimeout(() => {
90409
+ setIsVisible(entry.isIntersecting);
90410
+ }, 150);
90411
+ });
90412
+ },
90413
+ { threshold: 0.5 }
90414
+ );
90415
+ observer.observe(container);
90416
+ return () => {
90417
+ observer.disconnect();
90418
+ if (observerTimeoutRef.current) {
90419
+ clearTimeout(observerTimeoutRef.current);
90420
+ }
90421
+ };
90422
+ }, [pauseWhenHidden]);
90423
+ const canvasStyle = useMemo(() => ({
90424
+ willChange: "transform",
90425
+ transform: "translate3d(0, 0, 0)",
90426
+ backfaceVisibility: "hidden",
90427
+ zIndex: 1,
90428
+ opacity: !pauseWhenHidden || isVisible ? 1 : 0,
90429
+ transition: pauseWhenHidden ? "opacity 0.3s ease-out" : "none"
90430
+ }), [pauseWhenHidden, isVisible]);
90082
90431
  return /* @__PURE__ */ jsxs(
90083
90432
  "div",
90084
90433
  {
90434
+ ref: containerRef,
90085
90435
  className: cn(
90086
90436
  "relative w-full h-full overflow-hidden",
90087
90437
  containerClassName
@@ -90098,7 +90448,7 @@ var GlitchBackgroundInternal = ({
90098
90448
  "absolute inset-0 w-full h-full pointer-events-none",
90099
90449
  className
90100
90450
  ),
90101
- style: { zIndex: 1 }
90451
+ style: canvasStyle
90102
90452
  }
90103
90453
  ),
90104
90454
  children && /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
@@ -90413,7 +90763,12 @@ var FloatingElementsInternal = ({
90413
90763
  className: cn(
90414
90764
  "absolute inset-0 w-full h-full",
90415
90765
  className
90416
- )
90766
+ ),
90767
+ style: {
90768
+ willChange: "transform",
90769
+ transform: "translate3d(0, 0, 0)",
90770
+ backfaceVisibility: "hidden"
90771
+ }
90417
90772
  }
90418
90773
  ),
90419
90774
  children && /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
@@ -90489,6 +90844,7 @@ var BubbleBackgroundInternal = ({
90489
90844
  mergeDistance = 30
90490
90845
  }) => {
90491
90846
  const canvasRef = useRef(null);
90847
+ const containerRef = useRef(null);
90492
90848
  const offscreenCanvasRef = useRef(null);
90493
90849
  const animationRef = useRef(void 0);
90494
90850
  const bubblesRef = useRef([]);
@@ -90498,6 +90854,8 @@ var BubbleBackgroundInternal = ({
90498
90854
  const timeRef = useRef(0);
90499
90855
  const gradientCacheRef = useRef(/* @__PURE__ */ new Map());
90500
90856
  const performanceConfigRef = useRef(PERFORMANCE_PRESETS.medium);
90857
+ const [isVisible, setIsVisible] = useState(true);
90858
+ const observerTimeoutRef = useRef(null);
90501
90859
  const detectPerformance = useCallback(() => {
90502
90860
  const devicePixelRatio = window.devicePixelRatio || 1;
90503
90861
  const isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
@@ -90768,37 +91126,39 @@ var BubbleBackgroundInternal = ({
90768
91126
  return;
90769
91127
  }
90770
91128
  lastFrameTimeRef.current = currentTime;
90771
- timeRef.current += 1;
90772
- ctx.clearRect(0, 0, canvas.width, canvas.height);
90773
- if (backgroundColor !== "transparent") {
90774
- ctx.fillStyle = backgroundColor;
90775
- ctx.globalAlpha = backgroundOpacity;
90776
- ctx.fillRect(0, 0, canvas.width, canvas.height);
90777
- ctx.globalAlpha = 1;
90778
- }
90779
- updateBubbles(canvas, deltaTime);
90780
- if (glow && performanceConfigRef.current.glow) {
90781
- ctx.shadowBlur = 20 * glowIntensity;
90782
- ctx.shadowColor = colors[0];
90783
- }
90784
- if (blur2 && performanceConfigRef.current.blur && offscreenCanvasRef.current) {
90785
- const offCtx = offscreenCanvasRef.current.getContext("2d");
90786
- if (offCtx) {
90787
- offCtx.filter = `blur(${blurAmount}px)`;
90788
- offCtx.clearRect(0, 0, canvas.width, canvas.height);
90789
- bubblesRef.current.forEach((bubble) => {
90790
- drawBubble(offCtx, bubble);
91129
+ if (isVisible) {
91130
+ timeRef.current += 1;
91131
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
91132
+ if (backgroundColor !== "transparent") {
91133
+ ctx.fillStyle = backgroundColor;
91134
+ ctx.globalAlpha = backgroundOpacity;
91135
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
91136
+ ctx.globalAlpha = 1;
91137
+ }
91138
+ updateBubbles(canvas, deltaTime);
91139
+ if (glow && performanceConfigRef.current.glow) {
91140
+ ctx.shadowBlur = 20 * glowIntensity;
91141
+ ctx.shadowColor = colors[0];
91142
+ }
91143
+ if (blur2 && performanceConfigRef.current.blur && offscreenCanvasRef.current) {
91144
+ const offCtx = offscreenCanvasRef.current.getContext("2d");
91145
+ if (offCtx) {
91146
+ offCtx.filter = `blur(${blurAmount}px)`;
91147
+ offCtx.clearRect(0, 0, canvas.width, canvas.height);
91148
+ bubblesRef.current.forEach((bubble) => {
91149
+ drawBubble(offCtx, bubble);
91150
+ });
91151
+ ctx.drawImage(offscreenCanvasRef.current, 0, 0);
91152
+ }
91153
+ } else {
91154
+ const bubbles = bubblesRef.current;
91155
+ bubbles.forEach((bubble) => {
91156
+ drawBubble(ctx, bubble);
90791
91157
  });
90792
- ctx.drawImage(offscreenCanvasRef.current, 0, 0);
90793
91158
  }
90794
- } else {
90795
- const bubbles = bubblesRef.current;
90796
- bubbles.forEach((bubble) => {
90797
- drawBubble(ctx, bubble);
90798
- });
90799
- }
90800
- if (glow && performanceConfigRef.current.glow) {
90801
- ctx.shadowBlur = 0;
91159
+ if (glow && performanceConfigRef.current.glow) {
91160
+ ctx.shadowBlur = 0;
91161
+ }
90802
91162
  }
90803
91163
  animationRef.current = requestAnimationFrame(animate4);
90804
91164
  }, [
@@ -90811,7 +91171,8 @@ var BubbleBackgroundInternal = ({
90811
91171
  glowIntensity,
90812
91172
  blur2,
90813
91173
  blurAmount,
90814
- colors
91174
+ colors,
91175
+ isVisible
90815
91176
  ]);
90816
91177
  const handleResize = useCallback(() => {
90817
91178
  const canvas = canvasRef.current;
@@ -90845,6 +91206,31 @@ var BubbleBackgroundInternal = ({
90845
91206
  y: e.clientY - rect.top
90846
91207
  };
90847
91208
  }, []);
91209
+ useEffect(() => {
91210
+ const container = containerRef.current;
91211
+ if (!container)
91212
+ return;
91213
+ const intersectionObserver = new IntersectionObserver(
91214
+ (entries) => {
91215
+ entries.forEach((entry) => {
91216
+ if (observerTimeoutRef.current) {
91217
+ clearTimeout(observerTimeoutRef.current);
91218
+ }
91219
+ observerTimeoutRef.current = setTimeout(() => {
91220
+ setIsVisible(entry.isIntersecting);
91221
+ }, 150);
91222
+ });
91223
+ },
91224
+ { threshold: 0.5 }
91225
+ );
91226
+ intersectionObserver.observe(container);
91227
+ return () => {
91228
+ intersectionObserver.disconnect();
91229
+ if (observerTimeoutRef.current) {
91230
+ clearTimeout(observerTimeoutRef.current);
91231
+ }
91232
+ };
91233
+ }, []);
90848
91234
  useEffect(() => {
90849
91235
  const canvas = canvasRef.current;
90850
91236
  if (!canvas)
@@ -90885,9 +91271,20 @@ var BubbleBackgroundInternal = ({
90885
91271
  gradientCacheRef.current.clear();
90886
91272
  };
90887
91273
  }, []);
91274
+ const canvasStyle = useMemo(() => ({
91275
+ width: "100%",
91276
+ height: "100%",
91277
+ touchAction: "none",
91278
+ willChange: "transform",
91279
+ transform: "translate3d(0, 0, 0)",
91280
+ backfaceVisibility: "hidden",
91281
+ opacity: isVisible ? 1 : 0,
91282
+ transition: "opacity 0.3s ease-out"
91283
+ }), [isVisible]);
90888
91284
  return /* @__PURE__ */ jsxs(
90889
91285
  "div",
90890
91286
  {
91287
+ ref: containerRef,
90891
91288
  className: cn(
90892
91289
  "relative w-full h-full overflow-hidden",
90893
91290
  containerClassName
@@ -90901,11 +91298,7 @@ var BubbleBackgroundInternal = ({
90901
91298
  "absolute inset-0 w-full h-full",
90902
91299
  className
90903
91300
  ),
90904
- style: {
90905
- width: "100%",
90906
- height: "100%",
90907
- touchAction: "none"
90908
- }
91301
+ style: canvasStyle
90909
91302
  }
90910
91303
  ),
90911
91304
  children && /* @__PURE__ */ jsx("div", { className: "relative z-10", children })
@@ -91560,7 +91953,12 @@ var GeometricPatternsInternal = ({
91560
91953
  className: cn(
91561
91954
  "absolute inset-0 w-full h-full",
91562
91955
  className
91563
- )
91956
+ ),
91957
+ style: {
91958
+ willChange: "transform",
91959
+ transform: "translate3d(0, 0, 0)",
91960
+ backfaceVisibility: "hidden"
91961
+ }
91564
91962
  }
91565
91963
  ),
91566
91964
  children && /* @__PURE__ */ jsx("div", { className: "relative z-10", children })