How to make Responsive GSAP Slider with Button Wave Effect using HTML CSS & JavaScript

shobhitdev
15 Min Read

Let’s make a responsive slider with a button wave effect using HTML, CSS, and JavaScript. This slider will adjust to different screen sizes and will use the GreenSock Animation Platform (GSAP) for cool animations.

We’ll use HTML to build the slider, CSS to style it and make it responsive, and JavaScript with GSAP to create the animations and the button wave effect.

Whether you’re new to coding or have experience, this project is a fun way to show off content and add interactive elements to your website.

How to make Responsive GSAP Slider with Button Wave Effect using HTML CSS & JavaScript

Let’s add some motion and excitement to our web projects!

HTML :

This HTML document creates a webpage featuring a responsive slider that displays fruit images. It includes navigation buttons for moving through the slides and uses external CSS and JavaScript libraries for styling and animations. Each slide in the slider showcases a different fruit image.

				
					<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>Responsive GSAP Slider with Button Wave Effect</title>
  <link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css'><link rel="stylesheet" href="./style.css">

</head>
<body>
<!-- partial:index.partial.html -->
<body>
  <!-- header -->
  <header>
    <h2 id="fruity" class="rb-heading-index-1 logo"><h2 class="logo">
      Fruity
    </h2></h2>
  </header>
  <!-- main -->
  <main>
    <!-- Buttons -->
    <div>
      <button id="prevButton" class="wave"><i class="fa-solid fa-chevron-left"></i></button>
      <button id="nextButton" class="wave"><i class="fa-solid fa-chevron-right"></i></button>
    </div>
    <!-- Fixed Sections -->
    <div class="text">
      <h1 id="pear" class="rb-heading-index-2 h1">Pear</h1>
      <div class="cane-image ">
        <img decoding="async" src="Images\cane.svg" alt="">
        <img decoding="async" src="Images\Labels.jpg" alt="" class="cane-labels">
      </div>
    </div>
    <!-- Fixed Sections Ends-->
    <!-- Fruits Images Section -->
    <div class="section-container-main">
      <div class="section-container">
        <section class="section" id="section1">
          <div class="fruit-images">
            <div class="image-one fruit-image"><img decoding="async" src="Images\pear-one.png" alt="pear-image"></div>
            <div class="image-two fruit-image"><img decoding="async" src="Images\pear-two.png" alt="pear-image"></div>
            <div class="image-three fruit-image"><img decoding="async" src="Images\pear-three.png" alt="pear-image"></div>
            <div class="image-four fruit-image"><img decoding="async" src="Images\pear-four.png" alt="pear-image"></div>
          </div>
        </section>
        <section class="section" id="section2">
          <div class="fruit-images">
            <div class="image-one fruit-image"><img decoding="async" src="Images\apple-one.png" alt="apple-image"></div>
            <div class="image-two fruit-image"><img decoding="async" src="Images\apple-two.png" alt="apple-image"></div>
            <div class="image-three fruit-image"><img decoding="async" src="Images\apple-three.png" alt="apple-image"></div>
            <div class="image-four fruit-image"><img decoding="async" src="Images\apple-four.png" alt="apple-image"></div>
          </div>
        </section>
        <section class="section" id="section3">
          <div class="fruit-images">
            <div class="image-one fruit-image"><img decoding="async" src="Images\exotic-one.png" alt="exotic-image"></div>
            <div class="image-two fruit-image"><img decoding="async" src="Images\exotic-two.png" alt="exotic-image"></div>
            <div class="image-three fruit-image"><img decoding="async" src="Images\exotic-three.png" alt="exotic-image"></div>
            <div class="image-four fruit-image"><img decoding="async" src="Images\exotic-four.png" alt="exotic-image"></div>
          </div>
        </section>
      </div>
    </div>
  </main>
</body>
<!-- partial -->
  <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/3.9.1/gsap.min.js'></script><script  src="./script.js"></script>

</body>
</html>
				
			

CSS :

This CSS file enhances the webpage’s appearance by setting up fonts, colors, and spacing. It styles buttons and images to ensure they fit well on the page and adjusts the layout to look great on different screen sizes.

				
					@import url("https://fonts.googleapis.com/css2?family=Lexend:wght@100..900&display=swap");

/* Common Style */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
img {
  width: 100%;
  height: auto;
}
body {
  overflow: hidden !important;
}
a:focus {
  outline: none;
  box-shadow: none;
}
input:focus {
  outline: none;
  border: none;
  box-shadow: none;
}
input:focus-visible {
  outline: none;
  border: none;
  box-shadow: none;
}
button:focus,
:focus-visible {
  outline: none;
  border: none;
}
/* Root*/
:root {
  --pear-can: #e6ffde;
  --pear-logo: #03403f;
  --apple-can: #f2675a;
  --apple-logo: #ec4458;
  --exotic-can: #9590f1;
  --black-color: #000000;
  --white-color: #ffffff;
  --exotic-logo: #6464ff;
  --pear-background: #c9e78a;
  --apple-background: #ffb2b2;
  --exotic-background: #c1bff2;
}
/* Typography */
h1 {
  font-family: "Lexend";
  font-size: 449px !important;
  line-height: normal !important;
  color: var(--white-color) !important;
  margin: 0 !important;
}
h2 {
  font-family: "Lexend";
  font-size: 40px;
  line-height: normal;
  margin: 0;
  font-weight: 900;
}
/* Header */
header {
  padding: 22px 28px 0;
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  z-index: 99;
  text-align: center;
}
.logo {
  color: var(--pear-logo);
}
h1 {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
/* Cane Image and Wrapper Image */
.cane-image {
  max-width: 265px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  mask-image: url(Images/cane.svg);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center center;
  mask-position: center center;
  -webkit-mask-size: 100% auto;
  mask-size: 100% auto;
  overflow: hidden;
}
.cane-image img {
  width: 100%;
}
.cane-labels {
  position: absolute;
  top: 0;
  left: 0;
  width: 300% !important;
  mix-blend-mode: multiply;
  transition: all ease-in-out 0.3s;
}
/*Fruits Images */
.fruit-image {
  opacity: 1;
  position: absolute;
}
.image-one {
  max-width: 282px;
  bottom: 100px;
}
.image-two {
  max-width: 247px;
  top: 23%;
  left: 25%;
}
.image-three {
  max-width: 211px;
  top: 23%;
  right: 25%;
}
.image-four {
  max-width: 294px;
  bottom: 100px;
  right: 0;
}
/* After */
.fruit-image::after {
  content: "";
  position: absolute;
  background: linear-gradient(90deg, #000 3.66%, rgba(0, 0, 0, 0) 92.35%);
  opacity: 0.43;
  filter: blur(7.5px);
  transform: rotate(-6.941deg);
  right: 0;
  width: 173px;
  height: 30px;
}
.image-one::after {
  bottom: -50px;
}
.image-two::after {
  bottom: -200px;
  height: 22px;
}
.image-three::after {
  bottom: -280px;
  width: 103px;
}
.image-four::after {
  bottom: -50px;
}
/*Section  */
.section-container-main {
  width: 100vw;
  overflow: hidden;
  position: relative;
  z-index: -1;
}
.section-container {
  width: 300vw;
  display: flex;
  position: relative;
  transition: all ease-in-out 0.5s;
  align-items: center;
}
.section {
  min-width: 100vw;
  height: 100vh;
  position: relative;
  overflow: hidden;
  z-index: -1;
  background: var(--pear-background);
}
.section:nth-child(2) {
  background-color: var(--apple-background);
}
.section:nth-child(3) {
  background-color: var(--exotic-background);
}
/* Add this to your CSS */
/* Buttons */
button {
  position: fixed;
  top: 50%;
  right: 30px;
  z-index: 99;
  transform: translateY(-50%);
  border-radius: 50%;
  height: 80px;
  width: 80px;
  background-color: var(--white-color);
  border: none;
  font-size: 40px;
  color: var(--apple-logo);
  transition: all ease-in-out 0.3s;
  cursor: pointer;
}
#prevButton {
  left: 30px;
  right: unset;
  display: none;
  transition: all ease-in 0.3s;
}
.wave {
  animation: wave-apple-effect 4s linear infinite;
  animation-direction: normal;
}
@keyframes wave-pear-effect {
  0% {
    box-shadow: 0 0 0 0px var(--pear-background),
      0 0 0 0px var(--pear-background);
  }
  40% {
    box-shadow: 0 0 0 50px rgba(60, 41, 188, 0),
      0 0 0 0px var(--pear-background);
  }
  80% {
    box-shadow: 0 0 0 50px rgba(60, 41, 188, 0), 0 0 0 30px rgba(0, 0, 0, 0);
  }
  100% {
    box-shadow: 0 0 0 0px rgba(60, 41, 188, 0), 0 0 0 30px rgba(0, 230, 118, 0);
  }
}
@keyframes wave-apple-effect {
  0% {
    box-shadow: 0 0 0 0px var(--apple-background),
      0 0 0 0px var(--apple-background);
  }
  40% {
    box-shadow: 0 0 0 50px rgba(60, 41, 188, 0),
      0 0 0 0px var(--apple-background);
  }
  80% {
    box-shadow: 0 0 0 50px rgba(60, 41, 188, 0), 0 0 0 30px rgba(0, 0, 0, 0);
  }
  100% {
    box-shadow: 0 0 0 0px rgba(60, 41, 188, 0), 0 0 0 30px rgba(0, 230, 118, 0);
  }
}
@keyframes wave-exotic-effect {
  0% {
    box-shadow: 0 0 0 0px var(--exotic-background),
      0 0 0 0px var(--exotic-background);
  }
  40% {
    box-shadow: 0 0 0 50px rgba(60, 41, 188, 0),
      0 0 0 0px var(--exotic-background);
  }
  80% {
    box-shadow: 0 0 0 50px rgba(60, 41, 188, 0), 0 0 0 30px rgba(0, 0, 0, 0);
  }
  100% {
    box-shadow: 0 0 0 0px rgba(60, 41, 188, 0), 0 0 0 30px rgba(0, 230, 118, 0);
  }
}
/*.......... Responsive.............. */
@media screen and (max-width: 1550px) {
  h1 {
    font-size: 350px !important;
  }
  .cane-image {
    max-width: 280px;
  }
  .image-one {
    max-width: 250px;
  }
  .image-two {
    max-width: 215px;
    left: 22%;
    top: 10%;
  }
  .image-three {
    max-width: 180px;
  }
  .image-four {
    max-width: 260px;
    right: 40px;
  }
}
@media screen and (max-width: 1199px) {
  h1 {
    font-size: 300px !important;
  }
  .cane-image::after {
    width: 150%;
  }
  .image-one {
    max-width: 220px;
  }
  .image-two {
    max-width: 185px;
    left: 18%;
    top: 10%;
  }
  .image-three {
    max-width: 180px;
    right: 18%;
  }
  .image-four {
    max-width: 230px;
  }
}
@media screen and (max-width: 991px) {
  h1 {
    font-size: 240px !important;
  }
  .cane-image {
    max-width: 250px;
  }
  button {
    height: 80px;
    width: 80px;
    top: 90%;
  }
  .image-one {
    max-width: 180px;
  }
  .image-two {
    max-width: 165px;
    left: 12%;
    top: 12%;
  }
  .image-three {
    max-width: 150px;
    right: 12%;
  }
  .image-four {
    max-width: 200px;
  }
}
@media screen and (max-width: 767px) {
  h1 {
    font-size: 180px !important;
  }
  h2 {
    font-size: 30px;
  }
  .cane-image {
    max-width: 180px;
  }
  button {
    height: 60px;
    width: 60px;
    font-size: 20px;
  }
  .image-one {
    max-width: 180px;
    bottom: 150px;
  }
  .image-two {
    max-width: 145px;
    left: 12%;
    top: 15%;
  }
  .image-three {
    max-width: 130px;
    right: 10%;
  }
  .image-four {
    max-width: 180px;
    bottom: 150px;
  }
}
@media screen and (max-width: 575px) {
  h1 {
    font-size: 100px !important;
  }
  .cane-image::after {
    width: 100%;
  }
  .image-one {
    max-width: 150px;
  }
  .image-two {
    max-width: 115px;
    left: 4%;
    top: 18%;
  }
  .image-three {
    max-width: 100px;
    right: 4%;
  }
  .image-four {
    max-width: 150px;
    right: 0;
  }
}
				
			

Javascript :

This JavaScript code improves the webpage’s functionality by enabling interactive navigation between different sections. It starts by animating the fruit images when the page loads. It also listens for clicks on the next and previous buttons. When the next button is clicked, the script moves to the next section, updating text and colors while adding smooth animations. Similarly, clicking the previous button navigates to the previous section with the same updates and animations. Overall, this script enhances user engagement and improves the browsing experience on the webpage.

				
					//............................................................... Script ...................................................................
// Data for the sections
let h1Texts = ["Pear", "Apple", "Exotic"]; // Add your h1 texts here
let logoColors = [
  "var(--pear-logo)",
  "var(--apple-logo)",
  "var(--exotic-logo)"
]; // Add your logo colors here
let keyframes = ["wave-pear-effect", "wave-apple-effect", "wave-exotic-effect"]; // Add your keyframes here
// Normal GSAP animation.......
gsap.from(".fruit-image ", { y: "-100vh", delay: 0.5 });
gsap.to(".fruit-image img", {
  x: "random(-20, 20)",
  y: "random(-20, 20)",
  zIndex: 22,
  duration: 2,
  ease: "none",
  yoyo: true,
  repeat: -1
});

// get the elements
const waveEffect = document.querySelector(".wave");
const sections = document.querySelectorAll(".section");
const prevButton = document.getElementById("prevButton");
const nextButton = document.getElementById("nextButton");
const caneLabels = document.querySelector(".cane-labels");
const sectionContainer = document.querySelector(".section-container");
// Set index and current position
let index = 0;
let currentIndex = 0;
let currentPosition = 0;

// Add event listeners to the buttons
nextButton.addEventListener("click", () => {
  // Decrease the current position by 100% (to the left)
  if (currentPosition > -200) {
    currentPosition -= 100;
    // Update the left position of the cane-labels
    caneLabels.style.left = `${currentPosition}%`;
    sectionContainer.style.left = `${currentPosition}%`;
  }
  // Increment index and currentIndex
  currentIndex++;
  // Update the h1 text if currentIndex is less than the length of h1Texts
  if (currentIndex < h1Texts.length) {
    document.querySelector(".h1").innerHTML = h1Texts[currentIndex];
  }
  // Gasp animation for next section components
  gsap.to(".logo", {
    opacity: 1,
    duration: 1,
    color: logoColors[currentIndex]
  });
  gsap.from(".h1", { y: "20%", opacity: 0, duration: 0.5 });
  gsap.from(".fruit-image ", { y: "-100vh", delay: 0.4, duration: 0.4 });

  // Disable the nextButton if the last section is active
  if (currentIndex === h1Texts.length - 1) {
    nextButton.style.display = "none";
  }
  // Enable the prevButton if it's not the first section
  if (currentIndex > 0) {
    prevButton.style.display = "block";
  }
  // Button colors and animations
  nextButton.style.color = logoColors[currentIndex + 1];
  prevButton.style.color = logoColors[currentIndex - 1];
  nextButton.style.animationName = keyframes[currentIndex + 1];
  prevButton.style.animationName = keyframes[currentIndex - 1];
});
// Add event listeners to the buttons
prevButton.addEventListener("click", () => {
  if (currentPosition < 0) {
    currentPosition += 100;
    // Update the left position of the cane-labels
    caneLabels.style.left = `${currentPosition}%`;
    sectionContainer.style.left = `${currentPosition}%`;
    sectionContainer.style.transition = `all 0.5s ease-in-out`;
  }
  // Decrement index and currentIndex
  currentIndex--;
  if (currentIndex >= 0) {
    document.querySelector(".h1").innerHTML = h1Texts[currentIndex];
  }
  // Gasp animation for previous section components
  gsap.to(".logo", { color: logoColors[currentIndex], duration: 1 });
  gsap.from(".h1", { y: "20%", opacity: 0, duration: 0.5 });
  gsap.from(".fruit-image ", { y: "100vh", delay: 0.5 });
  // Enable the nextButton if it was disabled
  nextButton.style.display = "block";
  // Disable the prevButton if it's the first section
  if (currentIndex === 0) {
    prevButton.style.display = "none";
  }
  // Button colors and animations
  nextButton.style.color = logoColors[currentIndex + 1];
  prevButton.style.color = logoColors[currentIndex - 1];
  nextButton.style.animationName = keyframes[currentIndex + 1];
  prevButton.style.animationName = keyframes[currentIndex - 1];
});
				
			

In conclusion, creating a Responsive GSAP Slider with Button Wave Effect has been a rewarding experience. By combining modern web technologies like HTML, CSS, JavaScript, and the GreenSock Animation Platform (GSAP), we’ve crafted an engaging user experience.

Responsive GSAP Slider Video Preview

Download Button

Share This Article
Leave a comment