Magnetic Button
Un botón que es atraído físicamente por el cursor, creando una sensación de peso e inercia.
const btn = document.querySelector('.magnetic-btn');
const text = btn.querySelector('.magnetic-text');
btn.addEventListener('mousemove', (e) => {
const rect = btn.getBoundingClientRect();
const x = e.clientX - rect.left - rect.width / 2;
const y = e.clientY - rect.top - rect.height / 2;
// Mover el botón
btn.style.transform = `translate(${x * 0.3}px, ${y * 0.3}px)`;
// Efecto parallax en el texto interno
text.style.transform = `translate(${x * 0.2}px, ${y * 0.2}px)`;
});
btn.addEventListener('mouseleave', () => {
btn.style.transform = 'translate(0px, 0px)';
text.style.transform = 'translate(0px, 0px)';
});
Glow Hover Card
Una tarjeta premium que revela un degradado luminoso que rastrea la posición de tu cursor.
CodeXR Style Card
Mueve el ratón sobre esta tarjeta para revelar el efecto de luz perimetral.
.glow-card {
position: relative;
background: #111;
border-radius: 16px;
padding: 1px; /* Espacio para el borde brillante */
overflow: hidden;
}
.glow-card::before {
content: "";
position: absolute;
top: var(--y, 0);
left: var(--x, 0);
width: 400px;
height: 400px;
background: radial-gradient(
circle,
rgba(255, 215, 0, 0.4) 0%,
transparent 60%
);
transform: translate(-50%, -50%);
opacity: 0;
transition: opacity 0.3s ease;
}
.glow-card:hover::before {
opacity: 1;
}
.glow-card-content {
background: #111; /* Oculta el fondo central, dejando ver solo los bordes */
border-radius: 15px;
position: relative;
z-index: 1;
}
Glass OTP Input
Campos de verificación limpios con desenfoque de fondo y transiciones de auto-focus.
const inputs = document.querySelectorAll('.otp-input');
inputs.forEach((input, index) => {
input.addEventListener('keyup', (e) => {
// Si se introduce un valor, pasar al siguiente
if (e.target.value.length === 1 && index < inputs.length - 1) {
inputs[index + 1].focus();
}
// Si se pulsa Borrar, volver al anterior
if (e.key === 'Backspace' && index > 0) {
inputs[index - 1].focus();
}
});
});
Spring Toggle
Un interruptor de estilo iOS con una curva de animación muy fluida y satisfactoria.
.spring-toggle input { display: none; }
.toggle-track {
width: 60px; height: 32px;
background: #333;
border-radius: 99px;
padding: 4px;
cursor: pointer;
transition: background 0.4s ease;
}
.toggle-thumb {
width: 24px; height: 24px;
background: white;
border-radius: 50%;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
/* Cubic bezier para el efecto rebote / spring */
transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.spring-toggle input:checked + .toggle-track {
background: #007aff;
}
.spring-toggle input:checked + .toggle-track .toggle-thumb {
transform: translateX(28px);
}
Parallax 3D Card
Una tarjeta que se inclina dinámicamente en respuesta a las coordenadas del cursor.
Hover me
Move your mouse to tilt
const card = document.getElementById('parallaxCard');
card.addEventListener('mousemove', (e) => {
const rect = card.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const centerX = rect.width / 2;
const centerY = rect.height / 2;
const rotateX = ((y - centerY) / centerY) * -15; // Max 15deg
const rotateY = ((x - centerX) / centerX) * 15;
card.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale3d(1.05, 1.05, 1.05)`;
});
card.addEventListener('mouseleave', () => {
card.style.transform = `perspective(1000px) rotateX(0deg) rotateY(0deg) scale3d(1, 1, 1)`;
});
Hacker Text Scrambler
Efecto Cyberpunk que intercambia caracteres aleatoriamente antes de revelar el texto real.
SYSTEM COMPROMISED
const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const scrambleElement = document.querySelector(".scramble-text");
scrambleElement.onmouseover = event => {
let iteration = 0;
clearInterval(scrambleElement.interval);
scrambleElement.interval = setInterval(() => {
event.target.innerText = event.target.innerText
.split("")
.map((letter, index) => {
if(index < iteration) return event.target.dataset.value[index];
return letters[Math.floor(Math.random() * 26)];
})
.join("");
if(iteration >= event.target.dataset.value.length){
clearInterval(scrambleElement.interval);
}
iteration += 1 / 3; // Controls speed of reveal
}, 30);
}
Infinite Marquee
Un banner de desplazamiento horizontal continuo sin JS pesado.
.marquee-container {
overflow: hidden;
white-space: nowrap;
width: 100%;
background: var(--code-bg);
padding: 1rem 0;
display: flex;
}
.marquee-content {
display: flex;
gap: 2rem;
animation: scroll 15s linear infinite;
font-family: var(--font-mono);
color: var(--accent);
}
@keyframes scroll {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); } /* Requires duplicated content inside */
}
Meteor Shower
Generación de meteoritos animados en el fondo mediante Vanilla JS y animaciones CSS.
const container = document.getElementById('meteorContainer');
// Create 15 meteors
for(let i = 0; i < 15; i++) {
const meteor = document.createElement('span');
meteor.className = 'meteor';
// Randomize position, delay and duration
const left = Math.random() * 100; // 0 to 100%
const delay = Math.random() * 5; // 0 to 5s
const duration = 2 + Math.random() * 2; // 2 to 4s
meteor.style.left = `${left}%`;
meteor.style.top = `-50px`;
meteor.style.animationDelay = `${delay}s`;
meteor.style.animationDuration = `${duration}s`;
container.appendChild(meteor);
}
Animated Blob Button
Un botón con esferas de colores fluidas moviéndose en su interior a través de CSS blur.
.blob-btn {
position: relative;
padding: 1rem 2.5rem;
border-radius: 99px;
border: none;
background: transparent;
overflow: hidden;
cursor: pointer;
color: white;
}
.blob-text {
position: relative;
z-index: 10;
font-weight: 600;
}
.blob-bg {
position: absolute;
inset: 0;
background: #111;
z-index: 1;
}
.blob-bg::before, .blob-bg::after {
content: "";
position: absolute;
width: 100px;
height: 100px;
border-radius: 50%;
filter: blur(25px);
animation: blobMotion 4s infinite alternate ease-in-out;
}
.blob-bg::before { background: #ff0080; left: -20px; top: -20px; }
.blob-bg::after { background: #7928ca; right: -20px; bottom: -20px; animation-delay: -2s; }
@keyframes blobMotion {
0% { transform: translate(0, 0) scale(1); }
100% { transform: translate(20px, 20px) scale(1.2); }
}