Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save SompalSingh/04e94111af171c1ac0bfd26eab409b6c to your computer and use it in GitHub Desktop.
Save SompalSingh/04e94111af171c1ac0bfd26eab409b6c to your computer and use it in GitHub Desktop.
Animated Interactive Image Slider with Dynamic Background

Animated Interactive Image Slider with Dynamic Background

An elegant, feature-rich image slider with multiple transition effects and a vibrant animated background. This slider combines modern design techniques including glass morphism, parallax text effects, and dynamic animations to create an engaging user experience.

A Pen by Bogdan Sandu on CodePen.

License.

<!-- Floating background shapes -->
<div class="floating-shape shape1"></div>
<div class="floating-shape shape2"></div>
<div class="floating-shape shape3"></div>
<div class="floating-shape shape4"></div>
<div class="slider-container">
<div class="slider">
<div class="slide active transition-fade">
<img src="https://picsum.photos/800/450?random=1" alt="Slider Image 1">
<div class="slide-content">
<h2 class="slide-title">Amazing Landscapes</h2>
<p class="slide-description">Discover beautiful natural scenery from around the world</p>
</div>
</div>
<div class="slide">
<img src="https://picsum.photos/800/450?random=2" alt="Slider Image 2">
<div class="slide-content">
<h2 class="slide-title">Urban Architecture</h2>
<p class="slide-description">Explore the fascinating designs of modern cities</p>
</div>
</div>
<div class="slide">
<img src="https://picsum.photos/800/450?random=3" alt="Slider Image 3">
<div class="slide-content">
<h2 class="slide-title">Wildlife Photography</h2>
<p class="slide-description">Get up close with incredible animals in their natural habitats</p>
</div>
</div>
<div class="slide">
<img src="https://picsum.photos/800/450?random=4" alt="Slider Image 4">
<div class="slide-content">
<h2 class="slide-title">Abstract Art</h2>
<p class="slide-description">Experience the beauty of colors, shapes, and creative expressions</p>
</div>
</div>
</div>
<div class="navigation">
<button class="nav-btn prev">&lt;</button>
<button class="nav-btn next">&gt;</button>
</div>
<div class="dots-container">
<!-- Dots will be added dynamically with JavaScript -->
</div>
</div>
document.addEventListener('DOMContentLoaded', () => {
// Select elements
const slider = document.querySelector('.slider');
const slides = document.querySelectorAll('.slide');
const prevBtn = document.querySelector('.prev');
const nextBtn = document.querySelector('.next');
const dotsContainer = document.querySelector('.dots-container');
// Variables
let currentIndex = 0;
let autoSlideInterval;
const autoSlideDelay = 5000; // 5 seconds
// Available transition effects
const transitionEffects = ['fade', 'slideRight', 'slideLeft', 'zoom', 'slideUp'];
// Initialize - make first slide active
slides[0].classList.add('active');
slides[0].classList.add(`transition-${transitionEffects[0]}`);
// Create dot indicators
slides.forEach((_, index) => {
const dot = document.createElement('div');
dot.classList.add('dot');
if (index === 0) dot.classList.add('active');
dot.addEventListener('click', () => showSlide(index));
dotsContainer.appendChild(dot);
});
// Get all dots
const dots = document.querySelectorAll('.dot');
// Main function to show a slide
function showSlide(index) {
// Handle index boundaries
if (index < 0) index = slides.length - 1;
if (index >= slides.length) index = 0;
// Skip if already on this slide
if (index === currentIndex) return;
// Remove active class from all slides and dots
slides.forEach(slide => {
slide.classList.remove('active');
slide.classList.remove('transition-fade', 'transition-slideRight',
'transition-slideLeft', 'transition-zoom', 'transition-slideUp');
});
dots.forEach(dot => dot.classList.remove('active'));
// Apply random transition effect
const randomEffect = transitionEffects[Math.floor(Math.random() * transitionEffects.length)];
slides[index].classList.add(`transition-${randomEffect}`);
// Activate the new slide and dot
slides[index].classList.add('active');
dots[index].classList.add('active');
// Update the current index
currentIndex = index;
// Reset auto slide timer
resetAutoSlide();
}
// Next slide function
function nextSlide() {
showSlide(currentIndex + 1);
}
// Previous slide function
function prevSlide() {
showSlide(currentIndex - 1);
}
// Start auto slide
function startAutoSlide() {
autoSlideInterval = setInterval(nextSlide, autoSlideDelay);
}
// Reset auto slide timer
function resetAutoSlide() {
clearInterval(autoSlideInterval);
startAutoSlide();
}
// Event listeners
prevBtn.addEventListener('click', prevSlide);
nextBtn.addEventListener('click', nextSlide);
// Touch events for mobile swipe
let touchStartX = 0;
let touchEndX = 0;
slider.addEventListener('touchstart', (e) => {
touchStartX = e.changedTouches[0].screenX;
// Pause auto slide while touching
clearInterval(autoSlideInterval);
});
slider.addEventListener('touchend', (e) => {
touchEndX = e.changedTouches[0].screenX;
handleSwipe();
// Restart auto slide after touch
startAutoSlide();
});
function handleSwipe() {
const swipeThreshold = 50;
if (touchEndX < touchStartX - swipeThreshold) {
nextSlide(); // Swipe left -> next slide
} else if (touchEndX > touchStartX + swipeThreshold) {
prevSlide(); // Swipe right -> prev slide
}
}
// Pause auto slide on hover
slider.addEventListener('mouseenter', () => {
clearInterval(autoSlideInterval);
});
slider.addEventListener('mouseleave', () => {
startAutoSlide();
});
// Keyboard navigation
document.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft') {
prevSlide();
} else if (e.key === 'ArrowRight') {
nextSlide();
}
});
// Initialize auto slide
startAutoSlide();
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
background-size: 400% 400%;
animation: gradientBG 15s ease infinite;
position: relative;
overflow: hidden;
}
/* Animated background gradient */
@keyframes gradientBG {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
/* Floating background elements */
.floating-shape {
position: fixed;
background: rgba(255, 255, 255, 0.15);
border-radius: 50%;
pointer-events: none;
z-index: 0;
}
.shape1 {
top: 10%;
left: 10%;
width: 180px;
height: 180px;
animation: floatAnimation 20s infinite alternate ease-in-out;
}
.shape2 {
top: 70%;
left: 20%;
width: 120px;
height: 120px;
animation: floatAnimation 15s infinite alternate-reverse ease-in-out;
}
.shape3 {
top: 30%;
right: 15%;
width: 150px;
height: 150px;
animation: floatAnimation 25s infinite alternate ease-in-out;
animation-delay: 5s;
}
.shape4 {
bottom: 15%;
right: 10%;
width: 200px;
height: 200px;
animation: floatAnimation 18s infinite alternate-reverse ease-in-out;
animation-delay: 2s;
}
@keyframes floatAnimation {
0% { transform: translate(0, 0) rotate(0deg); }
25% { transform: translate(20px, 35px) rotate(5deg); }
50% { transform: translate(-15px, 25px) rotate(-5deg); }
75% { transform: translate(35px, -30px) rotate(3deg); }
100% { transform: translate(-25px, -25px) rotate(-3deg); }
}
.slider-container {
width: 800px;
max-width: 90vw;
position: relative;
overflow: hidden;
border-radius: 10px;
box-shadow: 0 15px 50px rgba(0, 0, 0, 0.3);
z-index: 5;
background: rgba(0, 0, 0, 0.2);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
padding: 15px;
border: 1px solid rgba(255, 255, 255, 0.2);
animation: appear 1s ease-out;
}
@keyframes appear {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
.slider {
position: relative;
height: 450px;
overflow: hidden;
}
.slide {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
z-index: 1;
transition: opacity 0.5s ease;
overflow: hidden;
pointer-events: none;
}
.slide.active {
opacity: 1;
z-index: 2;
pointer-events: auto;
}
.slide img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 8s ease-in-out;
}
.slide.active img {
transform: scale(1.1);
}
.slide-content {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 20px;
background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
color: white;
transform: translateY(100%);
transition: transform 0.7s ease, opacity 0.5s ease;
opacity: 0;
}
.slide.active .slide-content {
transform: translateY(0);
opacity: 1;
transition-delay: 0.3s;
}
.slide:hover .slide-content {
transform: translateY(0);
opacity: 1;
}
/* Slide title and description parallax effects */
.slide-title {
transform: translateX(-50px);
opacity: 0;
transition: transform 1s ease, opacity 1s ease;
transition-delay: 0.2s;
font-size: 1.5rem;
margin-bottom: 8px;
}
.slide-description {
transform: translateX(50px);
opacity: 0;
transition: transform 1s ease, opacity 1s ease;
transition-delay: 0.4s;
font-size: 1rem;
opacity: 0.9;
}
.slide.active .slide-title,
.slide.active .slide-description {
transform: translateX(0);
opacity: 1;
}
/* Navigation arrows */
.navigation {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 20;
pointer-events: none;
}
.nav-btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
background-color: rgba(255, 255, 255, 0.7);
color: #333;
border: none;
border-radius: 50%;
width: 50px;
height: 50px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
font-size: 1.5rem;
transition: all 0.3s ease;
pointer-events: auto;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
z-index: 30;
}
.nav-btn.prev {
left: 20px;
}
.nav-btn.next {
right: 20px;
}
.nav-btn:hover {
background-color: rgba(255, 255, 255, 0.9);
transform: translateY(-50%) scale(1.1);
}
/* Dots indicators */
.dots-container {
display: flex;
justify-content: center;
position: absolute;
bottom: 20px;
width: 100%;
z-index: 10;
}
.dot {
width: 12px;
height: 12px;
border-radius: 50%;
margin: 0 5px;
background-color: rgba(255, 255, 255, 0.5);
cursor: pointer;
transition: all 0.3s ease;
}
.dot.active {
background-color: white;
transform: scale(1.2);
}
/* Animation keyframes for transitions */
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideInRight {
from { transform: translateX(50px); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes slideInLeft {
from { transform: translateX(-50px); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
@keyframes zoomIn {
from { transform: scale(1.2); opacity: 0; }
to { transform: scale(1); opacity: 1; }
}
@keyframes slideInUp {
from { transform: translateY(50px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
/* Transition effect classes */
.transition-fade .slide-content {
animation: fadeIn 1s forwards;
}
.transition-slideRight .slide-content {
animation: slideInRight 1s forwards;
}
.transition-slideLeft .slide-content {
animation: slideInLeft 1s forwards;
}
.transition-zoom .slide-content {
animation: zoomIn 1s forwards;
}
.transition-slideUp .slide-content {
animation: slideInUp 1s forwards;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment