Skip to content

Commit 849b53b

Browse files
added animated login project (irfanshadikrishad#8)
1 parent 22ec792 commit 849b53b

3 files changed

Lines changed: 167 additions & 0 deletions

File tree

animated login/index.html

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Animated Neon Login</title>
7+
<link rel="stylesheet" href="style.css">
8+
</head>
9+
<body>
10+
<canvas id="bg-canvas"></canvas>
11+
12+
<!-- Login Form -->
13+
<div class="neon-login-container" id="loginContainer">
14+
<h2 class="neon-text">LOGIN</h2>
15+
<form id="login-form">
16+
<div class="neon-input-group">
17+
<input type="text" id="username" required autocomplete="off" placeholder=" " />
18+
<label for="username" class="neon-label">Username</label>
19+
</div>
20+
<div class="neon-input-group">
21+
<input type="password" id="password" required autocomplete="off" placeholder=" " />
22+
<label for="password" class="neon-label">Password</label>
23+
</div>
24+
<button type="submit" class="neon-btn">
25+
<span class="btn-text">Login</span>
26+
<span class="spinner"></span>
27+
</button>
28+
<div id="message" class="login-message"></div>
29+
</form>
30+
</div>
31+
32+
<!-- Welcome Page -->
33+
<div class="welcome-container" id="welcomeContainer" style="display:none;">
34+
<h1 class="welcome-text" id="welcomeMessage">Welcome!</h1>
35+
<button class="neon-btn" id="logoutBtn">Logout</button>
36+
</div>
37+
38+
<script src="script.js"></script>
39+
</body>
40+
</html>

animated login/script.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// ---------------- Background Bubbles ----------------
2+
const canvas=document.getElementById('bg-canvas');
3+
const ctx=canvas.getContext('2d');
4+
let w,h;
5+
function resizeCanvas(){ w=canvas.width=window.innerWidth; h=canvas.height=window.innerHeight; }
6+
window.addEventListener('resize',resizeCanvas); resizeCanvas();
7+
8+
class Bubble{constructor(){this.x=Math.random()*w;this.y=h+Math.random()*100;this.radius=15+Math.random()*25;
9+
this.vx=(Math.random()-0.5)*0.5;this.vy=-0.6-Math.random();this.alpha=0.1+Math.random()*0.1;
10+
this.color=['#14fff1','#f75fff','#2afaff','#ff4fd7','#64ffe7'][Math.floor(Math.random()*5)];}
11+
update(){this.x+=this.vx;this.y+=this.vy;if(this.y+this.radius<0){this.y=h+Math.random()*100;this.x=Math.random()*w;}}
12+
draw(){ctx.save();ctx.globalAlpha=this.alpha;ctx.beginPath();ctx.arc(this.x,this.y,this.radius,0,Math.PI*2);
13+
ctx.fillStyle=this.color;ctx.shadowColor=this.color;ctx.shadowBlur=20;ctx.fill();ctx.restore();}}
14+
15+
const bubbles=[];
16+
for(let i=0;i<40;i++) bubbles.push(new Bubble());
17+
function animate(){ ctx.clearRect(0,0,w,h); bubbles.forEach(b=>{b.update();b.draw();}); requestAnimationFrame(animate);}
18+
animate();
19+
20+
// ---------------- Login ----------------
21+
const loginForm=document.getElementById("login-form");
22+
const loginContainer=document.getElementById("loginContainer");
23+
const welcomeContainer=document.getElementById("welcomeContainer");
24+
const usernameInput=document.getElementById("username");
25+
const passwordInput=document.getElementById("password");
26+
const message=document.getElementById("message");
27+
const neonBtn=document.querySelector(".neon-btn");
28+
const btnText=neonBtn.querySelector(".btn-text");
29+
const spinner=neonBtn.querySelector(".spinner");
30+
const logoutBtn=document.getElementById("logoutBtn");
31+
const welcomeMsg=document.getElementById("welcomeMessage");
32+
33+
const validUsername="admin";
34+
const validPassword="12345";
35+
36+
// Check if already logged in
37+
const loggedUser=localStorage.getItem("loggedInUser");
38+
if(loggedUser){
39+
loginContainer.style.display="none";
40+
welcomeContainer.style.display="block";
41+
welcomeMsg.textContent=`Welcome, ${loggedUser}!`;
42+
}
43+
44+
// Login submit
45+
loginForm.addEventListener("submit",(e)=>{
46+
e.preventDefault();
47+
const username=usernameInput.value.trim();
48+
const password=passwordInput.value.trim();
49+
50+
message.style.opacity=0;
51+
loginForm.classList.remove("shake");
52+
btnText.textContent="";
53+
spinner.style.display="inline-block";
54+
neonBtn.disabled=true;
55+
56+
setTimeout(()=>{
57+
spinner.style.display="none";
58+
neonBtn.disabled=false;
59+
60+
if(username===validUsername && password===validPassword){
61+
btnText.textContent="Success!";
62+
localStorage.setItem("loggedInUser",username);
63+
loginContainer.style.display="none";
64+
welcomeContainer.style.display="block";
65+
welcomeMsg.textContent=`Welcome, ${username}!`;
66+
} else {
67+
btnText.textContent="Login";
68+
message.textContent="❌ Invalid Username or Password!";
69+
message.style.color="#f75fff";
70+
message.style.opacity=1;
71+
loginForm.classList.add("shake");
72+
}
73+
74+
setTimeout(()=>{ btnText.textContent="Login"; },1500);
75+
},1000);
76+
});
77+
78+
// Logout
79+
logoutBtn.addEventListener("click",()=>{
80+
localStorage.removeItem("loggedInUser");
81+
welcomeContainer.style.display="none";
82+
loginContainer.style.display="block";
83+
usernameInput.value="";
84+
passwordInput.value="";
85+
message.style.opacity=0;
86+
});

animated login/style.css

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
body, html {
2+
margin:0; padding:0;
3+
width:100vw; height:100vh;
4+
font-family:'Montserrat',sans-serif;
5+
background:#09151e; overflow:hidden;
6+
display:flex; justify-content:center; align-items:center;
7+
}
8+
9+
canvas#bg-canvas { position:fixed; top:0; left:0; width:100vw; height:100vh; z-index:0; }
10+
11+
/* --- Login Container --- */
12+
.neon-login-container, .welcome-container {
13+
position:relative; z-index:2;
14+
width:350px; background:rgba(20,25,41,0.88); border-radius:20px;
15+
box-shadow:0 0 46px #14fff1bb,0 0 120px #f75fff55 inset;
16+
text-align:center; padding:50px 32px; backdrop-filter:blur(7px);
17+
animation:cardPulse 3s infinite alternate;
18+
}
19+
20+
@keyframes cardPulse { 0%{box-shadow:0 0 38px #14fff1bb,0 0 88px #f75fff33 inset;} 100%{box-shadow:0 0 70px #14fff1dd,0 0 180px #f75fff88 inset;} }
21+
22+
.neon-text { font-size:2rem; color:#14fff1; font-weight:bold; text-shadow:0 0 19px #14fff1,0 0 36px #f75fff; margin-bottom:22px; animation:flicker 2s infinite alternate;}
23+
@keyframes flicker{0%,28%,72%,100%{text-shadow:0 0 24px #14fff1,0 0 44px #f75fff;}44%,55%{text-shadow:none;}}
24+
25+
.neon-input-group { position:relative; margin-bottom:28px; }
26+
.neon-input-group input { width:100%; font-size:18px; padding:13px 11px; background:transparent; border:none; border-bottom:3px solid #14fff1; color:#fff; outline:none; box-shadow:inset 0 0 13px #14fff1aa; transition:border-color 0.3s; }
27+
.neon-input-group input:focus { border-color:#f75fff; box-shadow:0 0 14px #f75fffdb; }
28+
.neon-label { position:absolute; left:11px; top:13px; color:#14fff1; font-weight:600; cursor:text; pointer-events:none; transition:all 0.3s; font-size:15px; text-shadow:0 0 15px #14fff1aa; }
29+
.neon-input-group input:focus ~ .neon-label, .neon-input-group input:not(:placeholder-shown) ~ .neon-label { top:-18px; font-size:12px; color:#f75fff; text-shadow:0 0 21px #f75fff; }
30+
31+
.neon-btn { width:100%; padding:12px 0; font-size:19px; font-weight:700; color:#14fff1; border:3px solid #14fff1; background:transparent; border-radius:12px; box-shadow:0 0 25px #14fff1, inset 0 0 42px #f75fffcc; cursor:pointer; letter-spacing:0.09em; transition:all 0.32s; }
32+
.neon-btn:hover { background:#14fff1; border-color:#f75fff; color:#1a2131; box-shadow:0 0 100px #f75fff,0 0 155px #14fff1 inset; transform:scale(1.06); }
33+
.spinner { display:none; margin-left:7px; width:21px; height:21px; border:3px solid #212333; border-top:3px solid #14fff1; border-radius:50%; animation:spin 0.85s linear infinite; }
34+
@keyframes spin{100%{transform:rotate(360deg);}}
35+
36+
.login-message { margin-top:15px; font-weight:600; text-align:center; opacity:0; transition:opacity 0.4s ease; }
37+
.shake { animation:shake 0.4s; }
38+
@keyframes shake{0%,100%{transform:translateX(0);}20%,60%{transform:translateX(-8px);}40%,80%{transform:translateX(8px);}}
39+
40+
/* Welcome Page */
41+
.welcome-text { font-size:2.2rem; color:#14fff1; text-shadow:0 0 20px #14fff1,0 0 40px #f75fff; animation:flicker 2s infinite alternate; margin-bottom:20px; }

0 commit comments

Comments
 (0)