Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Sumit Kumar - AI & ML Engineer</title> | |
| <link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet"> | |
| <link href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.0.0/css/all.min.css" rel="stylesheet"> | |
| <link href="https://cdn.jsdelivr.net/npm/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet"> | |
| <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&family=Space+Mono&display=swap" rel="stylesheet"> | |
| <style> | |
| :root { | |
| --primary: #0a192f; | |
| --secondary: #112240; | |
| --highlight: #64ffda; | |
| --accent-1: #5e38f7; | |
| --accent-2: #0ea5e9; | |
| --text-primary: #e6f1ff; | |
| --text-secondary: #8892b0; | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Poppins', sans-serif; | |
| background-color: var(--primary); | |
| color: var(--text-primary); | |
| overflow-x: hidden; | |
| } | |
| .mono { | |
| font-family: 'Space Mono', monospace; | |
| } | |
| .gradient-text { | |
| background: linear-gradient(90deg, var(--highlight), var(--accent-2)); | |
| -webkit-background-clip: text; | |
| background-clip: text; | |
| color: transparent; | |
| } | |
| .section { | |
| padding: 80px 0; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .container { | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| padding: 0 2rem; | |
| position: relative; | |
| z-index: 2; | |
| } | |
| .section-title { | |
| font-size: 2rem; | |
| font-weight: 600; | |
| margin-bottom: 2rem; | |
| position: relative; | |
| display: inline-block; | |
| } | |
| .section-title::after { | |
| content: ''; | |
| position: absolute; | |
| bottom: -8px; | |
| left: 0; | |
| width: 40%; | |
| height: 4px; | |
| background: linear-gradient(90deg, var(--highlight), transparent); | |
| } | |
| .glowing-btn { | |
| position: relative; | |
| color: var(--highlight); | |
| padding: 0.75rem 1.5rem; | |
| background: transparent; | |
| border: 1px solid var(--highlight); | |
| border-radius: 4px; | |
| cursor: pointer; | |
| overflow: hidden; | |
| transition: all 0.3s ease; | |
| z-index: 1; | |
| text-decoration: none; | |
| display: inline-block; | |
| } | |
| .glowing-btn::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 0%; | |
| height: 100%; | |
| background: rgba(100, 255, 218, 0.1); | |
| transition: all 0.3s ease; | |
| z-index: -1; | |
| } | |
| .glowing-btn:hover::before { | |
| width: 100%; | |
| } | |
| .glowing-btn:hover { | |
| box-shadow: 0 0 10px rgba(100, 255, 218, 0.5); | |
| transform: translateY(-2px); | |
| } | |
| .card { | |
| background-color: var(--secondary); | |
| border-radius: 8px; | |
| padding: 1.5rem; | |
| transition: all 0.3s ease; | |
| height: 100%; | |
| overflow: hidden; | |
| position: relative; | |
| } | |
| .card::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 3px; | |
| height: 0; | |
| background: var(--highlight); | |
| transition: height 0.3s ease; | |
| } | |
| .card:hover::before { | |
| height: 100%; | |
| } | |
| .card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); | |
| } | |
| .progress-bar { | |
| height: 6px; | |
| background: rgba(255, 255, 255, 0.1); | |
| border-radius: 3px; | |
| overflow: hidden; | |
| margin: 8px 0; | |
| } | |
| .progress { | |
| height: 100%; | |
| border-radius: 3px; | |
| background: linear-gradient(90deg, var(--highlight), var(--accent-2)); | |
| width: 0; | |
| transition: width 1.5s ease-in-out; | |
| } | |
| .timeline { | |
| position: relative; | |
| max-width: 1200px; | |
| margin: 0 auto; | |
| } | |
| .timeline::after { | |
| content: ''; | |
| position: absolute; | |
| width: 2px; | |
| background: var(--highlight); | |
| top: 0; | |
| bottom: 0; | |
| left: 50%; | |
| margin-left: -1px; | |
| } | |
| .timeline-item { | |
| padding: 10px 40px; | |
| position: relative; | |
| width: 50%; | |
| box-sizing: border-box; | |
| } | |
| .timeline-item:nth-child(odd) { | |
| left: 0; | |
| } | |
| .timeline-item:nth-child(even) { | |
| left: 50%; | |
| } | |
| .timeline-content { | |
| padding: 20px; | |
| background: var(--secondary); | |
| border-radius: 8px; | |
| position: relative; | |
| } | |
| .timeline-content::after { | |
| content: ''; | |
| position: absolute; | |
| width: 20px; | |
| height: 20px; | |
| right: -20px; | |
| background: var(--secondary); | |
| top: 20px; | |
| transform: rotate(45deg); | |
| } | |
| .timeline-item:nth-child(even) .timeline-content::after { | |
| left: -10px; | |
| } | |
| .timeline-date { | |
| color: var(--highlight); | |
| font-weight: 600; | |
| } | |
| .timeline-dot { | |
| width: 20px; | |
| height: 20px; | |
| background: var(--highlight); | |
| border-radius: 50%; | |
| position: absolute; | |
| top: 25px; | |
| z-index: 10; | |
| } | |
| .timeline-item:nth-child(odd) .timeline-dot { | |
| right: -10px; | |
| } | |
| .timeline-item:nth-child(even) .timeline-dot { | |
| left: -10px; | |
| } | |
| .skill-item { | |
| padding: 1rem; | |
| background: var(--secondary); | |
| border-radius: 8px; | |
| transition: all 0.3s ease; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .skill-item:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); | |
| } | |
| .skill-item::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 3px; | |
| height: 0; | |
| background: var(--highlight); | |
| transition: height 0.3s ease; | |
| } | |
| .skill-item:hover::before { | |
| height: 100%; | |
| } | |
| .project-card { | |
| background: var(--secondary); | |
| border-radius: 8px; | |
| overflow: hidden; | |
| height: 100%; | |
| transition: all 0.3s ease; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .project-card:hover { | |
| transform: translateY(-10px); | |
| box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3); | |
| } | |
| .project-image { | |
| height: 200px; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .project-content { | |
| padding: 1.5rem; | |
| flex-grow: 1; | |
| display: flex; | |
| flex-direction: column; | |
| } | |
| .project-title { | |
| font-size: 1.25rem; | |
| font-weight: 600; | |
| margin-bottom: 0.75rem; | |
| } | |
| .project-description { | |
| color: var(--text-secondary); | |
| margin-bottom: 1.5rem; | |
| flex-grow: 1; | |
| } | |
| .project-tags { | |
| display: flex; | |
| flex-wrap: wrap; | |
| margin-bottom: 1rem; | |
| } | |
| .project-tag { | |
| background: rgba(100, 255, 218, 0.1); | |
| color: var(--highlight); | |
| padding: 0.25rem 0.75rem; | |
| border-radius: 50px; | |
| font-size: 0.75rem; | |
| margin-right: 0.5rem; | |
| margin-bottom: 0.5rem; | |
| } | |
| .project-links { | |
| display: flex; | |
| justify-content: flex-end; | |
| } | |
| .project-link { | |
| color: var(--text-primary); | |
| margin-left: 1rem; | |
| font-size: 1.25rem; | |
| transition: color 0.3s ease; | |
| } | |
| .project-link:hover { | |
| color: var(--highlight); | |
| } | |
| .form-control { | |
| width: 100%; | |
| padding: 0.75rem 1rem; | |
| background: rgba(255, 255, 255, 0.05); | |
| border: 1px solid rgba(255, 255, 255, 0.1); | |
| border-radius: 4px; | |
| color: var(--text-primary); | |
| margin-bottom: 1.5rem; | |
| transition: all 0.3s ease; | |
| } | |
| .form-control:focus { | |
| outline: none; | |
| border-color: var(--highlight); | |
| box-shadow: 0 0 0 3px rgba(100, 255, 218, 0.1); | |
| } | |
| .social-link { | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| width: 40px; | |
| height: 40px; | |
| border-radius: 50%; | |
| background: var(--secondary); | |
| color: var(--text-primary); | |
| margin-right: 1rem; | |
| transition: all 0.3s ease; | |
| } | |
| .social-link:hover { | |
| background: var(--highlight); | |
| color: var(--primary); | |
| transform: translateY(-5px); | |
| } | |
| .nav-menu { | |
| position: fixed; | |
| top: 30px; | |
| right: 30px; | |
| display: flex; | |
| z-index: 1000; | |
| } | |
| .nav-item { | |
| margin-left: 2rem; | |
| position: relative; | |
| } | |
| .nav-link { | |
| color: var(--text-primary); | |
| text-decoration: none; | |
| font-weight: 500; | |
| position: relative; | |
| transition: color 0.3s ease; | |
| } | |
| .nav-link::after { | |
| content: ''; | |
| position: absolute; | |
| width: 0; | |
| height: 2px; | |
| bottom: -5px; | |
| left: 0; | |
| background: var(--highlight); | |
| transition: width 0.3s ease; | |
| } | |
| .nav-link:hover { | |
| color: var(--highlight); | |
| } | |
| .nav-link:hover::after { | |
| width: 100%; | |
| } | |
| .mobile-menu-toggle { | |
| display: none; | |
| background: transparent; | |
| border: none; | |
| color: var(--text-primary); | |
| font-size: 1.5rem; | |
| cursor: pointer; | |
| z-index: 1001; | |
| position: fixed; | |
| top: 20px; | |
| right: 20px; | |
| } | |
| .cursor-follower { | |
| position: fixed; | |
| width: 40px; | |
| height: 40px; | |
| border: 2px solid var(--highlight); | |
| border-radius: 50%; | |
| pointer-events: none; | |
| transform: translate(-50%, -50%); | |
| transition: transform 0.15s ease, width 0.3s ease, height 0.3s ease; | |
| z-index: 9999; | |
| mix-blend-mode: difference; | |
| } | |
| .canvas-container { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| z-index: 1; | |
| } | |
| #hero { | |
| min-height: 100vh; | |
| display: flex; | |
| align-items: center; | |
| } | |
| .certificate-item { | |
| background: var(--secondary); | |
| border-radius: 8px; | |
| padding: 1.5rem; | |
| margin-bottom: 1.5rem; | |
| position: relative; | |
| transition: all 0.3s ease; | |
| } | |
| .certificate-item:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); | |
| } | |
| .certificate-item::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 3px; | |
| height: 0; | |
| background: var(--highlight); | |
| transition: height 0.3s ease; | |
| } | |
| .certificate-item:hover::before { | |
| height: 100%; | |
| } | |
| .education-card { | |
| background: var(--secondary); | |
| border-radius: 8px; | |
| padding: 2rem; | |
| position: relative; | |
| overflow: hidden; | |
| transition: all 0.3s ease; | |
| } | |
| .education-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); | |
| } | |
| .education-card::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 3px; | |
| height: 0; | |
| background: var(--highlight); | |
| transition: height 0.3s ease; | |
| } | |
| .education-card:hover::before { | |
| height: 100%; | |
| } | |
| .radar-container { | |
| position: relative; | |
| width: 200px; | |
| height: 200px; | |
| } | |
| .radar-circle { | |
| position: absolute; | |
| border-radius: 50%; | |
| border: 1px solid var(--highlight); | |
| } | |
| .radar-spinner { | |
| position: absolute; | |
| top: 0; | |
| left: 50%; | |
| width: 50%; | |
| height: 1px; | |
| background: linear-gradient(90deg, transparent, var(--highlight)); | |
| transform-origin: left center; | |
| animation: spin 4s linear infinite; | |
| } | |
| @keyframes spin { | |
| 0% { | |
| transform: rotate(0deg); | |
| } | |
| 100% { | |
| transform: rotate(360deg); | |
| } | |
| } | |
| .glow-on-hover { | |
| transition: all 0.3s ease; | |
| } | |
| .glow-on-hover:hover { | |
| box-shadow: 0 0 20px rgba(100, 255, 218, 0.5); | |
| } | |
| .highlight-text { | |
| color: var(--highlight); | |
| } | |
| @media (max-width: 768px) { | |
| .timeline::after { | |
| left: 40px; | |
| } | |
| .timeline-item { | |
| width: 100%; | |
| padding-left: 70px; | |
| padding-right: 20px; | |
| } | |
| .timeline-item:nth-child(even) { | |
| left: 0; | |
| } | |
| .timeline-item:nth-child(odd) .timeline-content::after, | |
| .timeline-item:nth-child(even) .timeline-content::after { | |
| left: -10px; | |
| } | |
| .timeline-item:nth-child(odd) .timeline-dot, | |
| .timeline-item:nth-child(even) .timeline-dot { | |
| left: 30px; | |
| } | |
| .mobile-menu-toggle { | |
| display: block; | |
| } | |
| .nav-menu { | |
| position: fixed; | |
| top: 0; | |
| right: -100%; | |
| width: 70%; | |
| height: 100vh; | |
| background: var(--secondary); | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| transition: right 0.3s ease; | |
| } | |
| .nav-menu.active { | |
| right: 0; | |
| } | |
| .nav-item { | |
| margin: 1.5rem 0; | |
| } | |
| } | |
| @media print { | |
| .section { | |
| page-break-inside: avoid; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="cursor-follower" id="cursor-follower"></div> | |
| <button class="mobile-menu-toggle" id="mobile-menu-toggle"> | |
| <i class="fas fa-bars"></i> | |
| </button> | |
| <nav class="nav-menu" id="nav-menu"> | |
| <div class="nav-item"> | |
| <a href="#hero" class="nav-link">Home</a> | |
| </div> | |
| <div class="nav-item"> | |
| <a href="#about" class="nav-link">About</a> | |
| </div> | |
| <div class="nav-item"> | |
| <a href="#skills" class="nav-link">Skills</a> | |
| </div> | |
| <div class="nav-item"> | |
| <a href="#experience" class="nav-link">Experience</a> | |
| </div> | |
| <div class="nav-item"> | |
| <a href="#projects" class="nav-link">Projects</a> | |
| </div> | |
| <div class="nav-item"> | |
| <a href="#education" class="nav-link">Education</a> | |
| </div> | |
| <div class="nav-item"> | |
| <a href="#certificates" class="nav-link">Certificates</a> | |
| </div> | |
| <div class="nav-item"> | |
| <a href="#contact" class="nav-link">Contact</a> | |
| </div> | |
| </nav> | |
| <section id="hero" class="section"> | |
| <div class="canvas-container" id="hero-canvas"></div> | |
| <div class="container"> | |
| <div class="flex flex-col md:flex-row items-center"> | |
| <div class="md:w-1/2 mb-8 md:mb-0"> | |
| <h3 class="mono text-xl text-gray-400 mb-2">Hi, my name is</h3> | |
| <h1 class="text-5xl md:text-6xl font-bold mb-4">Sumit Kumar</h1> | |
| <h2 class="text-3xl md:text-4xl font-bold text-gray-400 mb-6">I build with AI & Machine Learning</h2> | |
| <p class="text-gray-400 text-lg mb-8 max-w-lg"> | |
| I'm a machine learning engineer specializing in developing intelligent solutions using cutting-edge technologies. Currently focusing on deep learning applications. | |
| </p> | |
| <div class="flex space-x-4"> | |
| <a href="#contact" class="glowing-btn">Contact Me</a> | |
| <a href="#projects" class="glowing-btn">Explore Projects</a> | |
| <a href="./Sumit Kumar Resume.pdf" download class="glowing-btn flex items-center"> | |
| <i class="fas fa-download mr-2"></i>Resume | |
| </a> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="about" class="section"> | |
| <div class="container"> | |
| <h2 class="section-title">About Me</h2> | |
| <div class="flex flex-col md:flex-row"> | |
| <div class="md:w-1/2 mb-8 md:mb-0"> | |
| <p class="text-gray-300 mb-4"> | |
| I'm a Computer Engineering student at Bharati Vidyapeeth College of Engineering, Pune with a passion for Machine Learning and AI. My journey in tech is driven by a desire to build intelligent solutions that solve real-world problems. | |
| </p> | |
| <p class="text-gray-300 mb-4"> | |
| With strong foundations in Python, C++, and data analysis, I specialize in developing machine learning models and implementing deep learning frameworks like TensorFlow and PyTorch. | |
| </p> | |
| <p class="text-gray-300 mb-6"> | |
| I'm constantly exploring new technologies and methodologies in the AI space, with particular interests in natural language processing and anomaly detection. | |
| </p> | |
| <div class="flex flex-wrap"> | |
| <div class="bg-secondary py-2 px-4 rounded-md mr-3 mb-3 text-highlight"> | |
| <i class="fas fa-brain mr-2"></i>Deep Learning | |
| </div> | |
| <div class="bg-secondary py-2 px-4 rounded-md mr-3 mb-3 text-highlight"> | |
| <i class="fas fa-robot mr-2"></i>Machine Learning | |
| </div> | |
| <div class="bg-secondary py-2 px-4 rounded-md mr-3 mb-3 text-highlight"> | |
| <i class="fas fa-code mr-2"></i>Python | |
| </div> | |
| <div class="bg-secondary py-2 px-4 rounded-md mr-3 mb-3 text-highlight"> | |
| <i class="fas fa-chart-line mr-2"></i>Data Science | |
| </div> | |
| </div> | |
| </div> | |
| <div class="md:w-1/2 relative"> | |
| <div class="canvas-container" id="brain-model"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="skills" class="section"> | |
| <div class="container"> | |
| <h2 class="section-title">Skills</h2> | |
| <div class="flex flex-col md:flex-row"> | |
| <div class="md:w-1/2 mb-8 md:mb-0"> | |
| <h3 class="text-xl font-semibold mb-4 text-highlight">Technical Skills</h3> | |
| <div class="grid grid-cols-1 gap-4"> | |
| <div class="skill-item"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <h4 class="font-medium">AI & Machine Learning</h4> | |
| <span class="text-highlight">90%</span> | |
| </div> | |
| <p class="text-sm text-gray-400 mb-2">TensorFlow, PyTorch, Scikit-Learn, Keras</p> | |
| <div class="progress-bar"> | |
| <div class="progress" style="width: 0;" data-width="90%"></div> | |
| </div> | |
| </div> | |
| <div class="skill-item"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <h4 class="font-medium">Programming Languages</h4> | |
| <span class="text-highlight">85%</span> | |
| </div> | |
| <p class="text-sm text-gray-400 mb-2">Python, C++</p> | |
| <div class="progress-bar"> | |
| <div class="progress" style="width: 0;" data-width="85%"></div> | |
| </div> | |
| </div> | |
| <div class="skill-item"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <h4 class="font-medium">Data Analysis & Visualization</h4> | |
| <span class="text-highlight">88%</span> | |
| </div> | |
| <p class="text-sm text-gray-400 mb-2">Pandas, NumPy, Matplotlib, Seaborn</p> | |
| <div class="progress-bar"> | |
| <div class="progress" style="width: 0;" data-width="88%"></div> | |
| </div> | |
| </div> | |
| <div class="skill-item"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <h4 class="font-medium">Big Data & Cloud</h4> | |
| <span class="text-highlight">80%</span> | |
| </div> | |
| <p class="text-sm text-gray-400 mb-2">SQL, Docker, Git</p> | |
| <div class="progress-bar"> | |
| <div class="progress" style="width: 0;" data-width="80%"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <h3 class="text-xl font-semibold mt-8 mb-4 text-highlight">Soft Skills</h3> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <div class="skill-item"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <h4 class="font-medium">Problem Solving</h4> | |
| <span class="text-highlight">92%</span> | |
| </div> | |
| <div class="progress-bar"> | |
| <div class="progress" style="width: 0;" data-width="92%"></div> | |
| </div> | |
| </div> | |
| <div class="skill-item"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <h4 class="font-medium">Communication</h4> | |
| <span class="text-highlight">88%</span> | |
| </div> | |
| <div class="progress-bar"> | |
| <div class="progress" style="width: 0;" data-width="88%"></div> | |
| </div> | |
| </div> | |
| <div class="skill-item"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <h4 class="font-medium">Teamwork</h4> | |
| <span class="text-highlight">90%</span> | |
| </div> | |
| <div class="progress-bar"> | |
| <div class="progress" style="width: 0;" data-width="90%"></div> | |
| </div> | |
| </div> | |
| <div class="skill-item"> | |
| <div class="flex justify-between items-center mb-2"> | |
| <h4 class="font-medium">Leadership</h4> | |
| <span class="text-highlight">85%</span> | |
| </div> | |
| <div class="progress-bar"> | |
| <div class="progress" style="width: 0;" data-width="85%"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="md:w-1/2 relative"> | |
| <div class="canvas-container" id="skills-graph"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="experience" class="section"> | |
| <div class="container"> | |
| <h2 class="section-title">Work Experience</h2> | |
| <div class="timeline"> | |
| <div class="timeline-item"> | |
| <div class="timeline-dot"></div> | |
| <div class="timeline-content"> | |
| <h3 class="text-xl font-semibold mb-2">Machine Learning Intern</h3> | |
| <h4 class="text-lg text-gray-400 mb-1">360DigiTMG</h4> | |
| <p class="timeline-date mb-3">June 2024 - August 2024</p> | |
| <h5 class="font-medium mb-2">Project: Medical Inventory Optimization</h5> | |
| <ul class="list-disc list-inside text-gray-300"> | |
| <li class="mb-2">Utilized Python libraries (Matplotlib, Seaborn, Pandas) to create visualizations (box plots, line plots, scatterplots, histograms) and identify patterns with over 90% accuracy.</li> | |
| <li class="mb-2">Conducted statistical analysis with SciPy, calculating Pearson correlation coefficients and covariance, achieving 95% precision in deriving insights.</li> | |
| <li>Managed time series data by converting date columns to datetime and creating time series plots, identifying temporal patterns with 92% accuracy.</li> | |
| </ul> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="projects" class="section"> | |
| <div class="container"> | |
| <h2 class="section-title">Projects</h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6"> | |
| <div class="project-card"> | |
| <div class="project-image"> | |
| <div class="canvas-container" id="project1-canvas"></div> | |
| </div> | |
| <div class="project-content"> | |
| <h3 class="project-title">Real-Time Anomaly Detection</h3> | |
| <div class="project-tags"> | |
| <span class="project-tag">Python</span> | |
| <span class="project-tag">Machine Learning</span> | |
| <span class="project-tag">IsolationForest</span> | |
| </div> | |
| <p class="project-description"> | |
| Real-time anomaly detection system for cloud server metrics using the IsolationForest algorithm. Features include pause/resume functionality, customizable parameters, and live plotting. | |
| </p> | |
| <div class="project-links"> | |
| <a href="https://github.com/Sumitkumar09876/Real-Time-Anamoly-Detection-in-Cloud-Server.git" class="project-link" target="_blank"> | |
| <i class="fab fa-github"></i> | |
| </a> | |
| <a href="https://github.com/Sumitkumar09876/Real-Time-Anamoly-Detection-in-Cloud-Server.git" class="project-link" target="_blank"> | |
| <i class="fas fa-external-link-alt"></i> | |
| </a> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="project-card"> | |
| <div class="project-image"> | |
| <div class="canvas-container" id="project2-canvas"></div> | |
| </div> | |
| <div class="project-content"> | |
| <h3 class="project-title">BiomedNLP-HealthPredict</h3> | |
| <div class="project-tags"> | |
| <span class="project-tag">NLP</span> | |
| <span class="project-tag">BERT</span> | |
| <span class="project-tag">Healthcare</span> | |
| </div> | |
| <p class="project-description"> | |
| NLP-driven healthcare assistant using PubMedBERT to predict diseases, recommend medications, and assess polypharmacy risk based on patient symptoms and demographics. | |
| </p> | |
| <div class="project-links"> | |
| <a href="https://huggingface.co/Sumitkumar098/BiomedNLP-HealthPredict" class="project-link" target="_blank"> | |
| <i class="fab fa-github"></i> | |
| </a> | |
| <a href="https://huggingface.co/Sumitkumar098/BiomedNLP-HealthPredict" class="project-link" target="_blank"> | |
| <i class="fas fa-external-link-alt"></i> | |
| </a> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="project-card"> | |
| <div class="project-image"> | |
| <div class="canvas-container" id="project3-canvas"></div> | |
| </div> | |
| <div class="project-content"> | |
| <h3 class="project-title">California Housing Price Prediction</h3> | |
| <div class="project-tags"> | |
| <span class="project-tag">TensorFlow</span> | |
| <span class="project-tag">Regression</span> | |
| <span class="project-tag">Feature Engineering</span> | |
| </div> | |
| <p class="project-description"> | |
| Built a linear regression model using TensorFlow with 85% accuracy in predicting house prices. Selected and engineered features like total rooms and population, achieving 90% feature selection accuracy. | |
| </p> | |
| <div class="project-links"> | |
| <a href="https://github.com/Sumitkumar09876/California-Housing-Price-Prediction-System.git" class="project-link" target="_blank"> | |
| <i class="fab fa-github"></i> | |
| </a> | |
| <a href="https://github.com/Sumitkumar09876/California-Housing-Price-Prediction-System.git" class="project-link" target="_blank"> | |
| <i class="fas fa-external-link-alt"></i> | |
| </a> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="education" class="section"> | |
| <div class="container"> | |
| <h2 class="section-title">Education</h2> | |
| <div class="education-card"> | |
| <div class="flex flex-col md:flex-row items-center"> | |
| <div class="md:w-1/3 mb-6 md:mb-0 flex justify-center"> | |
| <div class="relative w-full h-48"> | |
| <div class="canvas-container absolute inset-0" id="education-canvas"></div> | |
| <div class="absolute inset-0 flex items-center justify-center z-10"> | |
| <span class="text-3xl font-bold text-white bg-secondary bg-opacity-70 px-4 py-2 rounded-lg shadow-lg border-2 border-highlight">BVCOE</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="md:w-2/3 md:pl-8"> | |
| <h3 class="text-2xl font-bold mb-2">Bachelor of Technology, Computer Engineering</h3> | |
| <h4 class="text-xl text-gray-400 mb-2">Bharati Vidyapeeth College of Engineering, Pune</h4> | |
| <p class="text-gray-400 mb-4">December 2021 - June 2025</p> | |
| <div class="mb-4"> | |
| <div class="flex items-center"> | |
| <span class="mr-2">CGPA: 9.17/10</span> | |
| <div class="w-48 h-2 bg-gray-700 rounded-full"> | |
| <div class="h-full bg-highlight rounded-full" style="width: 91.7%"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <p class="text-gray-300"> | |
| Relevant coursework: Data Structures, Algorithms, Artificial Intelligence, Machine Learning, Database Systems, Computer Networks, and Software Engineering. | |
| </p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="certificates" class="section"> | |
| <div class="container"> | |
| <h2 class="section-title">Certificates</h2> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6"> | |
| <div class="certificate-item glow-on-hover"> | |
| <div class="flex items-start"> | |
| <div class="text-3xl text-highlight mr-4"> | |
| <i class="fas fa-certificate"></i> | |
| </div> | |
| <div> | |
| <h3 class="text-xl font-semibold mb-2">Machine Learning with Python</h3> | |
| <p class="text-gray-400 mb-2">IBM | Coursera</p> | |
| <p class="text-gray-300 mb-4">Covered supervised/unsupervised learning, regression, classification, clustering, and model evaluation techniques.</p> | |
| <a href="#" class="text-highlight hover:underline">View Credential</a> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="certificate-item glow-on-hover"> | |
| <div class="flex items-start"> | |
| <div class="text-3xl text-highlight mr-4"> | |
| <i class="fas fa-certificate"></i> | |
| </div> | |
| <div> | |
| <h3 class="text-xl font-semibold mb-2">Introduction to Microsoft Azure Cloud Services</h3> | |
| <p class="text-gray-400 mb-2">Microsoft</p> | |
| <p class="text-gray-300 mb-4">Fundamentals of cloud computing with Azure, including ML services and deployment.</p> | |
| <a href="#" class="text-highlight hover:underline">View Credential</a> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="contact" class="section"> | |
| <div class="container"> | |
| <h2 class="section-title">Get In Touch</h2> | |
| <div class="flex flex-col md:flex-row"> | |
| <div class="md:w-1/2 mb-8 md:mb-0"> | |
| <form action="#" method="POST"> | |
| <div class="mb-6"> | |
| <label for="name" class="block mb-2">Name</label> | |
| <input type="text" id="name" name="name" required class="form-control" placeholder="Your Name"> | |
| </div> | |
| <div class="mb-6"> | |
| <label for="email" class="block mb-2">Email</label> | |
| <input type="email" id="email" name="email" required class="form-control" placeholder="Your Email"> | |
| </div> | |
| <div class="mb-6"> | |
| <label for="message" class="block mb-2">Message</label> | |
| <textarea id="message" name="message" rows="5" required class="form-control" placeholder="Your Message"></textarea> | |
| </div> | |
| <button type="submit" class="glowing-btn">Send Message</button> | |
| </form> | |
| </div> | |
| <div class="md:w-1/2 md:pl-8"> | |
| <div class="bg-secondary p-6 rounded-lg"> | |
| <h3 class="text-xl font-semibold mb-6">Contact Information</h3> | |
| <div class="flex items-center mb-4"> | |
| <div class="w-10 h-10 flex items-center justify-center bg-highlight bg-opacity-20 rounded-full mr-4"> | |
| <i class="fas fa-map-marker-alt text-highlight"></i> | |
| </div> | |
| <span>Pune, Maharashtra, India</span> | |
| </div> | |
| <div class="flex items-center mb-4"> | |
| <div class="w-10 h-10 flex items-center justify-center bg-highlight bg-opacity-20 rounded-full mr-4"> | |
| <i class="fas fa-envelope text-highlight"></i> | |
| </div> | |
| <span>sumitthundarok@gmail.com</span> | |
| </div> | |
| <div class="flex items-center mb-6"> | |
| <div class="w-10 h-10 flex items-center justify-center bg-highlight bg-opacity-20 rounded-full mr-4"> | |
| <i class="fas fa-phone-alt text-highlight"></i> | |
| </div> | |
| <span>+91 7061346085</span> | |
| </div> | |
| <h3 class="text-xl font-semibold mb-4">Follow Me</h3> | |
| <div class="flex"> | |
| <a href="#" class="social-link"> | |
| <i class="fab fa-github"></i> | |
| </a> | |
| <a href="#" class="social-link"> | |
| <i class="fab fa-linkedin-in"></i> | |
| </a> | |
| <a href="#" class="social-link"> | |
| <i class="fab fa-twitter"></i> | |
| </a> | |
| <a href="#" class="social-link"> | |
| <i class="fab fa-medium-m"></i> | |
| </a> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <footer class="bg-secondary py-8"> | |
| <div class="container"> | |
| <div class="flex flex-col md:flex-row justify-between items-center"> | |
| <div class="mb-4 md:mb-0"> | |
| <p>© 2024 Sumit Kumar. All Rights Reserved.</p> | |
| </div> | |
| <div> | |
| <p>Designed and Built with <span class="text-highlight">❤</span></p> | |
| </div> | |
| </div> | |
| </div> | |
| </footer> | |
| <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/gsap@3.9.1/dist/gsap.min.js"></script> | |
| <script> | |
| // Cursor follower | |
| const cursor = document.getElementById('cursor-follower'); | |
| let mouseX = 0, mouseY = 0; | |
| let cursorX = 0, cursorY = 0; | |
| document.addEventListener('mousemove', (e) => { | |
| mouseX = e.clientX; | |
| mouseY = e.clientY; | |
| }); | |
| function updateCursor() { | |
| const dx = mouseX - cursorX; | |
| const dy = mouseY - cursorY; | |
| cursorX += dx * 0.1; | |
| cursorY += dy * 0.1; | |
| cursor.style.left = cursorX + 'px'; | |
| cursor.style.top = cursorY + 'px'; | |
| requestAnimationFrame(updateCursor); | |
| } | |
| updateCursor(); | |
| // Hide cursor on mobile devices | |
| function isMobile() { | |
| return window.innerWidth <= 768; | |
| } | |
| function updateCursorVisibility() { | |
| if (isMobile()) { | |
| cursor.style.display = 'none'; | |
| } else { | |
| cursor.style.display = 'block'; | |
| } | |
| } | |
| updateCursorVisibility(); | |
| window.addEventListener('resize', updateCursorVisibility); | |
| // Mobile menu toggle | |
| const mobileMenuToggle = document.getElementById('mobile-menu-toggle'); | |
| const navMenu = document.getElementById('nav-menu'); | |
| mobileMenuToggle.addEventListener('click', () => { | |
| navMenu.classList.toggle('active'); | |
| }); | |
| // Smooth scrolling for navigation links | |
| document.querySelectorAll('.nav-link').forEach(link => { | |
| link.addEventListener('click', (e) => { | |
| e.preventDefault(); | |
| const targetId = link.getAttribute('href'); | |
| const targetSection = document.querySelector(targetId); | |
| window.scrollTo({ | |
| top: targetSection.offsetTop, | |
| behavior: 'smooth' | |
| }); | |
| // Close mobile menu if open | |
| if (navMenu.classList.contains('active')) { | |
| navMenu.classList.remove('active'); | |
| } | |
| }); | |
| }); | |
| // Hero canvas animation | |
| function initHeroCanvas() { | |
| if (isMobile()) return; // Skip on mobile for performance | |
| const container = document.getElementById('hero-canvas'); | |
| const renderer = new THREE.WebGLRenderer({ | |
| alpha: true, | |
| antialias: true | |
| }); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| container.appendChild(renderer.domElement); | |
| const scene = new THREE.Scene(); | |
| const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000); | |
| camera.position.z = 30; | |
| // Create particles | |
| const particlesGeometry = new THREE.BufferGeometry(); | |
| const particleCount = 2000; | |
| const posArray = new Float32Array(particleCount * 3); | |
| const colorArray = new Float32Array(particleCount * 3); | |
| for(let i = 0; i < particleCount * 3; i += 3) { | |
| // Position | |
| posArray[i] = (Math.random() - 0.5) * 50; | |
| posArray[i+1] = (Math.random() - 0.5) * 50; | |
| posArray[i+2] = (Math.random() - 0.5) * 50; | |
| // Color | |
| const h = 0.6 + Math.random() * 0.2; // Blue to purple hue range | |
| const s = 0.5 + Math.random() * 0.5; | |
| const l = 0.5 + Math.random() * 0.5; | |
| const color = new THREE.Color().setHSL(h, s, l); | |
| colorArray[i] = color.r; | |
| colorArray[i+1] = color.g; | |
| colorArray[i+2] = color.b; | |
| } | |
| particlesGeometry.setAttribute('position', new THREE.BufferAttribute(posArray, 3)); | |
| particlesGeometry.setAttribute('color', new THREE.BufferAttribute(colorArray, 3)); | |
| const particlesMaterial = new THREE.PointsMaterial({ | |
| size: 0.1, | |
| vertexColors: true, | |
| transparent: true, | |
| opacity: 0.8 | |
| }); | |
| const particlesMesh = new THREE.Points(particlesGeometry, particlesMaterial); | |
| scene.add(particlesMesh); | |
| // Create connections between nearby particles | |
| const linesMaterial = new THREE.LineBasicMaterial({ | |
| color: 0x64ffda, | |
| transparent: true, | |
| opacity: 0.1 | |
| }); | |
| const linesGeometry = new THREE.BufferGeometry(); | |
| const linesPositions = []; | |
| // Find particles that are close enough to connect | |
| const maxDistance = 5; | |
| const positions = particlesGeometry.attributes.position.array; | |
| for (let i = 0; i < particleCount; i++) { | |
| const x1 = positions[i * 3]; | |
| const y1 = positions[i * 3 + 1]; | |
| const z1 = positions[i * 3 + 2]; | |
| for (let j = i + 1; j < particleCount; j++) { | |
| const x2 = positions[j * 3]; | |
| const y2 = positions[j * 3 + 1]; | |
| const z2 = positions[j * 3 + 2]; | |
| const distance = Math.sqrt( | |
| Math.pow(x2 - x1, 2) + | |
| Math.pow(y2 - y1, 2) + | |
| Math.pow(z2 - z1, 2) | |
| ); | |
| if (distance < maxDistance && Math.random() > 0.95) { | |
| linesPositions.push(x1, y1, z1); | |
| linesPositions.push(x2, y2, z2); | |
| } | |
| } | |
| } | |
| linesGeometry.setAttribute('position', new THREE.Float32BufferAttribute(linesPositions, 3)); | |
| const linesMesh = new THREE.LineSegments(linesGeometry, linesMaterial); | |
| scene.add(linesMesh); | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| particlesMesh.rotation.x += 0.0005; | |
| particlesMesh.rotation.y += 0.0005; | |
| linesMesh.rotation.x += 0.0005; | |
| linesMesh.rotation.y += 0.0005; | |
| // Follow mouse movement for particles and lines | |
| if (mouseX && mouseY) { | |
| const normalizedMouseX = (mouseX / window.innerWidth) * 2 - 1; | |
| const normalizedMouseY = -(mouseY / window.innerHeight) * 2 + 1; | |
| particlesMesh.rotation.x += normalizedMouseY * 0.0005; | |
| particlesMesh.rotation.y += normalizedMouseX * 0.0005; | |
| linesMesh.rotation.x += normalizedMouseY * 0.0005; | |
| linesMesh.rotation.y += normalizedMouseX * 0.0005; | |
| } | |
| renderer.render(scene, camera); | |
| } | |
| animate(); | |
| // Handle window resize | |
| window.addEventListener('resize', () => { | |
| camera.aspect = container.clientWidth / container.clientHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| }); | |
| } | |
| // Brain model for about section | |
| function initBrainModel() { | |
| if (isMobile()) return; // Skip on mobile for performance | |
| const container = document.getElementById('brain-model'); | |
| const renderer = new THREE.WebGLRenderer({ | |
| alpha: true, | |
| antialias: true | |
| }); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| container.appendChild(renderer.domElement); | |
| const scene = new THREE.Scene(); | |
| const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000); | |
| camera.position.z = 15; | |
| // Create brain-like structure | |
| const brainGroup = new THREE.Group(); | |
| // Create the brain shape | |
| const brainGeometry = new THREE.SphereGeometry(5, 32, 32); | |
| const brainMaterial = new THREE.MeshBasicMaterial({ | |
| color: 0x5e38f7, | |
| wireframe: true, | |
| transparent: true, | |
| opacity: 0.5 | |
| }); | |
| const brainMesh = new THREE.Mesh(brainGeometry, brainMaterial); | |
| brainGroup.add(brainMesh); | |
| // Add neurons | |
| const neuronCount = 100; | |
| const neurons = []; | |
| for (let i = 0; i < neuronCount; i++) { | |
| const neuronGeometry = new THREE.SphereGeometry(0.1, 8, 8); | |
| const neuronMaterial = new THREE.MeshBasicMaterial({ | |
| color: 0x64ffda, | |
| transparent: true, | |
| opacity: 0.8 | |
| }); | |
| const neuron = new THREE.Mesh(neuronGeometry, neuronMaterial); | |
| // Position neurons randomly within the brain | |
| const phi = Math.random() * Math.PI * 2; | |
| const theta = Math.random() * Math.PI; | |
| const radius = Math.random() * 4 + 0.5; | |
| neuron.position.x = radius * Math.sin(theta) * Math.cos(phi); | |
| neuron.position.y = radius * Math.sin(theta) * Math.sin(phi); | |
| neuron.position.z = radius * Math.cos(theta); | |
| brainGroup.add(neuron); | |
| neurons.push({ | |
| mesh: neuron, | |
| initialPosition: neuron.position.clone(), | |
| speed: Math.random() * 0.02 + 0.01 | |
| }); | |
| } | |
| // Create connections between neurons | |
| const connections = []; | |
| for (let i = 0; i < neuronCount; i++) { | |
| for (let j = i + 1; j < neuronCount; j++) { | |
| if (Math.random() > 0.9) { | |
| const lineGeometry = new THREE.BufferGeometry(); | |
| const lineMaterial = new THREE.LineBasicMaterial({ | |
| color: 0x64ffda, | |
| transparent: true, | |
| opacity: 0.2 | |
| }); | |
| const points = [ | |
| neurons[i].mesh.position.clone(), | |
| neurons[j].mesh.position.clone() | |
| ]; | |
| lineGeometry.setFromPoints(points); | |
| const line = new THREE.Line(lineGeometry, lineMaterial); | |
| brainGroup.add(line); | |
| connections.push({ | |
| line: line, | |
| pointsIndices: [i, j], | |
| active: false, | |
| duration: Math.random() * 2000 + 1000 | |
| }); | |
| } | |
| } | |
| } | |
| scene.add(brainGroup); | |
| // Animate neurons and connections | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| // Rotate brain | |
| brainGroup.rotation.y += 0.003; | |
| // Update neuron positions | |
| neurons.forEach((neuron, index) => { | |
| const time = Date.now() * neuron.speed; | |
| const offset = Math.sin(time) * 0.2; | |
| neuron.mesh.position.x = neuron.initialPosition.x + offset; | |
| neuron.mesh.position.y = neuron.initialPosition.y + offset; | |
| neuron.mesh.position.z = neuron.initialPosition.z + offset; | |
| }); | |
| // Update connections | |
| connections.forEach(connection => { | |
| const points = [ | |
| neurons[connection.pointsIndices[0]].mesh.position.clone(), | |
| neurons[connection.pointsIndices[1]].mesh.position.clone() | |
| ]; | |
| connection.line.geometry.setFromPoints(points); | |
| connection.line.geometry.attributes.position.needsUpdate = true; | |
| // Randomly activate connections | |
| if (Math.random() > 0.995) { | |
| connection.active = true; | |
| connection.line.material.opacity = 0.8; | |
| connection.activationTime = Date.now(); | |
| } | |
| // Deactivate after duration | |
| if (connection.active && Date.now() - connection.activationTime > connection.duration) { | |
| connection.active = false; | |
| connection.line.material.opacity = 0.2; | |
| } | |
| }); | |
| // Follow mouse movement | |
| if (mouseX && mouseY) { | |
| const rect = container.getBoundingClientRect(); | |
| if ( | |
| mouseX >= rect.left && | |
| mouseX <= rect.right && | |
| mouseY >= rect.top && | |
| mouseY <= rect.bottom | |
| ) { | |
| const normalizedMouseX = ((mouseX - rect.left) / rect.width) * 2 - 1; | |
| const normalizedMouseY = -((mouseY - rect.top) / rect.height) * 2 + 1; | |
| brainGroup.rotation.y = normalizedMouseX * 0.5; | |
| brainGroup.rotation.x = normalizedMouseY * 0.5; | |
| } | |
| } | |
| renderer.render(scene, camera); | |
| } | |
| animate(); | |
| // Handle window resize | |
| window.addEventListener('resize', () => { | |
| camera.aspect = container.clientWidth / container.clientHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| }); | |
| } | |
| // Skills graph animation | |
| function initSkillsGraph() { | |
| if (isMobile()) return; // Skip on mobile for performance | |
| const container = document.getElementById('skills-graph'); | |
| const renderer = new THREE.WebGLRenderer({ | |
| alpha: true, | |
| antialias: true | |
| }); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| container.appendChild(renderer.domElement); | |
| const scene = new THREE.Scene(); | |
| const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000); | |
| camera.position.z = 15; | |
| // Create a skills graph visualization | |
| const skillsGroup = new THREE.Group(); | |
| // Define skills - removed Computer Vision | |
| const skills = [ | |
| { name: 'Python', level: 0.9, color: 0x4B8BBE }, | |
| { name: 'TensorFlow', level: 0.85, color: 0xFF6F00 }, | |
| { name: 'PyTorch', level: 0.8, color: 0xEE4C2C }, | |
| { name: 'Scikit-Learn', level: 0.9, color: 0xF89939 }, | |
| { name: 'Data Analysis', level: 0.88, color: 0x64ffda }, | |
| { name: 'NLP', level: 0.78, color: 0x9C27B0 }, | |
| { name: 'Deep Learning', level: 0.87, color: 0x5e38f7 } | |
| ]; | |
| // Create a 3D graph | |
| const center = new THREE.Vector3(0, 0, 0); | |
| const sphereGeometry = new THREE.SphereGeometry(0.3, 16, 16); | |
| const nodeObjects = []; | |
| skills.forEach((skill, index) => { | |
| // Position nodes in a circle | |
| const angle = (index / skills.length) * Math.PI * 2; | |
| const radius = 6; | |
| const x = Math.cos(angle) * radius; | |
| const y = Math.sin(angle) * radius; | |
| const z = (Math.random() - 0.5) * 4; | |
| const nodeMaterial = new THREE.MeshBasicMaterial({ color: skill.color }); | |
| const node = new THREE.Mesh(sphereGeometry, nodeMaterial); | |
| node.position.set(x, y, z); | |
| nodeObjects.push({ mesh: node, position: new THREE.Vector3(x, y, z) }); | |
| skillsGroup.add(node); | |
| // Create a line to center (skill level) | |
| const lineGeometry = new THREE.BufferGeometry(); | |
| const lineMaterial = new THREE.LineBasicMaterial({ | |
| color: skill.color, | |
| transparent: true, | |
| opacity: 0.7 | |
| }); | |
| const scaledCenter = center.clone().lerp(node.position, 1 - skill.level); | |
| const points = [ | |
| scaledCenter, | |
| node.position.clone() | |
| ]; | |
| lineGeometry.setFromPoints(points); | |
| const line = new THREE.Line(lineGeometry, lineMaterial); | |
| skillsGroup.add(line); | |
| }); | |
| // Connect nodes that are related | |
| for (let i = 0; i < nodeObjects.length; i++) { | |
| for (let j = i + 1; j < nodeObjects.length; j++) { | |
| if (Math.random() > 0.5) { // Only connect some nodes | |
| const lineGeometry = new THREE.BufferGeometry(); | |
| const lineMaterial = new THREE.LineBasicMaterial({ | |
| color: 0x64ffda, | |
| transparent: true, | |
| opacity: 0.2 | |
| }); | |
| const points = [ | |
| nodeObjects[i].position.clone(), | |
| nodeObjects[j].position.clone() | |
| ]; | |
| lineGeometry.setFromPoints(points); | |
| const line = new THREE.Line(lineGeometry, lineMaterial); | |
| skillsGroup.add(line); | |
| } | |
| } | |
| } | |
| scene.add(skillsGroup); | |
| // Create floating particles | |
| const particlesGeometry = new THREE.BufferGeometry(); | |
| const particleCount = 200; | |
| const particlePositions = new Float32Array(particleCount * 3); | |
| for (let i = 0; i < particleCount * 3; i += 3) { | |
| particlePositions[i] = (Math.random() - 0.5) * 20; | |
| particlePositions[i + 1] = (Math.random() - 0.5) * 20; | |
| particlePositions[i + 2] = (Math.random() - 0.5) * 20; | |
| } | |
| particlesGeometry.setAttribute('position', new THREE.BufferAttribute(particlePositions, 3)); | |
| const particlesMaterial = new THREE.PointsMaterial({ | |
| color: 0x64ffda, | |
| size: 0.1, | |
| transparent: true, | |
| opacity: 0.6 | |
| }); | |
| const particles = new THREE.Points(particlesGeometry, particlesMaterial); | |
| scene.add(particles); | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| // Rotate the skills graph | |
| skillsGroup.rotation.y += 0.002; | |
| // Animate particles | |
| const positions = particlesGeometry.attributes.position.array; | |
| for (let i = 0; i < positions.length; i += 3) { | |
| positions[i + 1] += (Math.random() - 0.5) * 0.02; | |
| if (Math.abs(positions[i + 1]) > 10) { | |
| positions[i + 1] *= -1; | |
| } | |
| } | |
| particlesGeometry.attributes.position.needsUpdate = true; | |
| // Follow mouse movement | |
| if (mouseX && mouseY) { | |
| const rect = container.getBoundingClientRect(); | |
| if ( | |
| mouseX >= rect.left && | |
| mouseX <= rect.right && | |
| mouseY >= rect.top && | |
| mouseY <= rect.bottom | |
| ) { | |
| const normalizedMouseX = ((mouseX - rect.left) / rect.width) * 2 - 1; | |
| const normalizedMouseY = -((mouseY - rect.top) / rect.height) * 2 + 1; | |
| skillsGroup.rotation.y = normalizedMouseX * 1; | |
| skillsGroup.rotation.x = normalizedMouseY * 0.5; | |
| } | |
| } | |
| renderer.render(scene, camera); | |
| } | |
| animate(); | |
| // Handle window resize | |
| window.addEventListener('resize', () => { | |
| camera.aspect = container.clientWidth / container.clientHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| }); | |
| } | |
| // Project visualizations | |
| function initProject1Canvas() { | |
| const container = document.getElementById('project1-canvas'); | |
| if (!container) return; | |
| const renderer = new THREE.WebGLRenderer({ | |
| alpha: true, | |
| antialias: true | |
| }); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| container.appendChild(renderer.domElement); | |
| const scene = new THREE.Scene(); | |
| const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000); | |
| camera.position.z = 5; | |
| // Create anomaly detection visualization | |
| const dataPoints = []; | |
| const dataPointCount = 50; | |
| const normalPointMaterial = new THREE.MeshBasicMaterial({ color: 0x64ffda }); | |
| const anomalyPointMaterial = new THREE.MeshBasicMaterial({ color: 0xff6b6b }); | |
| const pointGeometry = new THREE.SphereGeometry(0.1, 8, 8); | |
| // Create a grid plane for reference | |
| const gridGeometry = new THREE.PlaneGeometry(10, 10, 10, 10); | |
| const gridMaterial = new THREE.MeshBasicMaterial({ | |
| color: 0x444444, | |
| wireframe: true, | |
| transparent: true, | |
| opacity: 0.3 | |
| }); | |
| const grid = new THREE.Mesh(gridGeometry, gridMaterial); | |
| grid.rotation.x = -Math.PI / 2; | |
| scene.add(grid); | |
| // Create data points | |
| for (let i = 0; i < dataPointCount; i++) { | |
| const isAnomaly = Math.random() > 0.9; | |
| let x, y, z; | |
| if (isAnomaly) { | |
| // Anomalies are more spread out | |
| x = (Math.random() - 0.5) * 8; | |
| y = (Math.random() - 0.5) * 8; | |
| z = (Math.random() - 0.5) * 8; | |
| } else { | |
| // Normal data points are clustered | |
| x = (Math.random() - 0.5) * 4; | |
| y = (Math.random() - 0.5) * 4; | |
| z = (Math.random() - 0.5) * 4; | |
| } | |
| const material = isAnomaly ? anomalyPointMaterial : normalPointMaterial; | |
| const point = new THREE.Mesh(pointGeometry, material); | |
| point.position.set(x, y, z); | |
| scene.add(point); | |
| dataPoints.push({ | |
| mesh: point, | |
| isAnomaly: isAnomaly, | |
| originalPosition: new THREE.Vector3(x, y, z), | |
| velocity: new THREE.Vector3( | |
| (Math.random() - 0.5) * 0.01, | |
| (Math.random() - 0.5) * 0.01, | |
| (Math.random() - 0.5) * 0.01 | |
| ) | |
| }); | |
| } | |
| // Add anomaly detection boundary | |
| const boundaryGeometry = new THREE.SphereGeometry(3, 32, 32); | |
| const boundaryMaterial = new THREE.MeshBasicMaterial({ | |
| color: 0x64ffda, | |
| wireframe: true, | |
| transparent: true, | |
| opacity: 0.2 | |
| }); | |
| const boundary = new THREE.Mesh(boundaryGeometry, boundaryMaterial); | |
| scene.add(boundary); | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| // Animate data points | |
| dataPoints.forEach(point => { | |
| point.mesh.position.add(point.velocity); | |
| // Bounce back if too far from original position | |
| const distance = point.mesh.position.distanceTo(point.originalPosition); | |
| if (distance > 1) { | |
| point.velocity.multiplyScalar(-1); | |
| } | |
| // Highlight anomalies | |
| if (point.isAnomaly) { | |
| point.mesh.scale.setScalar(1 + Math.sin(Date.now() * 0.005) * 0.5); | |
| } | |
| }); | |
| // Pulse the boundary | |
| boundary.scale.setScalar(1 + Math.sin(Date.now() * 0.001) * 0.05); | |
| // Rotate the scene | |
| scene.rotation.y += 0.005; | |
| renderer.render(scene, camera); | |
| } | |
| animate(); | |
| // Handle window resize | |
| window.addEventListener('resize', () => { | |
| camera.aspect = container.clientWidth / container.clientHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| }); | |
| } | |
| function initProject2Canvas() { | |
| const container = document.getElementById('project2-canvas'); | |
| if (!container) return; | |
| const renderer = new THREE.WebGLRenderer({ | |
| alpha: true, | |
| antialias: true | |
| }); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| container.appendChild(renderer.domElement); | |
| const scene = new THREE.Scene(); | |
| const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000); | |
| camera.position.z = 5; | |
| // Create NLP visualization | |
| const textGeometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16); | |
| const textMaterial = new THREE.MeshBasicMaterial({ | |
| color: 0x5e38f7, | |
| wireframe: true, | |
| transparent: true, | |
| opacity: 0.7 | |
| }); | |
| const textModel = new THREE.Mesh(textGeometry, textMaterial); | |
| scene.add(textModel); | |
| // Add text particles | |
| const particlesGeometry = new THREE.BufferGeometry(); | |
| const particleCount = 100; | |
| const particlePositions = new Float32Array(particleCount * 3); | |
| const particleSizes = new Float32Array(particleCount); | |
| for (let i = 0; i < particleCount * 3; i += 3) { | |
| const phi = Math.random() * Math.PI * 2; | |
| const theta = Math.random() * Math.PI; | |
| const radius = 2 + Math.random() * 1; | |
| particlePositions[i] = radius * Math.sin(theta) * Math.cos(phi); | |
| particlePositions[i + 1] = radius * Math.sin(theta) * Math.sin(phi); | |
| particlePositions[i + 2] = radius * Math.cos(theta); | |
| particleSizes[i / 3] = Math.random() * 0.2 + 0.05; | |
| } | |
| particlesGeometry.setAttribute('position', new THREE.BufferAttribute(particlePositions, 3)); | |
| particlesGeometry.setAttribute('size', new THREE.BufferAttribute(particleSizes, 1)); | |
| const particlesMaterial = new THREE.PointsMaterial({ | |
| color: 0x64ffda, | |
| size: 0.1, | |
| transparent: true, | |
| opacity: 0.8 | |
| }); | |
| const particles = new THREE.Points(particlesGeometry, particlesMaterial); | |
| scene.add(particles); | |
| // Add connections between particles | |
| const linesMaterial = new THREE.LineBasicMaterial({ | |
| color: 0x64ffda, | |
| transparent: true, | |
| opacity: 0.2 | |
| }); | |
| const linesGeometry = new THREE.BufferGeometry(); | |
| const linePositions = []; | |
| for (let i = 0; i < particleCount; i++) { | |
| const i3 = i * 3; | |
| const x1 = particlePositions[i3]; | |
| const y1 = particlePositions[i3 + 1]; | |
| const z1 = particlePositions[i3 + 2]; | |
| for (let j = i + 1; j < particleCount; j++) { | |
| const j3 = j * 3; | |
| const x2 = particlePositions[j3]; | |
| const y2 = particlePositions[j3 + 1]; | |
| const z2 = particlePositions[j3 + 2]; | |
| const distance = Math.sqrt( | |
| Math.pow(x2 - x1, 2) + | |
| Math.pow(y2 - y1, 2) + | |
| Math.pow(z2 - z1, 2) | |
| ); | |
| if (distance < 1 && Math.random() > 0.9) { | |
| linePositions.push(x1, y1, z1); | |
| linePositions.push(x2, y2, z2); | |
| } | |
| } | |
| } | |
| linesGeometry.setAttribute('position', new THREE.Float32BufferAttribute(linePositions, 3)); | |
| const lines = new THREE.LineSegments(linesGeometry, linesMaterial); | |
| scene.add(lines); | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| // Rotate torus knot | |
| textModel.rotation.x += 0.005; | |
| textModel.rotation.y += 0.003; | |
| // Animate particles | |
| const positions = particlesGeometry.attributes.position.array; | |
| for (let i = 0; i < particleCount; i++) { | |
| const i3 = i * 3; | |
| // Orbit effect | |
| const x = positions[i3]; | |
| const z = positions[i3 + 2]; | |
| const angle = Math.atan2(z, x) + 0.005; | |
| const radius = Math.sqrt(x * x + z * z); | |
| positions[i3] = Math.cos(angle) * radius; | |
| positions[i3 + 2] = Math.sin(angle) * radius; | |
| // Pulse effect | |
| particleSizes[i] = 0.05 + Math.sin(Date.now() * 0.001 + i) * 0.05; | |
| } | |
| particlesGeometry.attributes.position.needsUpdate = true; | |
| particlesGeometry.attributes.size.needsUpdate = true; | |
| // Rotate the whole scene | |
| scene.rotation.y += 0.002; | |
| renderer.render(scene, camera); | |
| } | |
| animate(); | |
| // Handle window resize | |
| window.addEventListener('resize', () => { | |
| camera.aspect = container.clientWidth / container.clientHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| }); | |
| } | |
| function initProject3Canvas() { | |
| const container = document.getElementById('project3-canvas'); | |
| if (!container) return; | |
| const renderer = new THREE.WebGLRenderer({ | |
| alpha: true, | |
| antialias: true | |
| }); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| container.appendChild(renderer.domElement); | |
| const scene = new THREE.Scene(); | |
| const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000); | |
| camera.position.z = 5; | |
| // Housing price prediction visualization | |
| // Create a house | |
| const houseGroup = new THREE.Group(); | |
| // Base | |
| const baseGeometry = new THREE.BoxGeometry(2, 0.2, 1.5); | |
| const baseMaterial = new THREE.MeshBasicMaterial({ color: 0x666666 }); | |
| const base = new THREE.Mesh(baseGeometry, baseMaterial); | |
| base.position.y = -0.5; | |
| houseGroup.add(base); | |
| // Walls | |
| const wallsGeometry = new THREE.BoxGeometry(1.8, 1, 1.3); | |
| const wallsMaterial = new THREE.MeshBasicMaterial({ color: 0xcccccc }); | |
| const walls = new THREE.Mesh(wallsGeometry, wallsMaterial); | |
| houseGroup.add(walls); | |
| // Roof | |
| const roofGeometry = new THREE.ConeGeometry(1.3, 0.8, 4); | |
| const roofMaterial = new THREE.MeshBasicMaterial({ color: 0x993300 }); | |
| const roof = new THREE.Mesh(roofGeometry, roofMaterial); | |
| roof.rotation.y = Math.PI / 4; | |
| roof.position.y = 0.9; | |
| houseGroup.add(roof); | |
| scene.add(houseGroup); | |
| // Add price graph | |
| const graphGroup = new THREE.Group(); | |
| graphGroup.position.set(-3, 0, 0); | |
| // Price line | |
| const lineGeometry = new THREE.BufferGeometry(); | |
| const lineMaterial = new THREE.LineBasicMaterial({ color: 0x64ffda }); | |
| const points = []; | |
| for (let i = 0; i < 10; i++) { | |
| const x = i * 0.3; | |
| const y = Math.sin(i * 0.5) * 0.5 + Math.random() * 0.3; | |
| points.push(new THREE.Vector3(x, y, 0)); | |
| } | |
| lineGeometry.setFromPoints(points); | |
| const priceLine = new THREE.Line(lineGeometry, lineMaterial); | |
| graphGroup.add(priceLine); | |
| // Add graph axes | |
| const axesGeometry = new THREE.BufferGeometry(); | |
| const axesMaterial = new THREE.LineBasicMaterial({ | |
| color: 0xffffff, | |
| opacity: 0.5, | |
| transparent: true | |
| }); | |
| const axesPoints = [ | |
| new THREE.Vector3(0, -1, 0), | |
| new THREE.Vector3(0, 1, 0), | |
| new THREE.Vector3(0, 0, 0), | |
| new THREE.Vector3(3, 0, 0) | |
| ]; | |
| axesGeometry.setFromPoints(axesPoints); | |
| const axes = new THREE.LineSegments(axesGeometry, axesMaterial); | |
| graphGroup.add(axes); | |
| // Add data points | |
| const dataPoints = []; | |
| const dataGeometry = new THREE.SphereGeometry(0.05, 8, 8); | |
| const dataMaterial = new THREE.MeshBasicMaterial({ color: 0xff6b6b }); | |
| for (let i = 0; i < 30; i++) { | |
| const x = Math.random() * 3; | |
| const y = Math.random() * 2 - 1; | |
| const z = Math.random() * 2 - 1; | |
| const point = new THREE.Mesh(dataGeometry, dataMaterial); | |
| point.position.set(x, y, z); | |
| graphGroup.add(point); | |
| dataPoints.push({ | |
| mesh: point, | |
| initialPosition: new THREE.Vector3(x, y, z), | |
| velocity: new THREE.Vector3( | |
| (Math.random() - 0.5) * 0.01, | |
| (Math.random() - 0.5) * 0.01, | |
| (Math.random() - 0.5) * 0.01 | |
| ) | |
| }); | |
| } | |
| scene.add(graphGroup); | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| // Rotate house | |
| houseGroup.rotation.y += 0.01; | |
| // Animate data points | |
| dataPoints.forEach(point => { | |
| point.mesh.position.add(point.velocity); | |
| // Bounce back if too far from original position | |
| const distance = point.mesh.position.distanceTo(point.initialPosition); | |
| if (distance > 0.3) { | |
| point.velocity.multiplyScalar(-1); | |
| } | |
| }); | |
| // Animate price line | |
| const linePoints = []; | |
| for (let i = 0; i < 10; i++) { | |
| const x = i * 0.3; | |
| const time = Date.now() * 0.001 + i; | |
| const y = Math.sin(time * 0.3) * 0.3 + 0.5; | |
| linePoints.push(new THREE.Vector3(x, y, 0)); | |
| } | |
| lineGeometry.setFromPoints(linePoints); | |
| renderer.render(scene, camera); | |
| } | |
| animate(); | |
| // Handle window resize | |
| window.addEventListener('resize', () => { | |
| camera.aspect = container.clientWidth / container.clientHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| }); | |
| } | |
| // Education radar animation with maximum visibility | |
| function initEducationRadar() { | |
| const container = document.getElementById('education-canvas'); | |
| if (!container) { | |
| console.error("Education canvas container not found"); | |
| return; | |
| } | |
| // Clear any existing canvas | |
| while (container.firstChild) { | |
| container.removeChild(container.firstChild); | |
| } | |
| const renderer = new THREE.WebGLRenderer({ | |
| alpha: true, | |
| antialias: true | |
| }); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| container.appendChild(renderer.domElement); | |
| const scene = new THREE.Scene(); | |
| const camera = new THREE.PerspectiveCamera(60, container.clientWidth / container.clientHeight, 0.1, 1000); | |
| camera.position.z = 4; // Position camera much closer | |
| // Create a more eye-catching BVCOE logo visualization | |
| const logoGroup = new THREE.Group(); | |
| // College emblem base - more vibrant and larger | |
| const emblemGeometry = new THREE.CircleGeometry(1.5, 32); | |
| const emblemMaterial = new THREE.MeshBasicMaterial({ | |
| color: 0x112240, | |
| transparent: true, | |
| opacity: 0.9 | |
| }); | |
| const emblem = new THREE.Mesh(emblemGeometry, emblemMaterial); | |
| logoGroup.add(emblem); | |
| // Create much brighter, more vibrant rings | |
| const createRing = (radius, tubeRadius, color, opacity) => { | |
| const geometry = new THREE.TorusGeometry(radius, tubeRadius, 16, 100); | |
| const material = new THREE.MeshBasicMaterial({ | |
| color: color, | |
| transparent: true, | |
| opacity: opacity | |
| }); | |
| return new THREE.Mesh(geometry, material); | |
| }; | |
| // Add extra-bright colored rings with increased size | |
| const ring1 = createRing(1.3, 0.08, 0x64ffda, 1.0); | |
| const ring2 = createRing(1.0, 0.06, 0x5e38f7, 1.0); | |
| const ring3 = createRing(0.7, 0.04, 0x0ea5e9, 1.0); | |
| logoGroup.add(ring1, ring2, ring3); | |
| // Add prominent particles with glow effect | |
| const createOrbitalParticles = (radius, count, color) => { | |
| const geometry = new THREE.BufferGeometry(); | |
| const positions = new Float32Array(count * 3); | |
| for (let i = 0; i < count; i++) { | |
| const angle = (i / count) * Math.PI * 2; | |
| const x = Math.cos(angle) * radius; | |
| const y = Math.sin(angle) * radius; | |
| const z = (Math.random() - 0.5) * 0.1; | |
| positions[i * 3] = x; | |
| positions[i * 3 + 1] = y; | |
| positions[i * 3 + 2] = z; | |
| } | |
| geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); | |
| const material = new THREE.PointsMaterial({ | |
| color: color, | |
| size: 0.25, // Much larger size | |
| transparent: true, | |
| opacity: 1.0 // Full opacity | |
| }); | |
| return new THREE.Points(geometry, material); | |
| }; | |
| // Create larger, more visible orbital particles | |
| const particles1 = createOrbitalParticles(1.3, 15, 0x64ffda); | |
| const particles2 = createOrbitalParticles(1.0, 12, 0x5e38f7); | |
| const particles3 = createOrbitalParticles(0.7, 9, 0x0ea5e9); | |
| logoGroup.add(particles1, particles2, particles3); | |
| // Add bright center glow | |
| const centerGeometry = new THREE.CircleGeometry(0.3, 32); | |
| const centerMaterial = new THREE.MeshBasicMaterial({ | |
| color: 0xffffff, | |
| transparent: true, | |
| opacity: 0.9 | |
| }); | |
| const center = new THREE.Mesh(centerGeometry, centerMaterial); | |
| logoGroup.add(center); | |
| // Add letter "B" for BVCOE | |
| const addLetter = (letter, position, color) => { | |
| // Use box geometry to create simple letters | |
| const letterGeometry = new THREE.BoxGeometry(0.15, 0.3, 0.05); | |
| const letterMaterial = new THREE.MeshBasicMaterial({ | |
| color: color, | |
| transparent: false | |
| }); | |
| const mesh = new THREE.Mesh(letterGeometry, letterMaterial); | |
| mesh.position.set(position.x, position.y, position.z); | |
| return mesh; | |
| }; | |
| // Add simple representation of letters | |
| const bLetter = addLetter("B", {x: -0.15, y: 0, z: 0.1}, 0x64ffda); | |
| logoGroup.add(bLetter); | |
| scene.add(logoGroup); | |
| // Animation loop with faster and more noticeable movements | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| // Rotate rings faster for more visibility | |
| ring1.rotation.z += 0.02; | |
| ring2.rotation.z -= 0.025; | |
| ring3.rotation.z += 0.03; | |
| // Rotate particles in opposite directions (faster) | |
| particles1.rotation.z -= 0.015; | |
| particles2.rotation.z += 0.02; | |
| particles3.rotation.z -= 0.025; | |
| // Pulse center with high visibility | |
| const scale = 1 + Math.sin(Date.now() * 0.005) * 0.3; | |
| center.scale.set(scale, scale, 1); | |
| // Add automatic rotation for constant movement | |
| logoGroup.rotation.y += 0.01; | |
| // Interactive rotation - more responsive | |
| if (mouseX && mouseY) { | |
| const rect = container.getBoundingClientRect(); | |
| if ( | |
| mouseX >= rect.left && | |
| mouseX <= rect.right && | |
| mouseY >= rect.top && | |
| mouseY <= rect.bottom | |
| ) { | |
| const normalizedMouseX = ((mouseX - rect.left) / rect.width) * 2 - 1; | |
| const normalizedMouseY = -((mouseY - rect.top) / rect.height) * 2 + 1; | |
| logoGroup.rotation.x = normalizedMouseY * 0.8; // More responsive rotation | |
| logoGroup.rotation.y = normalizedMouseX * 0.8; | |
| } else { | |
| // Slower return to neutral position | |
| logoGroup.rotation.x *= 0.95; | |
| } | |
| } | |
| renderer.render(scene, camera); | |
| } | |
| animate(); | |
| // Force the right size immediately and handle window resize | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| window.addEventListener('resize', () => { | |
| camera.aspect = container.clientWidth / container.clientHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(container.clientWidth, container.clientHeight); | |
| }); | |
| console.log("Education radar animation initialized"); | |
| } | |
| // Progress bars animation | |
| function animateProgressBars() { | |
| const progressBars = document.querySelectorAll('.progress'); | |
| const observer = new IntersectionObserver((entries) => { | |
| entries.forEach(entry => { | |
| if (entry.isIntersecting) { | |
| const target = entry.target; | |
| const width = target.getAttribute('data-width'); | |
| target.style.width = width; | |
| observer.unobserve(target); | |
| } | |
| }); | |
| }, { threshold: 0.1 }); | |
| progressBars.forEach(bar => { | |
| observer.observe(bar); | |
| }); | |
| } | |
| // Initialize all animations | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Initialize canvases | |
| initHeroCanvas(); | |
| initBrainModel(); | |
| initSkillsGraph(); | |
| initProject1Canvas(); | |
| initProject2Canvas(); | |
| initProject3Canvas(); | |
| initEducationRadar(); | |
| // Initialize other animations | |
| animateProgressBars(); | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Sumitkumar098/portfolio-webiste" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> | |