Skip to content

Commit 87369de

Browse files
committed
completing project 1
1 parent a273575 commit 87369de

File tree

6 files changed

+414
-0
lines changed

6 files changed

+414
-0
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"liveServer.settings.port": 5501
3+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Responsive Card Slider</title>
7+
<link rel="stylesheet" href="style.css">
8+
</head>
9+
<body>
10+
<div class="container">
11+
<h1>Responsive Card Slider</h1>
12+
13+
<div class="slider-container">
14+
<div class="slider-controls">
15+
<button id="prev-btn" class="control-btn">
16+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
17+
<polyline points="15 18 9 12 15 6"></polyline>
18+
</svg>
19+
</button>
20+
<button id="next-btn" class="control-btn">
21+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
22+
<polyline points="9 18 15 12 9 6"></polyline>
23+
</svg>
24+
</button>
25+
</div>
26+
27+
<div class="slider-wrapper">
28+
<div class="slider">
29+
<div class="card">
30+
<div class="card-image" style="background-color: #3498db;"></div>
31+
<div class="card-content">
32+
<h3>Mountain Adventure</h3>
33+
<p>Explore the breathtaking landscapes of the Rocky Mountains.</p>
34+
</div>
35+
</div>
36+
37+
<div class="card">
38+
<div class="card-image" style="background-color: #e74c3c;"></div>
39+
<div class="card-content">
40+
<h3>Beach Retreat</h3>
41+
<p>Relax and unwind on the pristine shores of tropical paradise.</p>
42+
</div>
43+
</div>
44+
45+
<div class="card">
46+
<div class="card-image" style="background-color: #2ecc71;"></div>
47+
<div class="card-content">
48+
<h3>City Exploration</h3>
49+
<p>Discover hidden gems and iconic landmarks in vibrant urban centers.</p>
50+
</div>
51+
</div>
52+
53+
<div class="card">
54+
<div class="card-image" style="background-color: #f39c12;"></div>
55+
<div class="card-content">
56+
<h3>Forest Escape</h3>
57+
<p>Immerse yourself in the tranquility of lush green forests.</p>
58+
</div>
59+
</div>
60+
61+
<div class="card">
62+
<div class="card-image" style="background-color: #9b59b6;"></div>
63+
<div class="card-content">
64+
<h3>Desert Journey</h3>
65+
<p>Experience the mystical beauty of vast desert landscapes.</p>
66+
</div>
67+
</div>
68+
69+
<div class="card">
70+
<div class="card-image" style="background-color: #1abc9c;"></div>
71+
<div class="card-content">
72+
<h3>Island Hopping</h3>
73+
<p>Sail through crystal clear waters and visit stunning islands.</p>
74+
</div>
75+
</div>
76+
</div>
77+
</div>
78+
79+
<div class="pagination">
80+
<!-- Pagination dots will be added dynamically with JavaScript -->
81+
</div>
82+
</div>
83+
</div>
84+
85+
<script src="script.js"></script>
86+
</body>
87+
</html>
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
document.addEventListener("DOMContentLoaded", function () {
2+
// Elements
3+
const slider = document.querySelector(".slider");
4+
const prevBtn = document.getElementById("prev-btn");
5+
const nextBtn = document.getElementById("next-btn");
6+
const pagination = document.querySelector(".pagination");
7+
const cards = document.querySelectorAll(".card");
8+
9+
// State
10+
let currentIndex = 0;
11+
let cardsPerView = getCardsPerView();
12+
let totalSlides = Math.ceil(cards.length / cardsPerView);
13+
14+
// Initialize
15+
createPaginationDots();
16+
updateSlider();
17+
18+
// Event listeners
19+
prevBtn.addEventListener("click", goToPrevSlide);
20+
nextBtn.addEventListener("click", goToNextSlide);
21+
window.addEventListener("resize", handleResize);
22+
23+
// Functions
24+
function getCardsPerView() {
25+
const windowWidth = window.innerWidth;
26+
if (windowWidth >= 1024) return 4;
27+
if (windowWidth >= 768) return 3;
28+
if (windowWidth >= 640) return 2;
29+
return 1;
30+
}
31+
32+
function createPaginationDots() {
33+
pagination.innerHTML = "";
34+
for (let i = 0; i < totalSlides; i++) {
35+
const dot = document.createElement("div");
36+
dot.classList.add("dot");
37+
if (i === currentIndex) dot.classList.add("active");
38+
dot.addEventListener("click", () => goToSlide(i));
39+
pagination.appendChild(dot);
40+
}
41+
}
42+
43+
function goToSlide(index) {
44+
currentIndex = index;
45+
updateSlider();
46+
}
47+
48+
function goToPrevSlide() {
49+
currentIndex = Math.max(currentIndex - 1, 0);
50+
updateSlider();
51+
}
52+
53+
function goToNextSlide() {
54+
currentIndex = Math.min(currentIndex + 1, totalSlides - 1);
55+
updateSlider();
56+
}
57+
58+
function updateSlider() {
59+
// Calculate the slide position
60+
const slideWidth = cards[0].offsetWidth;
61+
const gapWidth = 16; // 1rem = 16px
62+
const offset = currentIndex * cardsPerView * (slideWidth + gapWidth);
63+
64+
// Update slider position
65+
slider.style.transform = `translateX(-${offset}px)`;
66+
67+
// Update pagination
68+
document.querySelectorAll(".dot").forEach((dot, i) => {
69+
dot.classList.toggle("active", i === currentIndex);
70+
});
71+
72+
// Update button state
73+
prevBtn.disabled = currentIndex === 0;
74+
nextBtn.disabled = currentIndex === totalSlides - 1;
75+
76+
// Visual feedback on buttons
77+
prevBtn.style.opacity = currentIndex === 0 ? "0.5" : "1";
78+
nextBtn.style.opacity = currentIndex === totalSlides - 1 ? "0.5" : "1";
79+
}
80+
81+
function handleResize() {
82+
const newCardsPerView = getCardsPerView();
83+
if (newCardsPerView !== cardsPerView) {
84+
cardsPerView = newCardsPerView;
85+
totalSlides = Math.ceil(cards.length / cardsPerView);
86+
currentIndex = Math.min(currentIndex, totalSlides - 1);
87+
createPaginationDots();
88+
updateSlider();
89+
} else {
90+
updateSlider();
91+
}
92+
}
93+
94+
// Add touch swipe support
95+
let touchStartX = 0;
96+
let touchEndX = 0;
97+
98+
slider.addEventListener(
99+
"touchstart",
100+
(e) => {
101+
touchStartX = e.changedTouches[0].screenX;
102+
},
103+
false
104+
);
105+
106+
slider.addEventListener(
107+
"touchend",
108+
(e) => {
109+
touchEndX = e.changedTouches[0].screenX;
110+
handleSwipe();
111+
},
112+
false
113+
);
114+
115+
function handleSwipe() {
116+
const minSwipeDistance = 50;
117+
if (touchStartX - touchEndX > minSwipeDistance) {
118+
goToNextSlide();
119+
} else if (touchEndX - touchStartX > minSwipeDistance) {
120+
goToPrevSlide();
121+
}
122+
}
123+
124+
// Add keyboard support
125+
document.addEventListener("keydown", (e) => {
126+
if (e.key === "ArrowLeft") {
127+
goToPrevSlide();
128+
} else if (e.key === "ArrowRight") {
129+
goToNextSlide();
130+
}
131+
});
132+
133+
// Auto-play functionality (optional)
134+
let autoplayInterval;
135+
const autoplayDelay = 5000; // 5 seconds
136+
137+
function startAutoplay() {
138+
stopAutoplay(); // Clear any existing interval
139+
autoplayInterval = setInterval(() => {
140+
if (currentIndex < totalSlides - 1) {
141+
goToNextSlide();
142+
} else {
143+
goToSlide(0);
144+
}
145+
}, autoplayDelay);
146+
}
147+
148+
function stopAutoplay() {
149+
if (autoplayInterval) {
150+
clearInterval(autoplayInterval);
151+
}
152+
}
153+
154+
// Uncomment the line below to enable autoplay
155+
// startAutoplay();
156+
157+
// Stop autoplay on user interaction
158+
slider.addEventListener("mouseenter", stopAutoplay);
159+
slider.addEventListener("touchstart", stopAutoplay);
160+
prevBtn.addEventListener("click", stopAutoplay);
161+
nextBtn.addEventListener("click", stopAutoplay);
162+
pagination.addEventListener("click", stopAutoplay);
163+
});

0 commit comments

Comments
 (0)