<!-- <!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
margin: 0;
padding: 0;
min-height: 100vh;
background: linear-gradient(to bottom, #0a0a2a, #1a1a4a);
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
font-family: 'Arial', sans-serif;
}
.stars {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.star {
position: absolute;
background: white;
border-radius: 50%;
animation: twinkle 1.5s infinite ease-in-out;
}
@keyframes twinkle {
0%, 100% { opacity: 0.3; }
50% { opacity: 1; }
}
.gallery-container {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
perspective: 1000px;
}
.gallery {
position: relative;
width: 300px;
height: 400px;
transform-style: preserve-3d;
transition: transform 0.5s ease-out;
}
.card {
position: absolute;
width: 300px;
height: 400px;
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
backdrop-filter: blur(5px);
border: 2px solid rgba(255, 192, 203, 0.3);
transition: all 0.5s ease-out;
cursor: pointer;
overflow: hidden;
transform-origin: center center;
}
@media (max-width: 768px) {
.gallery, .card {
width: 240px;
height: 320px;
}
}
@media (max-width: 480px) {
.gallery, .card {
width: 200px;
height: 280px;
}
}
.card img {
width: 100%;
height: 100%;
object-fit: cover;
}
.card.active {
transform: scale(1.1) translateZ(100px);
box-shadow: 0 0 30px rgba(255, 192, 203, 0.5);
z-index: 10;
border: 2px solid rgba(255, 192, 203, 0.8);
}
.number {
position: absolute;
bottom: 10px;
right: 10px;
background: rgba(255, 192, 203, 0.7);
color: white;
padding: 5px 10px;
border-radius: 15px;
font-size: 14px;
}
</style>
</head>
<body>
<div class="stars"></div>
<div class="gallery-container">
<div class="gallery"></div>
</div>
<script>
// Create stars
function createStars() {
const starsContainer = document.querySelector('.stars');
for (let i = 0; i < 200; i++) {
const star = document.createElement('div');
star.className = 'star';
star.style.width = Math.random() * 3 + 'px';
star.style.height = star.style.width;
star.style.left = Math.random() * 100 + '%';
star.style.top = Math.random() * 100 + '%';
star.style.animationDelay = Math.random() * 2 + 's';
starsContainer.appendChild(star);
}
}
// Create gallery
function createGallery() {
const gallery = document.querySelector('.gallery');
const totalCards = 10;
const radius = window.innerWidth < 768 ? 400 : 600; // Reduced radius for better centering
let currentAngle = 0;
let isDragging = false;
let startX = 0;
let currentX = 0;
// Create cards
for (let i = 0; i < totalCards; i++) {
const card = document.createElement('div');
card.className = 'card';
card.innerHTML = `
<img src="/api/placeholder/300/400" alt="Romantic photo ${i + 1}">
<div class="number">${i + 1}</div>
`;
gallery.appendChild(card);
}
function updateCards() {
const cards = document.querySelectorAll('.card');
cards.forEach((card, index) => {
const angle = (currentAngle + (index * (360 / totalCards))) * (Math.PI / 180);
const x = Math.sin(angle) * radius;
const z = Math.cos(angle) * radius;
card.style.transform = `translate3d(${x}px, 0, ${z}px)`;
// Determine which card is in front
const normalizedAngle = ((currentAngle + (index * (360 / totalCards))) % 360 + 360) % 360;
if (normalizedAngle > 350 || normalizedAngle < 10) {
card.classList.add('active');
} else {
card.classList.remove('active');
}
// Adjust opacity based on position
const opacity = Math.max(0.2, 1 - Math.abs(normalizedAngle - 180) / 180);
card.style.opacity = opacity;
});
}
// Event listeners for mouse/touch interaction
gallery.addEventListener('mousedown', (e) => {
isDragging = true;
startX = e.clientX;
currentX = currentAngle;
gallery.style.cursor = 'grabbing';
});
window.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const diff = (e.clientX - startX) * 0.5;
currentAngle = currentX + diff;
updateCards();
});
window.addEventListener('mouseup', () => {
isDragging = false;
gallery.style.cursor = 'grab';
});
// Touch events
gallery.addEventListener('touchstart', (e) => {
isDragging = true;
startX = e.touches[0].clientX;
currentX = currentAngle;
e.preventDefault();
});
window.addEventListener('touchmove', (e) => {
if (!isDragging) return;
const diff = (e.touches[0].clientX - startX) * 0.5;
currentAngle = currentX + diff;
updateCards();
e.preventDefault();
}, { passive: false });
window.addEventListener('touchend', () => {
isDragging = false;
});
// Mouse wheel support
window.addEventListener('wheel', (e) => {
currentAngle += e.deltaX * 0.1 || e.deltaY * 0.1;
updateCards();
});
// Initial update
updateCards();
// Handle window resize
window.addEventListener('resize', () => {
const newRadius = window.innerWidth < 768 ? 400 : 600;
radius = newRadius;
updateCards();
});
}
// Initialize
createStars();
createGallery();
</script>
</body>
</html> -->
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
margin: 0;
padding: 0;
min-height: 100vh;
background: linear-gradient(to bottom, #0a0a2a, #1a1a4a);
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
font-family: 'Arial', sans-serif;
}
.nav-button {
position: fixed;
top: 50%;
transform: translateY(-50%);
width: 50px;
height: 50px;
background: rgba(255, 192, 203, 0.2);
border: 2px solid rgba(255, 192, 203, 0.5);
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 24px;
transition: all 0.3s ease;
z-index: 1000;
box-shadow: 0 0 15px rgba(255, 192, 203, 0.3);
}
.nav-button:hover {
background: rgba(255, 192, 203, 0.4);
box-shadow:
0 0 20px rgba(255, 192, 203, 0.5),
0 0 40px rgba(255, 192, 203, 0.3);
}
.nav-button.prev {
left: 30px;
}
.nav-button.next {
right: 30px;
}
.nav-button::before {
content: '';
position: absolute;
width: 15px;
height: 15px;
border-top: 3px solid white;
border-right: 3px solid white;
transition: all 0.3s ease;
}
.nav-button.prev::before {
transform: rotate(-135deg);
margin-left: 5px;
}
.nav-button.next::before {
transform: rotate(45deg);
margin-right: 5px;
}
.nav-button:active {
transform: translateY(-50%) scale(0.95);
}
.nav-button.active {
background: rgba(255, 192, 203, 0.6);
box-shadow:
0 0 30px rgba(255, 192, 203, 0.7),
0 0 50px rgba(255, 192, 203, 0.4);
}
@media (max-width: 768px) {
.nav-button {
width: 40px;
height: 40px;
}
.nav-button::before {
width: 12px;
height: 12px;
}
}
.spotlight {
position: fixed;
top: 0;
left: 50%;
width: 400px;
height: 400px;
transform: translateX(-50%);
background: radial-gradient(circle at center, rgba(255,255,255,0.1) 0%, transparent 70%);
pointer-events: none;
z-index: 2;
animation: spotlightPulse 4s infinite;
}
@keyframes spotlightPulse {
0%, 100% { opacity: 0.5; }
50% { opacity: 0.8; }
}
.stars {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.star {
position: absolute;
background: white;
border-radius: 50%;
animation: twinkle 1.5s infinite ease-in-out;
}
@keyframes twinkle {
0%, 100% { opacity: 0.3; transform: scale(1); }
50% { opacity: 1; transform: scale(1.2); }
}
.gallery-container {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
perspective: 2000px;
}
.gallery {
position: relative;
width: 300px;
height: 400px;
transform-style: preserve-3d;
transition: transform 0.5s ease-out;
}
.card {
position: absolute;
width: 300px;
height: 400px;
background: rgba(255, 255, 255, 0.1);
border-radius: 15px;
backdrop-filter: blur(5px);
border: 2px solid rgba(255, 192, 203, 0.3);
transition: all 0.6s cubic-bezier(0.4, 0.0, 0.2, 1);
cursor: pointer;
overflow: hidden;
transform-origin: center center;
box-shadow: 0 10px 30px rgba(0,0,0,0.5);
}
.card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(255,255,255,0.3) 0%, transparent 50%);
z-index: 2;
transition: opacity 0.3s;
}
.card::after {
content: '';
position: absolute;
top: -100%;
left: -100%;
right: -100%;
bottom: -100%;
background: radial-gradient(circle at center, rgba(255,255,255,0.8) 0%, transparent 50%);
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
}
.card.active {
transform: scale(1.2) translateZ(200px);
box-shadow: 0 20px 60px rgba(255, 192, 203, 0.4);
border: 2px solid rgba(255, 255, 255, 0.8);
}
.card.active::after {
opacity: 0.1;
}
@media (max-width: 768px) {
.gallery, .card {
width: 240px;
height: 320px;
}
}
.card img {
width: 100%;
height: 100%;
object-fit: cover;
transform: scale(1.1);
transition: transform 0.5s;
}
.card:hover img {
transform: scale(1.2);
}
.number {
position: absolute;
bottom: 10px;
right: 10px;
background: rgba(255, 192, 203, 0.7);
color: white;
padding: 5px 15px;
border-radius: 15px;
font-size: 14px;
z-index: 3;
box-shadow: 0 2px 10px rgba(0,0,0,0.3);
backdrop-filter: blur(5px);
}
.ambient-light {
position: fixed;
pointer-events: none;
width: 100%;
height: 100%;
background: radial-gradient(
circle at 50% 0%,
rgba(255,255,255,0.1) 0%,
transparent 50%
);
z-index: 1;
}
</style>
</head>
<body>
<div class="ambient-light"></div>
<div class="spotlight"></div>
<div class="stars"></div>
<button class="nav-button prev" aria-label="Previous"></button>
<button class="nav-button next" aria-label="Next"></button>
<div class="gallery-container">
<div class="gallery"></div>
</div>
<script>
function createStars() {
const starsContainer = document.querySelector('.stars');
for (let i = 0; i < 200; i++) {
const star = document.createElement('div');
star.className = 'star';
star.style.width = Math.random() * 3 + 'px';
star.style.height = star.style.width;
star.style.left = Math.random() * 100 + '%';
star.style.top = Math.random() * 100 + '%';
star.style.animationDelay = Math.random() * 2 + 's';
starsContainer.appendChild(star);
}
}
function createGallery() {
const gallery = document.querySelector('.gallery');
const totalCards = 10;
const radius = window.innerWidth < 768 ? 400 : 600;
let currentAngle = 0;
let isDragging = false;
let startX = 0;
let currentX = 0;
let autoRotateInterval;
const prevButton = document.querySelector('.nav-button.prev');
const nextButton = document.querySelector('.nav-button.next');
// Array of image URLs
const imageUrls = [
'pic1.jpg',
'pic2.jpg',
'pic3.jpg',
'pic4.jpg',
'pic5.jpg',
'pic6.jpg',
'pic7.jpg',
'pic8.jpg',
'pic9.jpg',
'pic10.jpg',
'pic11.jpg'
];
// Create cards...
for (let i = 0; i < totalCards; i++) {
const card = document.createElement('div');
card.className = 'card';
card.innerHTML = `
<img src="${imageUrls[i]}" alt="Romantic photo ${i + 1}">
<div class="number">${i + 1}</div>
`;
gallery.appendChild(card);
}
function rotateGallery(direction) {
clearInterval(autoRotateInterval);
currentAngle += direction * 36; // 360 / 10 cards = 36 degrees per card
updateCards();
}
// Navigation button click handlers
prevButton.addEventListener('click', () => rotateGallery(1));
nextButton.addEventListener('click', () => rotateGallery(-1));
function updateCards(extraRotation = 0) {
const cards = document.querySelectorAll('.card');
cards.forEach((card, index) => {
const angle = (currentAngle + extraRotation + (index * (360 / totalCards))) * (Math.PI / 180);
const x = Math.sin(angle) * radius;
const z = Math.cos(angle) * radius;
const rotateY = angle * (180 / Math.PI);
card.style.transform = `translate3d(${x}px, 0, ${z}px) rotateY(${rotateY}deg)`;
const normalizedAngle = ((currentAngle + extraRotation + (index * (360 / totalCards))) % 360 + 360) % 360;
if (normalizedAngle > 350 || normalizedAngle < 10) {
card.classList.add('active');
} else {
card.classList.remove('active');
}
const opacity = Math.max(0.2, 1 - Math.abs(normalizedAngle - 180) / 180);
card.style.opacity = opacity;
});
}
// Mouse and touch event handlers
gallery.addEventListener('mousedown', (e) => {
isDragging = true;
startX = e.clientX;
currentX = currentAngle;
gallery.style.cursor = 'grabbing';
clearInterval(autoRotateInterval);
});
window.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const diff = (e.clientX - startX) * 0.5;
currentAngle = currentX + diff;
updateCards();
// Light up the appropriate button based on drag direction
const dragDirection = e.movementX;
prevButton.classList.toggle('active', dragDirection < 0);
nextButton.classList.toggle('active', dragDirection > 0);
});
window.addEventListener('mouseup', () => {
isDragging = false;
gallery.style.cursor = 'grab';
prevButton.classList.remove('active');
nextButton.classList.remove('active');
});
// Touch events
gallery.addEventListener('touchstart', (e) => {
isDragging = true;
startX = e.touches[0].clientX;
currentX = currentAngle;
clearInterval(autoRotateInterval);
e.preventDefault();
});
window.addEventListener('touchmove', (e) => {
if (!isDragging) return;
const diff = (e.touches[0].clientX - startX) * 0.5;
currentAngle = currentX + diff;
updateCards();
// Light up the appropriate button based on touch direction
const touchDirection = e.touches[0].clientX - startX;
prevButton.classList.toggle('active', touchDirection < 0);
nextButton.classList.toggle('active', touchDirection > 0);
e.preventDefault();
}, { passive: false });
window.addEventListener('touchend', () => {
isDragging = false;
prevButton.classList.remove('active');
nextButton.classList.remove('active');
});
// Mouse wheel handler
window.addEventListener('wheel', (e) => {
clearInterval(autoRotateInterval);
const delta = e.deltaX * 0.1 || e.deltaY * 0.1;
currentAngle += delta;
updateCards();
// Light up the appropriate button based on wheel direction
prevButton.classList.toggle('active', delta > 0);
nextButton.classList.toggle('active', delta < 0);
});
// Initial update
updateCards();
}
// Initialize
createStars();
createGallery();
</script>
</body>
</html>