chore:preloader

This commit is contained in:
Ashwani Senapati
2025-11-30 10:49:11 +05:30
parent 1c8666f451
commit 91d6cac7df
4 changed files with 459 additions and 76 deletions

BIN
public/ml4elogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -45,7 +45,7 @@ export default function Footer() {
href="mailto:swaina@nitrkl.ac.in"
className="mt-3 inline-flex items-center justify-center rounded-md bg-cyan-900/30 px-3 py-2 text-cyan-200 hover:bg-cyan-800/40 transition"
>
swaina@nitrkl.ac.in
baigm@nitrkl.ac.in
</a>
</div>

View File

@@ -46,6 +46,198 @@
// </div>
// );
// }
// import { Canvas } from "@react-three/fiber";
// import { OrbitControls } from "@react-three/drei";
// import { Sphere, Line } from "@react-three/drei";
// import { useRef } from "react";
// import { useFrame } from "@react-three/fiber";
// import { EffectComposer, Bloom } from "@react-three/postprocessing";
// import { motion } from "framer-motion";
// import { ReactTyped } from "react-typed";
// import Navbar from "./Navbar";
// const Glow = ({ className = "" }) => (
// <div
// className={`pointer-events-none absolute inset-0 -z-10 opacity-60 blur-2xl
// [background:radial-gradient(60%_60%_at_20%_0%,rgba(0,255,255,.15),transparent_60%),radial-gradient(50%_50%_at_90%_20%,rgba(0,255,200,.12),transparent_60%),radial-gradient(40%_40%_at_50%_120%,rgba(0,200,255,.1),transparent_60%)] ${className}`}
// />
// );
// function AnimatedNeuralNode({ position, color, size = 0.08 }) {
// const ref = useRef();
// useFrame((state) => {
// if (ref.current) {
// // Subtle pulsing animation
// ref.current.scale.x = 1 + Math.sin(state.clock.elapsedTime * 2) * 0.1;
// ref.current.scale.y = 1 + Math.sin(state.clock.elapsedTime * 2) * 0.1;
// ref.current.scale.z = 1 + Math.sin(state.clock.elapsedTime * 2) * 0.1;
// }
// });
// return (
// <Sphere ref={ref} args={[size, 64, 64]} position={position}>
// <meshStandardMaterial
// color={color}
// emissive={color}
// emissiveIntensity={2} // boost emissive
// toneMapped={false} // important for bright bloom
// />
// </Sphere>
// );
// }
// function NeuralStructure({
// position = [0, 0, 0],
// color = "#00faff",
// nodeCount = 8,
// }) {
// const nodes = useRef([]);
// if (nodes.current.length === 0) {
// for (let i = 0; i < nodeCount; i++) {
// nodes.current.push([
// (Math.random() - 0.5) * 3,
// (Math.random() - 0.5) * 3,
// (Math.random() - 0.5) * 3,
// ]);
// }
// }
// const connections = [];
// for (let i = 0; i < nodeCount; i++) {
// const connectionCount = 2 + Math.floor(Math.random() * 2);
// const connectedIndices = new Set();
// while (connectedIndices.size < connectionCount) {
// const targetIndex = Math.floor(Math.random() * nodeCount);
// if (targetIndex !== i) {
// connectedIndices.add(targetIndex);
// }
// }
// connectedIndices.forEach((targetIndex) => {
// connections.push([i, targetIndex]);
// });
// }
// return (
// <group position={position}>
// {nodes.current.map((pos, i) => (
// <AnimatedNeuralNode key={i} position={pos} color={color} />
// ))}
// {connections.map(([start, end], i) => (
// <Line
// key={i}
// points={[nodes.current[start], nodes.current[end]]}
// color={color}
// lineWidth={1}
// transparent
// opacity={0.6}
// toneMapped={false} // allow bloom on lines too
// />
// ))}
// </group>
// );
// }
// export default function Home() {
// const structures = [];
// const colors = [
// "#00faff",
// "#00d9ff",
// "#00bfff",
// "#1e90ff",
// "#007fff",
// "#4dffff",
// ];
// for (let i = 0; i < 12; i++) {
// structures.push({
// position: [
// (Math.random() - 0.5) * 15,
// (Math.random() - 0.5) * 15,
// (Math.random() - 0.5) * 15,
// ],
// color: colors[i % colors.length],
// nodeCount: 5 + Math.floor(Math.random() * 6),
// });
// }
// return (
// <div className="w-screen h-screen border-t border-cyan-500/20
// bg-[#0b1117]">
// <Navbar/>
// <div className="absolute inset-0 flex md:left-10 items-center justify-center z-10 pointer-events-none">
// <Glow />
// <motion.div
// initial={{ opacity: 0, scale: 0.9 }}
// animate={{ opacity: 1, scale: 1 }}
// transition={{ duration: 1, ease: "easeOut" }}
// className="px-8 py-6 rounded-2xl bg-white/10 backdrop-blur-lg border border-white/20 shadow-lg text-center pointer-events-auto"
// >
// <motion.h1
// initial={{ opacity: 0, y: -20 }}
// animate={{ opacity: 1, y: 0 }}
// transition={{ duration: 1, ease: "easeOut" }}
// className="text-4xl md:text-8xl font-bold text-cyan-200 drop-shadow-[0_0_15px_#00faff] special-font"
// // style={{ fontFamily: "Roboto, sans-serif" }}
// >
// <b>MACHINE LEARNING FOR EVERYONE</b> (<b>ML4E</b>)
// </motion.h1>
// <motion.p
// initial={{ opacity: 0, y: 20 }}
// animate={{ opacity: 1, y: 0 }}
// transition={{ delay: 0.5, duration: 1, ease: "easeOut" }}
// className="mt-2 text-lg md:text-2xl text-blue-300 drop-shadow-[0_0_10px_#00d9ff]"
// style={{ fontFamily: "Roboto, sans-serif" }}
// >
// <ReactTyped
// strings={["THE OFFICIAL MACHINE LEARNING CLUB OF NIT ROURKELA"]}
// typeSpeed={50}
// backSpeed={30}
// backDelay={1500}
// loop={false}
// showCursor={true}
// />
// </motion.p>
// </motion.div>
// </div>
// <Canvas camera={{ position: [0, 0, 10], fov: 30 }}>
// <color attach="background" args={["#000000"]} />
// <ambientLight intensity={0.3} />
// <pointLight position={[10, 10, 10]} intensity={2} />
// {structures.map((props, i) => (
// <NeuralStructure key={i} {...props} />
// ))}
// <OrbitControls
// enableZoom={true}
// autoRotate
// autoRotateSpeed={1.5} // adjust speed (default = 2.0)
// enablePan={false}
// enableRotate={window.innerWidth > 768}
// touches={{
// ONE: null,
// TWO: null
// }}
// />
// {/* 🌟 Bloom Effect for neon glow */}
// <EffectComposer>
// <Bloom
// intensity={2.5} // strength of glow
// kernelSize={3} // blur size
// luminanceThreshold={0.1} // what gets bloomed
// luminanceSmoothing={0.9}
// />
// </EffectComposer>
// </Canvas>
// </div>
// );
// }
import { Canvas } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
import { Sphere, Line } from "@react-three/drei";
@@ -55,12 +247,14 @@ import { EffectComposer, Bloom } from "@react-three/postprocessing";
import { motion } from "framer-motion";
import { ReactTyped } from "react-typed";
import Navbar from "./Navbar";
const Glow = ({ className = "" }) => (
<div
className={`pointer-events-none absolute inset-0 -z-10 opacity-60 blur-2xl
[background:radial-gradient(60%_60%_at_20%_0%,rgba(0,255,255,.15),transparent_60%),radial-gradient(50%_50%_at_90%_20%,rgba(0,255,200,.12),transparent_60%),radial-gradient(40%_40%_at_50%_120%,rgba(0,200,255,.1),transparent_60%)] ${className}`}
/>
);
function AnimatedNeuralNode({ position, color, size = 0.08 }) {
const ref = useRef();
@@ -78,8 +272,8 @@ function AnimatedNeuralNode({ position, color, size = 0.08 }) {
<meshStandardMaterial
color={color}
emissive={color}
emissiveIntensity={2} // boost emissive
toneMapped={false} // important for bright bloom
emissiveIntensity={2}
toneMapped={false}
/>
</Sphere>
);
@@ -88,7 +282,7 @@ function AnimatedNeuralNode({ position, color, size = 0.08 }) {
function NeuralStructure({
position = [0, 0, 0],
color = "#00faff",
nodeCount = 8,
nodeCount = 18, // Fixed node count instead of random
}) {
const nodes = useRef([]);
@@ -133,7 +327,7 @@ function NeuralStructure({
lineWidth={1}
transparent
opacity={0.6}
toneMapped={false} // allow bloom on lines too
toneMapped={false}
/>
))}
</group>
@@ -151,7 +345,10 @@ export default function Home() {
"#4dffff",
];
for (let i = 0; i < 12; i++) {
// Fixed number of structures (18 as requested between 12-24)
const fixedStructureCount = 18;
for (let i = 0; i < fixedStructureCount; i++) {
structures.push({
position: [
(Math.random() - 0.5) * 15,
@@ -159,28 +356,29 @@ export default function Home() {
(Math.random() - 0.5) * 15,
],
color: colors[i % colors.length],
nodeCount: 5 + Math.floor(Math.random() * 6),
nodeCount: 18, // Fixed node count for all structures
});
}
return (
<div className="w-screen h-screen border-t border-cyan-500/20
bg-[#0b1117]">
<div className="w-screen min-h-screen border-t border-cyan-500/20 bg-[#0b1117] overflow-y-auto">
<Navbar/>
{/* Content Section - Now scrollable on mobile */}
<div className="relative min-h-screen">
<div className="absolute inset-0 flex md:left-10 items-center justify-center z-10 pointer-events-none">
<Glow />
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 1, ease: "easeOut" }}
className="px-8 py-6 rounded-2xl bg-white/10 backdrop-blur-lg border border-white/20 shadow-lg text-center pointer-events-auto"
className="px-8 py-6 rounded-2xl bg-white/10 backdrop-blur-lg border border-white/20 shadow-lg text-center pointer-events-auto mx-4"
>
<motion.h1
initial={{ opacity: 0, y: -20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 1, ease: "easeOut" }}
className="text-4xl md:text-8xl font-bold text-cyan-200 drop-shadow-[0_0_15px_#00faff] special-font"
// style={{ fontFamily: "Roboto, sans-serif" }}
>
<b>MACHINE LEARNING FOR EVERYONE</b> (<b>ML4E</b>)
</motion.h1>
@@ -204,6 +402,8 @@ export default function Home() {
</motion.div>
</div>
{/* Canvas with fixed height and proper z-index */}
<div className="fixed inset-0 z-0">
<Canvas camera={{ position: [0, 0, 10], fov: 30 }}>
<color attach="background" args={["#000000"]} />
<ambientLight intensity={0.3} />
@@ -214,27 +414,32 @@ export default function Home() {
))}
<OrbitControls
enableZoom={true}
autoRotate
autoRotateSpeed={1.5} // adjust speed (default = 2.0)
enableZoom={false} // Disabled zoom completely
autoRotate={false} // Disabled auto rotation
enablePan={false}
enableRotate={window.innerWidth > 768}
minDistance={8} // Prevent zoom out
maxDistance={12} // Prevent zoom in
touches={{
ONE: null,
TWO: null
}}
/>
{/* 🌟 Bloom Effect for neon glow */}
<EffectComposer>
<Bloom
intensity={2.5} // strength of glow
kernelSize={3} // blur size
luminanceThreshold={0.1} // what gets bloomed
intensity={2.5}
kernelSize={3}
luminanceThreshold={0.1}
luminanceSmoothing={0.9}
/>
</EffectComposer>
</Canvas>
</div>
{/* Add some scrollable content to demonstrate scrolling */}
</div>
</div>
);
}

View File

@@ -1,13 +1,191 @@
// "use client"
// import dynamic from "next/dynamic";
// import Footer from "./components/Footer"
// const Home = dynamic(() => import("./components/Home"), { ssr: false });
// export default function App() {
// return (
// <>
// <Home />
// {/* <Hero3D /> */}
// <Footer />
// </>
// );
// }
"use client"
import { useState, useEffect } from "react";
import dynamic from "next/dynamic";
import Footer from "./components/Footer"
import { motion, AnimatePresence } from "framer-motion";
import Footer from "./components/Footer";
const Home = dynamic(() => import("./components/Home"), { ssr: false });
// Preloader Component
function Preloader({ onComplete }: { onComplete: () => void }) {
const [progress, setProgress] = useState(0);
useEffect(() => {
// Simulate loading progress
const interval = setInterval(() => {
setProgress((prev) => {
if (prev >= 100) {
clearInterval(interval);
setTimeout(() => onComplete(), 500); // Small delay before fade out
return 100;
}
return prev + Math.random() * 15; // Randomized progress increments
});
}, 150);
return () => clearInterval(interval);
}, [onComplete]);
return (
<motion.div
initial={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.8 }}
className="fixed inset-0 z-50 flex flex-col items-center justify-center bg-[#0b1117] overflow-hidden"
>
{/* Animated Background Glow */}
<div className="absolute inset-0 pointer-events-none">
<div className="absolute inset-0 opacity-40 blur-3xl
[background:radial-gradient(60%_60%_at_50%_50%,rgba(0,255,255,.2),transparent_70%)]
animate-pulse"
/>
</div>
{/* Neural Network Animation */}
<div className="absolute inset-0 pointer-events-none opacity-30">
{[...Array(20)].map((_, i) => (
<motion.div
key={i}
className="absolute w-2 h-2 bg-cyan-400 rounded-full"
style={{
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
}}
animate={{
scale: [0, 1, 0],
opacity: [0, 1, 0],
}}
transition={{
duration: 2 + Math.random() * 2,
repeat: Infinity,
delay: Math.random() * 2,
}}
/>
))}
</div>
{/* Main Content */}
<div className="relative z-10 text-center px-6">
{/* Logo/Title */}
<motion.div
initial={{ scale: 0.5, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ duration: 0.8, ease: "easeOut" }}
className="mb-12"
>
<h1 className="text-6xl md:text-8xl font-bold text-cyan-200
drop-shadow-[0_0_20px_#00faff] mb-4 special-font">
ML4E
</h1>
<p className="text-xl md:text-2xl text-blue-300
drop-shadow-[0_0_10px_#00d9ff]"
style={{ fontFamily: "Roboto, sans-serif" }}>
Machine Learning For Everyone
</p>
</motion.div>
{/* Loading Bar */}
<div className="w-64 md:w-96 mx-auto">
<div className="relative h-2 bg-cyan-950/30 rounded-full overflow-hidden
border border-cyan-500/20">
<motion.div
className="absolute inset-y-0 left-0 bg-gradient-to-r
from-cyan-400 via-blue-400 to-cyan-300
shadow-[0_0_20px_#00faff]"
initial={{ width: "0%" }}
animate={{ width: `${Math.min(progress, 100)}%` }}
transition={{ duration: 0.3 }}
/>
{/* Glowing effect on progress bar */}
<motion.div
className="absolute inset-y-0 left-0 bg-gradient-to-r
from-transparent via-white to-transparent opacity-50"
style={{ width: `${Math.min(progress, 100)}%` }}
animate={{
x: ["-100%", "100%"],
}}
transition={{
duration: 1,
repeat: Infinity,
ease: "linear",
}}
/>
</div>
{/* Progress Percentage */}
<motion.p
className="mt-4 text-cyan-300 text-sm font-mono"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.5 }}
>
{Math.floor(Math.min(progress, 100))}%
</motion.p>
</div>
{/* Loading Text */}
<motion.p
className="mt-8 text-blue-300/60 text-sm"
animate={{ opacity: [0.4, 1, 0.4] }}
transition={{ duration: 2, repeat: Infinity }}
>
Initializing Neural Networks...
</motion.p>
</div>
{/* Corner Accents */}
<div className="absolute top-0 left-0 w-32 h-32 border-t-2 border-l-2
border-cyan-500/30" />
<div className="absolute top-0 right-0 w-32 h-32 border-t-2 border-r-2
border-cyan-500/30" />
<div className="absolute bottom-0 left-0 w-32 h-32 border-b-2 border-l-2
border-cyan-500/30" />
<div className="absolute bottom-0 right-0 w-32 h-32 border-b-2 border-r-2
border-cyan-500/30" />
</motion.div>
);
}
export default function App() {
const [isLoading, setIsLoading] = useState(true);
const [showHome, setShowHome] = useState(false);
useEffect(() => {
// Start loading the Home component immediately
setShowHome(true);
}, []);
return (
<>
<AnimatePresence>
{isLoading && (
<Preloader onComplete={() => setIsLoading(false)} />
)}
</AnimatePresence>
{/* Home component loads in background while preloader shows */}
<div style={{ display: isLoading ? "none" : "block" }}>
{showHome && (
<>
<Home />
{/* <Hero3D /> */}
<Footer />
</>
)}
</div>
</>
);
}