diff --git a/src/components/Button.tsx b/src/components/Button.tsx index e35d4cc..af41297 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -7,6 +7,7 @@ interface ButtonProps { variant?: "default" | "blue" | "blue_alt"; shadowEnabled?: boolean; disabled?: boolean; + style?: React.CSSProperties; } export default function Button(props: ButtonProps) { @@ -28,7 +29,10 @@ export default function Button(props: ButtonProps) { }; return ( -
+
{/* Shadow element */} {shadowEnabled && !disabled && (
{/* Shadow layer */} @@ -68,7 +70,7 @@ function CoverHeading({ children, textPosition }: CoverHeadingProps) { function DateBox() { return (
@@ -91,7 +95,7 @@ function DateBox() { function Cover() { return (
@@ -116,13 +120,21 @@ function Cover() { Фестиваль технических видов спорта 2025 Фестиваль технических видов спорта 2025
@@ -131,10 +143,94 @@ function Cover() { onClick={() => { window.location.href = "/about"; }} + className="animate-pulse-glow hover:animate-none transition-all duration-300 hover:scale-105" + style={{ + animationDelay: "0.8s", + animationFillMode: "both", + }} > смотреть карту
+ +
); } diff --git a/src/components/Info.tsx b/src/components/Info.tsx index 9760a08..1458d8c 100644 --- a/src/components/Info.tsx +++ b/src/components/Info.tsx @@ -1,11 +1,58 @@ /* eslint-disable @next/next/no-img-element */ import { gothampro } from "@/utils/fonts"; import Button from "./Button"; +import { useEffect, useRef } from "react"; function Info() { + const containerRef = useRef(null); + const elementsRef = useRef<(HTMLDivElement | null)[]>([]); + + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + entry.target.classList.add("animate-fade-in-up"); + entry.target.classList.remove("opacity-0", "translate-y-8"); + } + }); + }, + { threshold: 0.1, rootMargin: "0px 0px -50px 0px" } + ); + + elementsRef.current.forEach((el) => { + if (el) observer.observe(el); + }); + + return () => observer.disconnect(); + }, []); + + const addToRefs = (el: HTMLDivElement | null) => { + if (el && !elementsRef.current.includes(el)) { + elementsRef.current.push(el); + } + }; + return (
+ +
-
+

[ о нас ] @@ -30,7 +80,10 @@ function Info() {

-
+
@@ -41,7 +94,10 @@ function Info() {
-
+
@@ -60,7 +116,10 @@ function Info() {
-
+
@@ -81,27 +140,36 @@ function Info() {
-
+
moto
-
+
car
-
+
jump
diff --git a/src/components/Partners.tsx b/src/components/Partners.tsx index 1c2e06b..6ba2e35 100644 --- a/src/components/Partners.tsx +++ b/src/components/Partners.tsx @@ -1,7 +1,37 @@ /* eslint-disable @next/next/no-img-element */ import { fluxgore } from "@/utils/fonts"; +import Button from "./Button"; +import { useEffect, useRef } from "react"; function Partners() { + const elementsRef = useRef<(HTMLDivElement | null)[]>([]); + + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + entry.target.classList.add("animate-fade-in-up"); + entry.target.classList.remove("opacity-0", "translate-y-8"); + } + }); + }, + { threshold: 0.1, rootMargin: "0px 0px -50px 0px" } + ); + + elementsRef.current.forEach((el) => { + if (el) observer.observe(el); + }); + + return () => observer.disconnect(); + }, []); + + const addToRefs = (el: HTMLDivElement | null) => { + if (el && !elementsRef.current.includes(el)) { + elementsRef.current.push(el); + } + }; + return (
-
-

- партнеры -

+ -
+
+
+

+ партнеры +

+
+ +
Dep Logo Mos Logo Raf Logo Ctvs Logo SMP Logo
+ +
+ +
); diff --git a/src/components/Video.tsx b/src/components/Video.tsx index 5f909f0..d56624f 100644 --- a/src/components/Video.tsx +++ b/src/components/Video.tsx @@ -1,5 +1,6 @@ /* eslint-disable @next/next/no-img-element */ import { fluxgore, gothampro } from "@/utils/fonts"; +import { useEffect, useRef } from "react"; interface VideoStatsProps { number: string; @@ -26,6 +27,34 @@ function VideoStats(props: VideoStatsProps) { } function Video() { + const elementsRef = useRef<(HTMLDivElement | null)[]>([]); + + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + entry.target.classList.add("animate-fade-in-up"); + entry.target.classList.remove("opacity-0", "translate-y-8"); + } + }); + }, + { threshold: 0.1, rootMargin: "0px 0px -50px 0px" } + ); + + elementsRef.current.forEach((el) => { + if (el) observer.observe(el); + }); + + return () => observer.disconnect(); + }, []); + + const addToRefs = (el: HTMLDivElement | null) => { + if (el && !elementsRef.current.includes(el)) { + elementsRef.current.push(el); + } + }; + return (
+ +
-
+

@@ -59,14 +107,17 @@ function Video() {

-
+
-
- - - - +
+
+ +
+
+ +
+
+ +
+
+ +