웹솔루션개발 22년 노하우! 해피CGI의 모든것

[해피CGI][cgimall] Responsive GSAP Slider with Button Wave Effect 본문

웹프로그램밍 자료실/HTML 자료

[해피CGI][cgimall] Responsive GSAP Slider with Button Wave Effect

해피CGI윤실장 2024. 6. 26. 09:09






버튼 웨이브 효과가 있으며 반응형 슬라이드 입니다.

자세한 내용은 데모사이트 주소에서 확인이 가능합니다.


HTML

 
<body>
  <!-- header -->
  <header>
    <h2 class="logo">
      Fruity
    </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 class="h1">Pear</h1>
      <div class="cane-image ">
       
       
      </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">
           
pear-image
           
pear-image
           
pear-image
           
pear-image
          </div>
        </section>
        <section class="section" id="section2">
          <div class="fruit-images">
           
apple-image
           
apple-image
           
apple-image
           
apple-image
          </div>
        </section>
        <section class="section" id="section3">
          <div class="fruit-images">
           
exotic-image
           
exotic-image
           
exotic-image
           
exotic-image
          </div>
        </section>
      </div>
    </div>
  </main>
</body>
 


CSS

 
/* 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%);
  -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;
  }
}
 
 
 


JS

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];
});
 

 

 

Comments