diff --git a/src/pages/Anim.tsx b/src/pages/Anim.tsx deleted file mode 100644 index 5d26edd..0000000 --- a/src/pages/Anim.tsx +++ /dev/null @@ -1,133 +0,0 @@ -"use client" -import { useEffect, useState } from "react" -import { useHistory } from "react-router-dom" - -export default function Welcome() { - const history = useHistory() - const [animationPhase, setAnimationPhase] = useState(0) - - useEffect(() => { - const timer1 = setTimeout(() => setAnimationPhase(1), 500) - const timer2 = setTimeout(() => setAnimationPhase(2), 1500) - const timer3 = setTimeout(() => setAnimationPhase(3), 2500) - // const timer4 = setTimeout(() => history.push("/login"), 4000) // Раскомментируйте при необходимости - - return () => { - clearTimeout(timer1) - clearTimeout(timer2) - clearTimeout(timer3) - // clearTimeout(timer4) - } - }, [history]) - - return ( -
- {/* Фон и частицы */} -
- {/* floating particles */} -
-
-
-
-
-
- - {/* Основной контент */} -
-
- {/* Заголовки и загрузка */} - {/* ... ваш существующий код ... */} - {/* SVG с анимацией конечностей */} - - {/* Группа с зеркальным отражением всего, кроме рук */} - - {/* Голова */} - - - {/* Тело */} - - - {/* Левая рука (смотрит вниз) */} - - - {/* Правая рука (волнообразная вверх) */} - - - {/* Левая нога - длиннее */} - - - {/* Правая нога - длиннее */} - - - {/* Внутри SVG добавим стили для анимации линий */} - - {/* Анимация для всех элементов одновременно */} - - - - -
-
-
-
- ) -} \ No newline at end of file diff --git a/src/pages/Welcome.tsx b/src/pages/Welcome.tsx index 9a24608..83588c4 100644 --- a/src/pages/Welcome.tsx +++ b/src/pages/Welcome.tsx @@ -1,75 +1,219 @@ "use client" + import { useEffect, useState } from "react" -import { useHistory } from "react-router-dom" -import manImage from "../assets/man.svg" // Reverted to original import export default function Welcome() { - const history = useHistory() const [animationPhase, setAnimationPhase] = useState(0) + const [displayedTitle, setDisplayedTitle] = useState("") + const [displayedSubtitle, setDisplayedSubtitle] = useState("") + const [loaderWidth, setLoaderWidth] = useState(0) // Изначально 0 для анимации слева направо + + const fullTitle = "Реабилитация" + const fullSubtitle = "Восстановление через движение" useEffect(() => { - const timer1 = setTimeout(() => setAnimationPhase(1), 500) - const timer2 = setTimeout(() => setAnimationPhase(2), 1500) - const timer3 = setTimeout(() => setAnimationPhase(3), 2500) - // const timer4 = setTimeout(() => history.push("/login"), 4000) // Uncomment if you want auto-redirect + // Phase 1: App name appears, ball appears (after 0.2s) + const timer1 = setTimeout(() => setAnimationPhase(1), 700) + // Phase 2: Limbs start growing (after 0.7s) + // Limb growth animation is 2s, so it finishes at 0.7s + 2s = 2.7s + const timer2 = setTimeout(() => setAnimationPhase(2), 700) + // Phase 3: SVG rotates, ball tosses (after 1.7s, when limbs are fully grown) + const timer3 = setTimeout(() => setAnimationPhase(3), 1700) + // Phase 4: Subtitle and Loader appear (after ball toss finishes) + // Ball toss animation is 1.2s with 0.1s delay, so it finishes around 1.7s + 0.1s + 1.2s = 3.0s + // Starting Phase 4 at 3.1s ensures ball is completely gone + const timer4 = setTimeout(() => setAnimationPhase(4), 3100) // Запускаем фазу 4 после исчезновения мяча + // Phase 5: Ball starts bouncing (after subtitle and loader appear, e.g., 3.1s + 1s for subtitle opacity = 4.1s, so start at 4.2s) + const timer5 = setTimeout(() => setAnimationPhase(5), 3100) return () => { clearTimeout(timer1) clearTimeout(timer2) clearTimeout(timer3) - // clearTimeout(timer4) + clearTimeout(timer4) + clearTimeout(timer5) } - }, [history]) + }, []) + + useEffect(() => { + if (animationPhase >= 1) { + setDisplayedTitle(fullTitle) // Заголовок появляется мгновенно + } + if (animationPhase >= 4) { // Подзаголовок и лоадер появляются в фазе 4 + setDisplayedSubtitle(fullSubtitle) // Подзаголовок появляется целиком + setLoaderWidth(100) // Лоадер анимируется до полной ширины + } + }, [animationPhase]) // Зависимость от animationPhase return (
- Man illustration - {/* Uncomment and update path for emblemImage if needed */} - {/* Emblem */} + {/* Background and particles */}
{/* Floating particles */}
-
+ {/* SVG with animated figure */} + = 3 ? 'svg-rotate-active' : ''}`} + > + + + + {/* Group with mirror transform for the human figure */} + + {/* Голова */} + + {/* Тело */} + + {/* Левая рука (смотрит вниз) - THIS IS THE TOSSING ARM AFTER MIRRORING */} + {/* Wrapped in a new group for counter-rotation */} + = 3 ? 'tossing-arm-counter-rotate' : ''}`}> + = 2 ? 'limb-grow-active' : ''}`} /* Apply active class when phase 2 starts */ + style={{ '--length': '70' }} + /> + + {/* Правая рука (волнообразная вверх) - This arm will remain static after growth */} + = 2 ? 'limb-grow-active' : ''}`} /* Apply active class when phase 2 starts */ + style={{ '--length': '60' }} + /> + {/* Левая нога - длиннее */} + = 2 ? 'limb-grow-active' : ''}`} /* Apply active class when phase 2 starts */ + /> + {/* Правая нога - длиннее */} + = 2 ? 'limb-grow-active' : ''}`} /* Apply active class when phase 2 starts */ + /> + + + {/* Ball - now a separate div for absolute positioning */} +
= 1 ? 'opacity-100' : 'opacity-0'} + ${animationPhase >= 3 ? 'ball-toss-active' : ''} + ${animationPhase >= 5 ? 'ball-bounce-active' : ''} + `} + style={{ + // Adjusted initial position using vh/vw for better responsiveness + top: 'calc(50% - 20vh)', // Примерно 20% высоты вьюпорта выше центра + left: '50%', // Примерно 3.8% ширины вьюпорта левее центра + transform: 'translate(-50%, -50%)', // Центрирует сам div относительно его top/left + }} + /> {/* Main Content */}
-
+
{/* App Name */}
= 1 ? "opacity-100 translate-y-0" : "opacity-0 translate-y-8" - }`} + className={`transition-opacity duration-1000 delay-100 ${animationPhase >= 1 ? "opacity-100" : "opacity-0"}`} > -

Реабилитация

-

Восстановление через движение

-
- {/* Loading indicator */} -
= 1 ? "opacity-100" : "opacity-0" - }`} - > -
-
-
-

Загрузка...

+

{displayedTitle}

+ {/* Line Loader - now appears with subtitle in phase 4, and grows from left to right */} +
= 4 ? 1 : 0 }} + >
+ {/* Subtitle - appears with opacity transition in phase 4 */} +

= 4 ? 'opacity-100' : 'opacity-0'}`}> + {displayedSubtitle} +

diff --git a/src/pages/WelcomeOld.tsx b/src/pages/WelcomeOld.tsx new file mode 100644 index 0000000..9a24608 --- /dev/null +++ b/src/pages/WelcomeOld.tsx @@ -0,0 +1,79 @@ +"use client" +import { useEffect, useState } from "react" +import { useHistory } from "react-router-dom" +import manImage from "../assets/man.svg" // Reverted to original import + +export default function Welcome() { + const history = useHistory() + const [animationPhase, setAnimationPhase] = useState(0) + + useEffect(() => { + const timer1 = setTimeout(() => setAnimationPhase(1), 500) + const timer2 = setTimeout(() => setAnimationPhase(2), 1500) + const timer3 = setTimeout(() => setAnimationPhase(3), 2500) + // const timer4 = setTimeout(() => history.push("/login"), 4000) // Uncomment if you want auto-redirect + + return () => { + clearTimeout(timer1) + clearTimeout(timer2) + clearTimeout(timer3) + // clearTimeout(timer4) + } + }, [history]) + + return ( +
+ Man illustration + {/* Uncomment and update path for emblemImage if needed */} + {/* Emblem */} +
+ {/* Floating particles */} +
+
+
+
+
+
+ {/* Main Content */} +
+
+ {/* App Name */} +
= 1 ? "opacity-100 translate-y-0" : "opacity-0 translate-y-8" + }`} + > +

Реабилитация

+

Восстановление через движение

+
+ {/* Loading indicator */} +
= 1 ? "opacity-100" : "opacity-0" + }`} + > +
+
+
+

Загрузка...

+
+
+
+
+
+ ) +}