<div class="hover-card-container">
<div class="hover-card">
<div class="card-content">
<div class="card-image">
<img src="https://images.unsplash.com/photo-1523275335684-37898b6baf30?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Imagen del Producto">
</div>
<div class="card-info">
<h3 class="card-title">Auriculares Premium</h3>
<p class="card-description">Experimenta un sonido cristalino con nuestros auriculares premium con cancelación de ruido.</p>
<div class="card-meta">
<span class="card-price">$299</span>
<button class="card-button">Ver Detalles</button>
</div>
</div>
<div class="card-shine"></div>
</div>
</div>
<div class="hover-card">
<div class="card-content">
<div class="card-image">
<img src="https://images.unsplash.com/photo-1546868871-7041f2a55e12?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=80" alt="Imagen del Producto">
</div>
<div class="card-info">
<h3 class="card-title">Reloj Inteligente</h3>
<p class="card-description">Haz seguimiento de tus objetivos de fitness y mantente conectado con nuestro último smartwatch.</p>
<div class="card-meta">
<span class="card-price">$199</span>
<button class="card-button">Ver Detalles</button>
</div>
</div>
<div class="card-shine"></div>
</div>
</div>
</div>
.hover-card-container {
display: flex;
flex-wrap: wrap;
gap: 30px;
justify-content: center;
perspective: 1000px;
padding: 20px 0;
}
.hover-card {
width: 300px;
height: 400px;
position: relative;
transform-style: preserve-3d;
transform: perspective(1000px);
}
.card-content {
width: 100%;
height: 100%;
position: relative;
transform-style: preserve-3d;
transition: transform 0.6s cubic-bezier(0.23, 1, 0.32, 1);
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
overflow: hidden;
background: white;
}
.hover-card:hover .card-content {
transform: rotateY(5deg) rotateX(5deg);
box-shadow: 0 15px 40px rgba(0, 0, 0, 0.2);
}
.card-image {
width: 100%;
height: 60%;
overflow: hidden;
border-top-left-radius: 15px;
border-top-right-radius: 15px;
}
.card-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.6s ease;
}
.hover-card:hover .card-image img {
transform: scale(1.05);
}
.card-info {
padding: 20px;
height: 40%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.card-title {
margin: 0 0 5px 0;
font-size: 1.4rem;
font-weight: 600;
color: #2d3748;
}
.card-description {
margin: 0;
font-size: 0.9rem;
color: #718096;
line-height: 1.4;
}
.card-meta {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 15px;
}
.card-price {
font-size: 1.2rem;
font-weight: 700;
color: #4a5568;
}
.card-button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 8px 16px;
border-radius: 50px;
font-size: 0.85rem;
font-weight: 500;
cursor: pointer;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card-button:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
}
.card-shine {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 15px;
background: linear-gradient(
135deg,
rgba(255, 255, 255, 0.25) 0%,
rgba(255, 255, 255, 0) 60%
);
pointer-events: none;
opacity: 0;
transition: opacity 0.6s ease;
}
.hover-card:hover .card-shine {
opacity: 1;
}
/* Responsive adjustments */
@media (max-width: 768px) {
.hover-card {
width: 280px;
height: 380px;
}
.card-title {
font-size: 1.2rem;
}
.card-description {
font-size: 0.85rem;
}
}
@media (max-width: 480px) {
.hover-card-container {
gap: 20px;
}
.hover-card {
width: 260px;
height: 360px;
}
}
document.addEventListener('DOMContentLoaded', function() {
const cards = document.querySelectorAll('.hover-card');
cards.forEach(card => {
// Efecto de Rotación 3D
card.addEventListener('mousemove', handleMouseMove);
card.addEventListener('mouseleave', handleMouseLeave);
// Soporte táctil para móviles
card.addEventListener('touchmove', handleTouchMove);
card.addEventListener('touchend', handleMouseLeave);
});
function handleMouseMove(e) {
const cardContent = this.querySelector('.card-content');
const cardRect = this.getBoundingClientRect();
// Calcular posición del ratón relativa al centro de la tarjeta
const cardCenterX = cardRect.left + cardRect.width / 2;
const cardCenterY = cardRect.top + cardRect.height / 2;
const mouseX = e.clientX - cardCenterX;
const mouseY = e.clientY - cardCenterY;
// Calcular rotación (máximo 10 grados)
const rotateY = mouseX * 10 / (cardRect.width / 2);
const rotateX = -mouseY * 10 / (cardRect.height / 2);
// Aplicar transformación de rotación
cardContent.style.transform = `rotateY(${rotateY}deg) rotateX(${rotateX}deg)`;
// Actualizar posición del efecto de brillo
updateShineEffect(this, e.clientX - cardRect.left, e.clientY - cardRect.top, cardRect.width, cardRect.height);
}
function handleTouchMove(e) {
if (e.touches.length > 0) {
const touch = e.touches[0];
const cardContent = this.querySelector('.card-content');
const cardRect = this.getBoundingClientRect();
// Calcular posición del toque relativa al centro de la tarjeta
const cardCenterX = cardRect.left + cardRect.width / 2;
const cardCenterY = cardRect.top + cardRect.height / 2;
const touchX = touch.clientX - cardCenterX;
const touchY = touch.clientY - cardCenterY;
// Calcular rotación (máximo 10 grados)
const rotateY = touchX * 10 / (cardRect.width / 2);
const rotateX = -touchY * 10 / (cardRect.height / 2);
// Aplicar transformación de rotación
cardContent.style.transform = `rotateY(${rotateY}deg) rotateX(${rotateX}deg)`;
// Actualizar posición del efecto de brillo
updateShineEffect(this, touch.clientX - cardRect.left, touch.clientY - cardRect.top, cardRect.width, cardRect.height);
}
}
function handleMouseLeave() {
const cardContent = this.querySelector('.card-content');
// Restablecer rotación
cardContent.style.transform = 'rotateY(0deg) rotateX(0deg)';
// Restablecer efecto de brillo
const shine = this.querySelector('.card-shine');
shine.style.background = 'linear-gradient(135deg, rgba(255, 255, 255, 0.25) 0%, rgba(255, 255, 255, 0) 60%)';
}
function updateShineEffect(card, mouseX, mouseY, width, height) {
const shine = card.querySelector('.card-shine');
// Calcular ángulo basado en la posición del ratón
const angleX = (mouseX / width) * 360;
const angleY = (mouseY / height) * 360;
// Actualizar ángulo del gradiente
shine.style.background = `linear-gradient(${angleX}deg, rgba(255, 255, 255, 0.25) 0%, rgba(255, 255, 255, 0) 80%)`;
}
});