Implement bespoke 'EVENTIFY' text fill loader with Royal Blue color
This commit is contained in:
@@ -5,6 +5,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
|
||||
import { AuthProvider } from "@/contexts/AuthContext";
|
||||
import { ProtectedRoute } from "@/components/auth/ProtectedRoute";
|
||||
import { PageLoader } from "@/components/ui/PageLoader"; // Added import for PageLoader
|
||||
import Login from "./pages/Login";
|
||||
import Dashboard from "./pages/Dashboard";
|
||||
import PartnerDirectory from "./features/partners/PartnerDirectory";
|
||||
@@ -24,6 +25,7 @@ const App = () => (
|
||||
<Sonner />
|
||||
<BrowserRouter>
|
||||
<AuthProvider>
|
||||
<PageLoader /> {/* Rendered PageLoader here */}
|
||||
<Routes>
|
||||
<Route path="/login" element={<Login />} />
|
||||
<Route
|
||||
|
||||
75
src/components/ui/PageLoader.tsx
Normal file
75
src/components/ui/PageLoader.tsx
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { animate, transform } from "framer-motion";
|
||||
|
||||
export function PageLoader() {
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const textFill = document.querySelector(".text-fill") as HTMLElement;
|
||||
|
||||
if (textFill) {
|
||||
let progress = 0;
|
||||
const mapProgressToClipPath = transform(
|
||||
[0, 1],
|
||||
["inset(0 100% 0 0)", "inset(0 0% 0 0)"]
|
||||
);
|
||||
|
||||
const interval = setInterval(() => {
|
||||
progress = progress + Math.random() * 0.2;
|
||||
if (progress > 1) progress = 1;
|
||||
|
||||
animate(
|
||||
textFill,
|
||||
{ clipPath: mapProgressToClipPath(progress) },
|
||||
{ type: "spring", stiffness: 100, damping: 10 }
|
||||
);
|
||||
|
||||
if (progress >= 1) {
|
||||
clearInterval(interval);
|
||||
setTimeout(() => setIsLoaded(true), 500); // Wait a bit before hiding
|
||||
}
|
||||
}, 500);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}
|
||||
}, []);
|
||||
|
||||
if (isLoaded) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-background pointer-events-none">
|
||||
<style>{`
|
||||
@import url("https://fonts.googleapis.com/css2?family=Unbounded:wght@200..900&display=swap");
|
||||
.loader-text {
|
||||
font-family: "Unbounded", sans-serif;
|
||||
font-optical-sizing: auto;
|
||||
font-weight: 900;
|
||||
font-style: normal;
|
||||
text-transform: uppercase;
|
||||
font-size: 64px;
|
||||
letter-spacing: -0.06em;
|
||||
position: relative;
|
||||
color: #4361ee; /* Royal Blue */
|
||||
}
|
||||
.text-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 0.2;
|
||||
}
|
||||
.text-fill {
|
||||
position: relative;
|
||||
clip-path: inset(0 100% 0 0);
|
||||
will-change: clip-path;
|
||||
z-index: 1;
|
||||
color: #4361ee; /* Royal Blue */
|
||||
}
|
||||
`}</style>
|
||||
<div className="relative font-bold text-4xl sm:text-6xl">
|
||||
<div className="loader-text text-bg" aria-hidden="true">EVENTIFY</div>
|
||||
<div className="loader-text text-fill">EVENTIFY</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user