Skip to content

Commit 34a4ab8

Browse files
authored
Touch Slider
1 parent 027be79 commit 34a4ab8

File tree

3 files changed

+191
-0
lines changed

3 files changed

+191
-0
lines changed

app.js

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
const slider = document.querySelector(".slider-container"),
2+
slides = Array.from(document.querySelectorAll(".slide"));
3+
4+
let isDragging = false,
5+
startPos = 0,
6+
currentTranslate = 0,
7+
prevTranslate = 0,
8+
animationID = 0,
9+
currentIndex = 0;
10+
11+
slides.forEach((slide, index) => {
12+
const slideImage = slide.querySelector("img");
13+
slideImage.addEventListener("dragstart", (e) => e.preventDefault());
14+
15+
// Touch Events
16+
17+
slide.addEventListener("touchstart", touchStart(index));
18+
slide.addEventListener("touchend", touchEnd);
19+
slide.addEventListener("touchmove", touchMove);
20+
21+
// Mouse events
22+
23+
slide.addEventListener("mousedown", touchStart(index));
24+
slide.addEventListener("mouseup", touchEnd);
25+
slide.addEventListener("mouseleave", touchEnd);
26+
slide.addEventListener("mousemove", touchMove);
27+
});
28+
29+
window.oncontextmenu = function (event) {
30+
event.preventDefault();
31+
event.stopPropagation();
32+
return false;
33+
};
34+
35+
function touchStart(index) {
36+
return function (event) {
37+
currentIndex = index;
38+
startPos = getPositionX(event);
39+
isDragging = true;
40+
41+
animationID = requestAnimationFrame(animation);
42+
slider.classList.add("grabbing");
43+
};
44+
}
45+
46+
function touchEnd() {
47+
isDragging = false;
48+
cancelAnimationFrame(animationID);
49+
50+
const movedBy = currentTranslate - prevTranslate;
51+
52+
if (movedBy < -100 && currentIndex < slides.length - 1) {
53+
currentIndex += 1;
54+
}
55+
56+
if (movedBy > 100 && currentIndex > 0) {
57+
currentIndex -= 1;
58+
}
59+
60+
setPositionByIndex();
61+
slider.classList.remove("grabbing");
62+
}
63+
64+
function touchMove(event) {
65+
if (isDragging) {
66+
const currentPosition = getPositionX(event);
67+
currentTranslate = prevTranslate + currentPosition - startPos;
68+
}
69+
}
70+
71+
function getPositionX(event) {
72+
return event.type.includes("mouse") ? event.pageX : event.touches[0].clientX;
73+
}
74+
75+
function animation() {
76+
setSliderPosition();
77+
if (isDragging) requestAnimationFrame(animation);
78+
}
79+
80+
function setSliderPosition() {
81+
slider.style.transform = `translateX(${currentTranslate}px)`;
82+
}
83+
84+
function setPositionByIndex() {
85+
currentTranslate = currentIndex * -window.innerWidth;
86+
prevTranslate = currentTranslate;
87+
setSliderPosition();
88+
}

index.html

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Touch Slider</title>
8+
<link rel="stylesheet" href="style.css" />
9+
<script src="app.js" defer></script>
10+
</head>
11+
<body>
12+
<div class="slider-container">
13+
<div class="slide">
14+
<h2>Airpods</h2>
15+
<h4>$199</h4>
16+
<img src="https://i.ibb.co/y08W0Jx/image1.png" />
17+
<a href="#" class="btn">Buy Now</a>
18+
</div>
19+
20+
<div class="slide">
21+
<h2>iPhone12</h2>
22+
<h4>$799</h4>
23+
<img src="https://i.ibb.co/NYdGg2q/image2.png" />
24+
<a href="#" class="btn">Buy Now</a>
25+
</div>
26+
27+
<div class="slide">
28+
<h2>iPad</h2>
29+
<h4>$599</h4>
30+
<img src="https://i.ibb.co/Jd3t4hQ/image3.png" />
31+
<a href="#" class="btn">Buy Now</a>
32+
</div>
33+
</div>
34+
</body>
35+
</html>

style.css

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
@import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap");
2+
3+
* {
4+
box-sizing: border-box;
5+
margin: 0;
6+
padding: 0;
7+
}
8+
9+
html,
10+
body {
11+
font-family: "Poppins", sans-serif;
12+
height: 100%;
13+
width: 100%;
14+
overflow: hidden;
15+
background-color: #333;
16+
color: #fff;
17+
line-height: 1.7;
18+
}
19+
20+
.slider-container {
21+
height: 100vh;
22+
display: inline-flex;
23+
overflow: hidden;
24+
transform: translateX(0);
25+
transition: transform 0.3s ease-out;
26+
cursor: grab;
27+
}
28+
29+
.slide {
30+
max-height: 100vh;
31+
width: 100vw;
32+
display: flex;
33+
flex-direction: column;
34+
align-items: center;
35+
justify-content: center;
36+
padding: 1rem;
37+
user-select: none;
38+
}
39+
40+
.slide img {
41+
max-width: 100%;
42+
max-height: 60%;
43+
transition: transform 0.3s ease-in-out;
44+
}
45+
46+
.slide h2 {
47+
font-size: 2.5rem;
48+
margin-bottom: 0.5rem;
49+
}
50+
51+
.slide h4 {
52+
font-size: 1.3rem;
53+
}
54+
55+
.btn {
56+
background-color: #444;
57+
color: #fff;
58+
text-decoration: none;
59+
padding: 1rem 1.5rem;
60+
}
61+
62+
.grabbing {
63+
cursor: grabbing;
64+
}
65+
66+
.grabbing .slide img {
67+
transform: scale(0.9);
68+
}

0 commit comments

Comments
 (0)