Custom Shopify Development

Mudassir Bilal

Web Developer
Framer Shopify Developer
The demand of the clients were clear, He asked me to create a custom slider with JavaScript for his Shopify store, He asked me to do it without using any library and so I did, I did it within matter of time. It took some time but it was worth it.
<!DOCTYPE html>

<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>

<style>
* {
margin: 0;
padding: 0;
}

.slider__wrapper {
position: relative;
}

.slider {
position: relative;
max-width: 100%;
height: 42vh;
margin: auto;
overflow: hidden;
}

.slide {
width: 100%;
height: 100%;
position: absolute;
text-align: center;
-webkit-transition: 0.6s ease;
transition: 0.6s ease;
-webkit-transform: translate(-100%, 0);
transform: translate(-100%, 0);
}

.slide>img {
width: 100%;
height: 100%;
object-fit: cover;
}

.slide.active {
-webkit-transform: translate(0, 0);
transform: translate(0, 0);
}

.slide.active~.slide {
-webkit-transform: translate(100%, 0);
transform: translate(100%, 0);
}

.d8-button {
border: none;
cursor: pointer;
background: none;
}

.d8-arrows>button svg {
pointer-events: none;
border-radius: 9999px;
width: 20px;
height: 20px;
padding: 5px;
background: rgba(0, 0, 0, .27);
fill: #fff;
}

.d8-arrows {
position: absolute;
top: 45%;
width: 95%;
margin-left: 2.5%;
display: flex;
justify-content: space-between;
}

#prev {
transform: scaleX(-1);
}

.dots {
position: absolute;
bottom: 10px;
display: flex;
width: 100%;
justify-content: center;
}

.slide-dot-active {
background-color: white !important;
transform: scale(1) !important;
}

.autoPlay {
background-color: transparent !important;
transform: scale(1.25, 1.25);
}

.autoPlay span {
display: block;
height: 100%;
width: 100%;
}

.autoPlay svg {
height: 10px;
width: 10px;
position: absolute;
top: 0;
left: 0;
}

#autoPlay_pause {
fill: white;
}

#autoPlay_play {
display: none;
}

.d8-dot-button {
height: 10px;
width: 10px;
border-radius: 100px;
transition: all 0.5s;
margin: 0 5px;
border: 1px solid white;
}

.dotsContainer {
display: flex;
justify-content: space-around;
}

.slide-dot-scale100 {
transform: scale(1);
}

.slide-dot-scale75 {
transform: scale(0.75);
}

.slide-dot-scale50 {
transform: scale(0.5);
}

.slide-dot-scale0 {
transform: scale(0);
}

.displayNone {
display: none !important;
}
</style>

</head>

<body>


<div class="slider__wrapper">
<div class="slider">
<div class="slide active">
<img class="desktopImage" src="./375 into 180 height/1 33.png" alt="">
</div>
<div class="slide">
<img class="desktopImage" src="./375 into 180 height/2 9.png" alt="">
</div>
<div class="slide">
<img class="desktopImage" src="./375 into 180 height/3 8.png" alt="">
</div>
<div class="slide">
<img class="desktopImage" src="./375 into 180 height/4 7.png" alt="">
</div>
</div>

<div class="d8-arrows">
<button id="prev" class="btn d8-button">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" focusable="false">
<path d="m15.5 0.932-4.3 4.38 14.5 14.6-14.5 14.5 4.3 4.4 14.6-14.6 4.4-4.3-4.4-4.4-14.6-14.6z">
</path>
</svg>
</button>
<button id="next" class="btn d8-button">
<svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40" focusable=" false">
<path d="m15.5 0.932-4.3 4.38 14.5 14.6-14.5 14.5 4.3 4.4 14.6-14.6 4.4-4.3-4.4-4.4-14.6-14.6z">
</path>
</svg>
</button>
</div>

<div class="dots">
<div class="dotsContainer">

<div class="autoPlay d8-button d8-dot-button" id="autoPlayBtn">
<span id="autoPlay_play">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="16" height="16"
viewBox="0 0 408.221 408.221" xml:space="preserve">
<path
d="M204.11,0C91.388,0,0,91.388,0,204.111c0,112.725,91.388,204.11,204.11,204.11c112.729,0,204.11-91.385,204.11-204.11
C408.221,91.388,316.839,0,204.11,0z M286.547,229.971l-126.368,72.471c-17.003,9.75-30.781,1.763-30.781-17.834V140.012
c0-19.602,13.777-27.575,30.781-17.827l126.368,72.466C303.551,204.403,303.551,220.217,286.547,229.971z">
</path>
</svg>
</span>
<span id="autoPlay_pause">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="16" height="16"
viewBox="0 0 45.812 45.812" xml:space="preserve">
<path
d="M39.104,6.708c-8.946-8.943-23.449-8.946-32.395,0c-8.946,8.944-8.946,23.447,0,32.394
c8.944,8.946,23.449,8.946,32.395,0C48.047,30.156,48.047,15.653,39.104,6.708z M20.051,31.704c0,1.459-1.183,2.64-2.641,2.64
s-2.64-1.181-2.64-2.64V14.108c0-1.457,1.182-2.64,2.64-2.64s2.641,1.183,2.641,2.64V31.704z M31.041,31.704
c0,1.459-1.183,2.64-2.64,2.64s-2.64-1.181-2.64-2.64V14.108c0-1.457,1.183-2.64,2.64-2.64s2.64,1.183,2.64,2.64V31.704z">
</path>
</svg>
</span>
</div>
<div class="slide-dot slide-dot-active d8-button d8-dot-button"></div>
<div class="slide-dot d8-button d8-dot-button"></div>
<div class="slide-dot d8-button d8-dot-button"></div>
<div class="slide-dot d8-button d8-dot-button"></div>
</div>
</div>

</div>

<script>
const dots = document.getElementsByClassName('slide-dot');

function allignDots() {
for (let i = 0; i < dots.length; i++) {
dots[i].classList.remove("slide-dot-scale100")
dots[i].classList.remove("slide-dot-scale75")
dots[i].classList.remove("slide-dot-scale50")
dots[i].classList.remove("slide-dot-scale0")
if (i <= 2) {
dots[i].classList.add("slide-dot-scale100")
} else if (i == 3) {
dots[i].classList.add("slide-dot-scale75")
} else if (i == 4) {
dots[i].classList.add("slide-dot-scale50")
} else {
dots[i].classList.add("slide-dot-scale0")
}
}
changeDots();
}
allignDots()

function changeDots() {
for (let index = 0; index < dots.length; index++) {
const element = dots[index];
element.classList.remove("displayNone");
if (window.getComputedStyle(element).getPropertyValue('transform') === "matrix(0, 0, 0, 0, 0, 0)") {
element.classList.add('displayNone');
} else {
element.classList.remove('displayNone');
}
}
}

changeDots()

function removeDots0() {
const dots = document.getElementsByClassName('slide-dot');
for (let i = 0; i < dots.length; i++) {
const element = dots[i];
if (element.classList.contains("slide-dot-active")) {
if (i > 2) {
for (let index = 0; index < dots.length; index++) {
dots[index].classList.remove("slide-dot-scale100");
dots[index].classList.remove("slide-dot-scale75");
dots[index].classList.remove("slide-dot-scale50");
dots[index].classList.remove("slide-dot-scale0");
if (index == i) {
dots[index].classList.add("slide-dot-scale100")
} else if (index == (i - 1)) {
dots[index].classList.add("slide-dot-scale75")
} else if (index == (i - 2)) {
dots[index].classList.add("slide-dot-scale50")
} else if (index == (i + 1)) {
dots[index].classList.add("slide-dot-scale75")
} else if (index == (i + 2)) {
dots[index].classList.add("slide-dot-scale50")
} else {
dots[index].classList.add("slide-dot-scale0")
}
}
changeDots()
} else {
allignDots();
}
}
}
}

removeDots0()



let autoplay = true;
function slider() {

let autoplayInterval;
let currentIndex = 0;
let slides = document.querySelectorAll(".slide"),
slider = document.querySelector(".slider"),
last = slider.lastElementChild,
first = slider.firstElementChild,
btn = document.querySelectorAll(".btn"),
dots = document.querySelectorAll(".slide-dot")

slider.insertBefore(last, first);


let activeElement;
for (let i = 0; i < dots.length; i++) {
const element = dots[i];
element.addEventListener("click", () => {
for (let index = 0; index < dots.length; index++) {
if (dots[index].classList.contains("slide-dot-active")) {
activeElement = index;
}
}
if (i < activeElement) {
console.log(`dot is ${(activeElement - i)} dots behind`)
let intervalIndex = 0;
let intervalId = setInterval(() => {
if (intervalIndex < (activeElement - i)) {
document.getElementById("prev").click();
intervalIndex++;
} else {
clearInterval(intervalId);
intervalId = null;
}
}, 300)
} else if (i > activeElement) {
console.log("dot is forward", Number((activeElement - i).toString().replace(/-/g, "")));
let intervalIndex = 0;
let intervalId = setInterval(() => {
if (intervalIndex < Number((activeElement - i).toString().replace(/-/g, ""))) {
document.getElementById("next").click();
intervalIndex++;
} else {
clearInterval(intervalId);
intervalId = null;
}
}, 300)
}
})
}


function autoPlay() {
if (autoplay == true) {
autoplayInterval = setInterval(() => {
dots[currentIndex].classList.remove('slide-dot-active');
slider = document.querySelector(".slider");
const activeSlide = document.querySelector(".active");
last = slider.lastElementChild;
first = slider.firstElementChild;
slider.insertBefore(first, last.nextSibling);
activeSlide.classList.remove("active");
activeSlide.nextElementSibling.classList.add("active");
currentIndex = (currentIndex + 1) % dots.length;
dots[currentIndex].classList.add('slide-dot-active');
// removeDots0()
}, 10000)
} else {
clearInterval(autoplayInterval)
autoplayInterval = null;
}
}

autoPlay();

for (let index = 0; index < btn.length; index++) {
const element = btn[index];
element.addEventListener("click", movement)
}

function movement(e) {
slider = document.querySelector(".slider");
last = slider.lastElementChild;
first = slider.firstElementChild;

const activeSlide = document.querySelector(".active");

dots[currentIndex].classList.remove('slide-dot-active');
if (e.target.id === "next") {
slider.insertBefore(first, last.nextSibling);

activeSlide.classList.remove("active");
activeSlide.nextElementSibling.classList.add("active");
currentIndex = (currentIndex + 1) % dots.length
} else {
slider.insertBefore(last, first);
activeSlide.classList.remove("active");
activeSlide.previousElementSibling.classList.add("active");
currentIndex = (currentIndex - 1 + dots.length) % dots.length;
}
dots[currentIndex].classList.add('slide-dot-active');
// removeDots0();
}

document.getElementById('autoPlayBtn').addEventListener("click", () => {
if (autoplay == false) {
autoplay = true;
document.getElementById('autoPlay_play').style.display = "none"
document.getElementById('autoPlay_pause').style.display = "block"
} else {
autoplay = false;
document.getElementById('autoPlay_play').style.display = "block"
document.getElementById('autoPlay_pause').style.display = "none"
}
autoPlay();
})
}
slider();
</script>


</body>

</html>
This is just one of the work I did, I have nothing more to say, looking forward to work with you.
Partner With Mudassir
View Services

More Projects by Mudassir