-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
224 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
.wrapper-carousel { | ||
width: 100%; | ||
position: relative; | ||
} | ||
.wrapper-carousel i { | ||
top: 50%; | ||
height: 50px; | ||
width: 50px; | ||
cursor: pointer; | ||
font-size: 1.25rem; | ||
position: absolute; | ||
text-align: center; | ||
line-height: 50px; | ||
background: #fff; | ||
border-radius: 50%; | ||
box-shadow: 0 3px 6px rgba(0,0,0,0.23); | ||
transform: translateY(-50%); | ||
transition: transform 0.1s linear; | ||
} | ||
.wrapper-carousel i:active{ | ||
transform: translateY(-50%) scale(0.85); | ||
} | ||
.wrapper-carousel i:first-child{ | ||
left: -22px; | ||
} | ||
.wrapper-carousel i:last-child{ | ||
right: -22px; | ||
} | ||
.wrapper-carousel .carousel-secondary{ | ||
display: grid; | ||
grid-auto-flow: column; | ||
grid-auto-columns: calc((100% / 3)); | ||
overflow-x: auto; | ||
scroll-snap-type: x mandatory; | ||
gap: 16px; | ||
border-radius: 8px; | ||
scroll-behavior: smooth; | ||
scrollbar-width: none; | ||
} | ||
.carousel-secondary::-webkit-scrollbar { | ||
display: none; | ||
} | ||
.carousel-secondary.no-transition { | ||
scroll-behavior: auto; | ||
} | ||
.carousel-secondary.dragging { | ||
scroll-snap-type: none; | ||
scroll-behavior: auto; | ||
} | ||
.carousel-secondary.dragging .card-secondary { | ||
cursor: grab; | ||
user-select: none; | ||
} | ||
.carousel-secondary :where(.card-secondary, .card-img) { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
} | ||
.carousel-secondary .card-secondary { | ||
scroll-snap-align: start; | ||
height: 342px; | ||
list-style: none; | ||
background: #fff; | ||
cursor: pointer; | ||
padding-bottom: 15px; | ||
flex-direction: column; | ||
border-radius: 8px; | ||
} | ||
.carousel-secondary .card-secondary .card-img { | ||
background: #bc5148; | ||
height: 148px; | ||
width: 148px; | ||
border-radius: 50%; | ||
} | ||
.card-secondary .card-img img { | ||
width: 140px; | ||
height: 140px; | ||
border-radius: 50%; | ||
object-fit: cover; | ||
border: 4px solid #fff; | ||
} | ||
.carousel-secondary .card-secondary h2 { | ||
font-weight: 500; | ||
font-size: 1.56rem; | ||
margin: 30px 0 5px; | ||
} | ||
.carousel-secondary .card-secondary span { | ||
color: #6A6D78; | ||
font-size: 1.31rem; | ||
} | ||
|
||
@media screen and (max-width: 990px) { | ||
.wrapper-carousel .carousel-secondary { | ||
grid-auto-columns: calc((100% / 2)); | ||
} | ||
} | ||
|
||
@media screen and (max-width: 600px) { | ||
.wrapper-carousel .carousel-secondary { | ||
grid-auto-columns: 110%; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
const wrapper = document.querySelector(".wrapper-carousel"); | ||
const carousel = document.querySelector(".carousel-secondary"); | ||
const firstCardWidth = carousel.querySelector(".card-secondary").offsetWidth; | ||
const arrowBtns = document.querySelectorAll(".wrapper-carousel i"); | ||
const carouselChildren = [...carousel.children]; | ||
|
||
let isDragging = false, isAutoPlay = false, startX, startScrollLeft, timeoutId; | ||
|
||
// Get the number of cards that can fit in the carousel at once | ||
let cardPerView = Math.round(carousel.offsetWidth / firstCardWidth); | ||
|
||
// Insert copies of the last few cards to beginning of carousel for infinite scrolling | ||
carouselChildren.slice(-cardPerView).reverse().forEach(card => { | ||
carousel.insertAdjacentHTML("afterbegin", card.outerHTML); | ||
}); | ||
|
||
// Insert copies of the first few cards to end of carousel for infinite scrolling | ||
carouselChildren.slice(0, cardPerView).forEach(card => { | ||
carousel.insertAdjacentHTML("beforeend", card.outerHTML); | ||
}); | ||
|
||
// Scroll the carousel at appropriate position to hide first few duplicate cards on Firefox | ||
carousel.classList.add("no-transition"); | ||
carousel.scrollLeft = carousel.offsetWidth; | ||
carousel.classList.remove("no-transition"); | ||
|
||
// Add event listeners for the arrow buttons to scroll the carousel left and right | ||
arrowBtns.forEach(btn => { | ||
btn.addEventListener("click", () => { | ||
carousel.scrollLeft += btn.id === "left" ? -firstCardWidth : firstCardWidth; | ||
}); | ||
}); | ||
|
||
const dragStart = (e) => { | ||
isDragging = true; | ||
carousel.classList.add("dragging"); | ||
// Records the initial cursor and scroll position of the carousel | ||
startX = e.pageX; | ||
startScrollLeft = carousel.scrollLeft; | ||
} | ||
|
||
const dragging = (e) => { | ||
if(!isDragging) return; // if isDragging is false return from here | ||
// Updates the scroll position of the carousel based on the cursor movement | ||
carousel.scrollLeft = startScrollLeft - (e.pageX - startX); | ||
} | ||
|
||
const dragStop = () => { | ||
isDragging = false; | ||
carousel.classList.remove("dragging"); | ||
} | ||
|
||
const infiniteScroll = () => { | ||
// If the carousel is at the beginning, scroll to the end | ||
if(carousel.scrollLeft === 0) { | ||
carousel.classList.add("no-transition"); | ||
carousel.scrollLeft = carousel.scrollWidth - (2 * carousel.offsetWidth); | ||
carousel.classList.remove("no-transition"); | ||
} | ||
// If the carousel is at the end, scroll to the beginning | ||
else if(Math.ceil(carousel.scrollLeft) === carousel.scrollWidth - carousel.offsetWidth) { | ||
carousel.classList.add("no-transition"); | ||
carousel.scrollLeft = carousel.offsetWidth; | ||
carousel.classList.remove("no-transition"); | ||
} | ||
|
||
// Clear existing timeout & start autoplay if mouse is not hovering over carousel | ||
clearTimeout(timeoutId); | ||
if(!wrapper.matches(":hover")) autoPlay(); | ||
} | ||
|
||
const autoPlay = () => { | ||
if(window.innerWidth < 800 || !isAutoPlay) return; // Return if window is smaller than 800 or isAutoPlay is false | ||
// Autoplay the carousel after every 2500 ms | ||
timeoutId = setTimeout(() => carousel.scrollLeft += firstCardWidth, 2500); | ||
} | ||
autoPlay(); | ||
|
||
carousel.addEventListener("mousedown", dragStart); | ||
carousel.addEventListener("mousemove", dragging); | ||
document.addEventListener("mouseup", dragStop); | ||
carousel.addEventListener("scroll", infiniteScroll); | ||
wrapper.addEventListener("mouseenter", () => clearTimeout(timeoutId)); | ||
wrapper.addEventListener("mouseleave", autoPlay); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<div class="container"> | ||
<div class="wrapper-carousel"> | ||
<i id="left" class="fa-solid fa-angle-left"></i> | ||
<ul class="carousel-secondary"> | ||
<li class="card-secondary"> | ||
<div class="card-img"><img src="https://fer-bar.github.io/AlberCan/images/article2.jpg" alt="img" draggable="false"></div> | ||
<h2>Blanche Pearson</h2> | ||
<span>Sales Manager</span> | ||
</li> | ||
<li class="card-secondary"> | ||
<div class="card-img"><img src="https://fer-bar.github.io/AlberCan/images/article3.jpg" alt="img" draggable="false"></div> | ||
<h2>Joenas Brauers</h2> | ||
<span>Web Developer</span> | ||
</li> | ||
<li class="card-secondary"> | ||
<div class="card-img"><img src="https://fer-bar.github.io/AlberCan/images/pet1.jpg" alt="img" draggable="false"></div> | ||
<h2>Lariach French</h2> | ||
<span>Online Teacher</span> | ||
</li> | ||
<li class="card-secondary"> | ||
<div class="card-img"><img src="https://fer-bar.github.io/AlberCan/images/pet2.jpg" alt="img" draggable="false"></div> | ||
<h2>Iver Don Fallas</h2> | ||
<span>Alcoholico</span> | ||
</li> | ||
<li class="card-secondary"> | ||
<div class="card-img"><img src="https://fer-bar.github.io/AlberCan/images/pet3.jpg" alt="img" draggable="false"></div> | ||
<h2>Kristina Zasiadko</h2> | ||
<span>Bank Manager</span> | ||
</li> | ||
<li class="card-secondary"> | ||
<div class="card-img"><img src="https://fer-bar.github.io/AlberCan/images/pet4.jpg" alt="img" draggable="false"></div> | ||
<h2>Donald Horton</h2> | ||
<span>App Designer</span> | ||
</li> | ||
</ul> | ||
<i id="right" class="fa-solid fa-angle-right"></i> | ||
</div> | ||
</div> |