Code Details
Animation Login Form
Animation Login Form
Web Development
Animation
sigin-signup page
<!doctype html>
<html lang="bn">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Neon Login — Mouse Reactive Background</title>
</head>
<body>
<canvas id="bg"></canvas>
<div class="wrap">
<div class="card" id="card">
<header>
<h1>LOGIN</h1>
<p>Welcome Back</p>
</header>
<form onsubmit="event.preventDefault(); alert('Sign in (demo)')" autocomplete="off">
<div class="field">
<label for="user">Username</label>
<input id="user" type="text" placeholder="Enter username" />
</div>
<div class="field">
<label for="pass">Password</label>
<input id="pass" type="password" placeholder="Enter password" />
</div>
<div class="controls">
<label class="checkbox"><input type="checkbox" /> Remember me</label>
<a href="#" style="color:var(--muted); text-decoration:none; font-size:13px;">Forgot Password?</a>
</div>
<button class="btn" type="submit">Sign In</button>
</form>
<a class="mutelink" href="#">Don't have an account? <strong style="color:var(--accent1)">Register</strong></a>
</div>
</div>
<script>
/* ---------------------------
Particle network background
- responsive canvas
- particles attract/repel based on mouse
- lines drawn between close particles
- small parallax translate for card
----------------------------*/
(() => {
const canvas = document.getElementById('bg');
const ctx = canvas.getContext('2d', { alpha: true });
let w = canvas.width = innerWidth;
let h = canvas.height = innerHeight;
const DPR = Math.max(1, window.devicePixelRatio || 1);
canvas.width = innerWidth * DPR;
canvas.height = innerHeight * DPR;
canvas.style.width = innerWidth + 'px';
canvas.style.height = innerHeight + 'px';
ctx.scale(DPR, DPR);
let particles = [];
const COUNT_BASE = Math.round((w*h) / 60000); // density control
const PARTICLE_COUNT = Math.max(20, COUNT_BASE * 40); // at least 20
const MAX_DIST = 160;
const mouse = { x: w/2, y: h/2, active:false };
function rand(min,max){ return Math.random()*(max-min)+min; }
function createParticles(){
particles = [];
for(let i=0;i<PARTICLE_COUNT;i++){
particles.push({
x: rand(0,w),
y: rand(0,h),
vx: rand(-0.25,0.25),
vy: rand(-0.25,0.25),
r: rand(1.2,2.6),
life: rand(50,200)
});
}
}
function resize(){
w = canvas.width = innerWidth * DPR;
h = canvas.height = innerHeight * DPR;
canvas.style.width = innerWidth + 'px';
canvas.style.height = innerHeight + 'px';
ctx.setTransform(DPR,0,0,DPR,0,0);
createParticles();
}
window.addEventListener('resize', resize);
resize();
// mouse
window.addEventListener('mousemove', (e) => {
mouse.x = e.clientX;
mouse.y = e.clientY;
mouse.active = true;
// small translate card parallax
const card = document.getElementById('card');
const cx = (e.clientX - window.innerWidth/2) / (window.innerWidth/2);
const cy = (e.clientY - window.innerHeight/2) / (window.innerHeight/2);
card.style.transform = `perspective(900px) translate3d(${cx*8}px,${cy*8}px,0) rotateX(${ -cy*3 }deg) rotateY(${ cx*4 }deg)`;
});
window.addEventListener('mouseleave', ()=>{ mouse.active=false; document.getElementById('card').style.transform=''; });
window.addEventListener('touchmove', (e) => {
if(e.touches && e.touches[0]){
mouse.x = e.touches[0].clientX;
mouse.y = e.touches[0].clientY;
mouse.active = true;
}
}, {passive:true});
// color sampling from CSS variables
const style = getComputedStyle(document.documentElement);
const accent1 = style.getPropertyValue('--accent1').trim() || '#13f7d9';
const accent2 = style.getPropertyValue('--accent2').trim() || '#00ffff';
function draw(){
ctx.clearRect(0,0,innerWidth,innerHeight);
// subtle global glow (faint)
// draw particles
for(let i=0;i<particles.length;i++){
const p = particles[i];
// mouse interaction: slight attraction
if(mouse.active){
const dx = mouse.x - p.x;
const dy = mouse.y - p.y;
const d = Math.sqrt(dx*dx + dy*dy);
const maxEffect = 180;
if(d < maxEffect){
const force = (1 - (d / maxEffect)) * 0.34;
p.vx += (dx / d) * force * 0.12;
p.vy += (dy / d) * force * 0.12;
}
}
// slight random drift
p.vx += rand(-0.02,0.02);
p.vy += rand(-0.02,0.02);
// speed limit
p.vx = Math.max(Math.min(p.vx, 0.7), -0.7);
p.vy = Math.max(Math.min(p.vy, 0.7), -0.7);
p.x += p.vx;
p.y += p.vy;
// wrap edges
if(p.x < -20) p.x = innerWidth + 20;
if(p.x > innerWidth + 20) p.x = -20;
if(p.y < -20) p.y = innerHeight + 20;
if(p.y > innerHeight + 20) p.y = -20;
// draw point (small soft)
ctx.beginPath();
const grad = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, Math.max(8, p.r*6));
grad.addColorStop(0, accent1 + '11'); // faint
grad.addColorStop(1, 'rgba(0,0,0,0)');
ctx.fillStyle = grad;
ctx.arc(p.x, p.y, p.r, 0, Math.PI*2);
ctx.fill();
}
// lines between particles
for(let i=0;i<particles.length;i++){
for(let j=i+1;j<particles.length;j++){
const a = particles[i];
const b = particles[j];
const dx = a.x - b.x;
const dy = a.y - b.y;
const d2 = dx*dx + dy*dy;
if(d2 < MAX_DIST*MAX_DIST){
const d = Math.sqrt(d2);
const alpha = 1 - (d / MAX_DIST);
ctx.beginPath();
ctx.moveTo(a.x, a.y);
ctx.lineTo(b.x, b.y);
ctx.strokeStyle = `rgba(15,255,255,${(alpha*0.08)})`;
ctx.lineWidth = 1;
ctx.stroke();
}
}
}
// optional: connect to mouse as a focal node
if(mouse.active){
for(let i=0;i<particles.length;i++){
const p = particles[i];
const dx = p.x - mouse.x;
const dy = p.y - mouse.y;
const d2 = dx*dx + dy*dy;
if(d2 < 160*160){
const d = Math.sqrt(d2);
const alpha = 1 - (d / 160);
ctx.beginPath();
ctx.moveTo(p.x, p.y);
ctx.lineTo(mouse.x, mouse.y);
ctx.strokeStyle = `rgba(19,247,217,${(alpha*0.06)})`;
ctx.lineWidth = 1;
ctx.stroke();
}
}
}
// subtle vignette to darken edges (optional)
const vg = ctx.createRadialGradient(innerWidth/2, innerHeight/2, Math.min(innerWidth,innerHeight)/4, innerWidth/2, innerHeight/2, Math.max(innerWidth,innerHeight));
vg.addColorStop(0, 'rgba(0,0,0,0)');
vg.addColorStop(1, 'rgba(0,0,0,0.45)');
ctx.fillStyle = vg;
ctx.fillRect(0,0,innerWidth,innerHeight);
requestAnimationFrame(draw);
}
createParticles();
draw();
// small adaptive update (if user changes CSS vars live)
setInterval(() => {
// no-op for now but could re-read colors
}, 2000);
})();
</script>
</body>
</html>
:root{
/* Change these to adjust color grade */
--bg: #000814;
--card-bg: rgba(0,0,0,0.45);
--accent1: #13f7d9; /* teal-ish */
--accent2: #0ff; /* cyan */
--text: rgba(255,255,255,0.92);
--muted: rgba(255,255,255,0.45);
--glass-border: rgba(19,247,217,0.12);
}
html,body{
height:100%;
margin:0;
font-family: "Inter", "Segoe UI", Roboto, Arial, sans-serif;
background: var(--bg);
color: var(--text);
-webkit-font-smoothing:antialiased;
-moz-osx-font-smoothing:grayscale;
overflow:hidden;
}
/* full-screen canvas behind everything */
canvas#bg {
position:fixed;
inset:0;
display:block;
z-index:0;
}
/* center container */
.wrap{
position:relative;
z-index:2;
height:100vh;
display:flex;
align-items:center;
justify-content:center;
pointer-events:none; /* so canvas gets pointer by default; inner card will enable pointer */
}
/* login card */
.card{
pointer-events:auto;
width:360px;
max-width:92%;
padding:34px 28px;
border-radius:22px;
background: linear-gradient(180deg, rgba(255,255,255,0.02), rgba(255,255,255,0.01));
box-shadow:
0 10px 30px rgba(0,0,0,0.6),
0 0 40px rgba(0,0,0,0.5);
border: 1px solid rgba(255,255,255,0.03);
position:relative;
transform-style:preserve-3d;
transition: transform 0.15s ease-out;
/* neon outer glow */
}
.card::before{
content:"";
position:absolute;
inset:-8px;
border-radius:26px;
background: linear-gradient(135deg, rgba(19,247,217,0.06), rgba(15,255,255,0.04));
filter: blur(14px);
z-index:-2;
}
.card::after{
content:"";
position:absolute;
inset:0;
border-radius:22px;
padding:2px;
background: linear-gradient(180deg, rgba(0,0,0,0.2), rgba(0,0,0,0.35));
-webkit-mask: linear-gradient(#000,#000) content-box, linear-gradient(#000,#000);
mask-composite:exclude;
z-index:-1;
}
header h1{
text-align:center;
margin:0 0 6px;
font-size:28px;
letter-spacing:2px;
color:var(--accent1);
text-shadow: 0 2px 8px rgba(0,0,0,0.6);
}
header p{
text-align:center;
margin:0 0 18px;
color:var(--muted);
font-size:14px;
}
form .field{
margin-bottom:16px;
position:relative;
}
label{
display:block;
color:var(--muted);
font-size:13px;
margin-bottom:8px;
}
input[type="text"], input[type="password"]{
width:100%;
padding:12px 14px;
border-radius:6px;
background: rgba(0,0,0,0.35);
border:1px solid rgba(255,255,255,0.04);
color:var(--text);
outline:none;
font-size:15px;
transition: box-shadow 0.12s, border-color 0.12s;
}
input[type="text"]:focus, input[type="password"]:focus{
border-color: rgba(19,247,217,0.7);
box-shadow: 0 0 18px rgba(19,247,217,0.06), inset 0 1px 0 rgba(255,255,255,0.02);
}
.controls{
display:flex;
align-items:center;
justify-content:space-between;
gap:12px;
margin:8px 0 18px;
color:var(--muted);
font-size:13px;
}
.checkbox{
display:flex;
align-items:center;
gap:8px;
}
.btn{
display:block;
width:100%;
padding:12px 14px;
border-radius:28px;
background:transparent;
border: 2px solid rgba(19,247,217,0.35);
color:var(--accent1);
text-transform:uppercase;
letter-spacing:2px;
font-weight:600;
cursor:pointer;
transition: background 0.12s, transform 0.08s;
}
.btn:hover{
background: linear-gradient(90deg, rgba(19,247,217,0.06), rgba(15,255,255,0.04));
transform: translateY(-1px);
}
.mutelink{
display:block;
text-align:center;
margin-top:16px;
color:var(--muted);
font-size:14px;
text-decoration:none;
}
/* small responsive tweak */
@media (max-width:420px){
.card{ padding:26px 18px; width:92%; }
header h1{ font-size:22px; }
}
Aj Designer