Currently the carousel goes from slide to slide through the use of sluding with your finger, but on top of that I want to add arrows that allow you to go from slide to slide, even if they are just apart of the logo image. Any ideas on how to implement this?
CSS:
ul,
body,
p {
margin: 0;
padding: 0;
}
.slider {
box-sizing: border-box;
background: black;
width: 100vw;
height: 55vh;
overflow: hidden;
}
.slider .slides-container {
display: flex;
width: 100%;
height: 100%;
cursor: -webkit-grab;
cursor: grab;
transition: transform .5s;
}
.slider:active .slides-container {
cursor: -webkit-grabbing;
cursor: grabbing;
}
.slider .slides-container.moving {
transition: none;
}
.slider .slides-container.moving .slide {
transition: none;
}
.slider .slides-container.moving .parallax {
transition: none;
}
.slider .slide {
position: relative;
display: block;
width: 100%;
height: 100%;
background: #fff;
opacity: .8;
transform: scale(.9);
transform-origin: center;
transition: transform .5s, opacity .5s;
}
.slider .slide.current {
opacity: 1;
transform: scale(1);
}
.slider .slide .parallax {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
opacity: 0;
pointer-events: none;
transition: transform .5s, opacity .5s;
}
.slider .slide.current .parallax {
display: flex;
opacity: 1;
transform: translate3d(0, 0, 0);
}
.slider .slide .content {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.slider .slide .parallax p {
position: static;
text-align: left;
color: #000;
font-size: 2.3em;
justify-content: center;
align-items: center;
width: 77%
}
.slider .slide .parallax img {
position: static;
width: 35%;
justify-content: center;
align-items: center;
}
.slider .slide .parallax #TNYT {
position: static;
width: 35%;
justify-content: center;
align-items: center;
padding-top: 15px;
}
.slider .slide .parallax #ESQUIRE {
position: static;
width: 40%;
justify-content: center;
align-items: center;
margin-top: -10px;
}
.slider .slide .parallax #CNET {
position: static;
width: 35%;
justify-content: center;
align-items: center;
padding-top: 15px;
margin-bottom: -10px;
}
.slider .slide:nth-child(6n+2) {
background: #fff;
}
.slider .slide:nth-child(6n+3) {
background: #fff;
}
.slider .slide:nth-child(6n+4) {
background: #fff;
}
.slider .slide:nth-child(6n+5) {
background: #fff;
}
.slider .slide:nth-child(6n+6) {
background: #fff;
}
HTML:
<div class="slider">
<ul class="slides-container">
<li class="slide">
<div class="parallax">
<div class="content">
<p class="quote">“By eliminating middlemen and maintaining zero surplus stock,
Kuze is able to offer its premium products at a more affordable price compared to other bespoke clothing
brands, while still being Eco-friendly.”</p>
<img class="logo" src="https://cdn.shopify.com/s/files/1/0758/3105/0520/files/GQ.png?v=1700523020" alt="">
</div>
</div>
</li>
<li class="slide">
<div class="parallax">
<div class="content">
<p class="quote">“Say goodbye to ill-fitting clothes - no more drooping shoulders,
rolled-up cuffs, or loose, baggy tops and stretched waists.
With Kuze, every piece is tailored to fit you perfectly.”</p>
<img id="TNYT" class="logo" src="https://cdn.shopify.com/s/files/1/0758/3105/0520/files/TNYT.png?v=1700523020" alt="">
</div>
</div>
</li>
<li class="slide">
<div class="parallax">
<div class="content">
<p class="quote">“Kuze collaborates with leading fashion professionals and academic researchers to develop
their
Fit Recognition Engine®, ensuring a precise and personalized fit for every individual.”</p>
<img id="ESQUIRE" class="logo" src="https://cdn.shopify.com/s/files/1/0758/3105/0520/files/Esquire.png?v=1700523020" alt="">
</div>
</div>
</li>
<li class="slide">
<div class="parallax">
<div class="content">
<p class="quote">“the ultimate aim at Kuze is to boost the confidence of their customers by providing them
with
clothing that not only looks good but also feels great to wear.”</p>
<img id="CNET" class="logo" src="https://cdn.shopify.com/s/files/1/0758/3105/0520/files/CNET.png?v=1700523020" alt="">
</div>
</div>
</li>
<li class="slide">
<div class="parallax">
<div class="content">
<p class="quote">“At Kuze, each piece of clothing created is a unique masterpiece, tailored to ensure a
precise
fit. From incorporating your initials to meticulous tailoring, they ensure that every product is truly
one-of-a-kind.”</p>
<img class="logo" src="https://cdn.shopify.com/s/files/1/0758/3105/0520/files/Details.png?v=1700523020" alt="">
</div>
</div>
</li>
</ul>
</div>
JS:
/**
* Code by Noé Falque ➡️ noe.im
**/
class Slider {
constructor(el) {
this.el = el
this.container = this.el.querySelector('.slides-container')
this.slides = this.container.querySelectorAll('.slide')
this.parallaxes = this.container.querySelectorAll('.parallax')
this.current = 0;
this.currentPos
this.mouseOffset
this.moving = false
this.container.style.width = this.slides.length * 100 + '%'
this.slides[0].classList.add('current')
let startPos, lastTouchX
const
dragStart = (e) => {
e.stopPropagation()
if (e.touches) lastTouchX = e.touches[0].clientX
startPos = e.clientX || lastTouchX
this.mouseOffset = 0
this.currentPos = this.container.getBoundingClientRect().left;
this.moving = true;
requestAnimationFrame(this.move.bind(this))
},
dragEnd = (e) => {
if (this.moving) {
const moveX = e.clientX || lastTouchX
if (moveX < startPos - 100) this.next()
else if (moveX > startPos + 100) this.prev()
else this.goTo(this.current)
this.moving = false
}
},
dragMove = (e) => {
if (e.touches) lastTouchX = e.touches[0].clientX
const moveX = e.clientX || lastTouchX
this.mouseOffset = moveX - startPos
}
this.container.addEventListener('mousedown', dragStart)
this.container.addEventListener('touchstart', dragStart)
window.addEventListener('mouseup', dragEnd)
this.container.addEventListener('touchend', dragEnd)
window.addEventListener('mousemove', dragMove)
this.container.addEventListener('touchmove', dragMove)
window.addEventListener('keydown', (e) => {
e = e || window.event;
if (e.keyCode == '39') {// right arrow
this.next()
}
else if (e.keyCode == '37') {// left arrow
this.prev()
}
})
}
move() {
if (this.moving) {
this.container.style.transform = 'translate3d(' + (this.currentPos + this.mouseOffset) + 'px, 0, 0)'
this.container.classList.add('moving')
const slideWidth = this.slides[0].offsetWidth;
this.slides.forEach(($_slide, i) => {
const coef = 1 - Math.abs($_slide.getBoundingClientRect().left / slideWidth)
$_slide.style.opacity = .5 + (coef * .5)
$_slide.style.transform = 'scale(' + (.9 + coef * .1) + ')'
})
this.parallaxes.forEach(($_item, i) => {
const coef = this.slides[i].getBoundingClientRect().left / slideWidth
$_item.style.opacity = 1 - Math.abs(coef * 1.8)
$_item.style.transform = 'translate3d(' + (-coef * 85) + '%, 0, 0)'
})
requestAnimationFrame(this.move.bind(this))
}
}
goTo(i) {
if (i >= 0 && i < this.slides.length) this.current = i
this.container.classList.remove('moving')
this.container.style.transform = 'translate3d(' + this.current * -100 / this.slides.length + '%, 0, 0)'
this.slides.forEach(($_slide, i) => {
$_slide.classList.remove('current')
$_slide.removeAttribute('style')
})
this.slides[this.current].classList.add('current')
this.slides[this.current].removeAttribute('style')
this.parallaxes.forEach(($_item, i) => {
$_item.removeAttribute('style')
$_item.style.transform = 'translate3d(' + (i <= this.current ? 85 : -85) + '%, 0, 0)'
})
this.slides[this.current].querySelector('.parallax').removeAttribute('style')
}
next() {
this.goTo(this.current + 1)
}
prev() {
this.goTo(this.current - 1)
}
}
const $sliders = document.querySelectorAll('.slider')
const sliders = []
$sliders.forEach(($slider) => {
sliders.push(new Slider($slider))
})
I tried to add an image of an arrow and build radio functionality but unfortunatly i keep messing up.