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

[해피CGI][cgimall] 스무스 텍스트 및 이미지 효과 Image Reveal animation on scroll without dependancies 본문

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

[해피CGI][cgimall] 스무스 텍스트 및 이미지 효과 Image Reveal animation on scroll without dependancies

해피CGI윤실장 2025. 4. 2. 09:10




마우스 스크롤 시 적용되는 텍스트, 이미지효과입니다.
응용하여 다양한 예제를 만들 수


HTML 구조

<div class='container'>

  <h2 class="fadeup">Cool cool cool</h2>

  <div class='reveal'>

    <div class="image-wrap">

     

https://images.unsplash.com/photo-1496865534669-25ec2a3a0fd3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=668&q=80'>

    </div>

  </div>

</div>

<div class='container'>

  <h2 class="fadeup">Cool cool cool</h2>

  <div class='reveal'>

    <div class="image-wrap">

     

https://images.unsplash.com/photo-1493552152660-f915ab47ae9d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=668&q=80'>

    </div>

  </div>

</div>

<div class='container'>

  <h2 class="fadeup">Cool cool cool</h2>

  <div class='reveal'>

    <div class="image-wrap">

     

https://images.unsplash.com/photo-1496198253360-4c44aa485f6c?ixlib=rb-1.2.1&auto=format&fit=crop&w=668&q=80'>

    </div>

  </div>

</div>

<div class='container'>

  <h2 class="fadeup">Cool cool cool</h2>

  <div class='reveal'>

    <div class="image-wrap">

     

https://images.unsplash.com/photo-1494058303350-0bd5a9ecc5d3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=668&q=80'>

    </div>

  </div>

</div>

 



CSS 소스

.container {

  display: grid;

  place-items: center;

  height: 100vh;

  width: 100%;

  position: relative;

}

 

.credit {

  position: fixed;

  top: 20px;

  right: 20px;

  font-family: Termina, sans-serif;

  font-weight: 800;

  font-size: 0.7rem;

}

 

.credit a {

  color: #1a292c;

  text-transform: lowercase;

}

 

.container:nth-child(2) {

  background: #3c564f;

}

.container:nth-child(1) {

  background: #b69187;

}

.container:nth-child(4) {

  background: #bcb8ad;

}

.container:nth-child(3) {

  background: #b6916d;

}

 

img {

  height: 100%;

  width: auto;

  max-width: 75vw;

  object-fit: contain;

}

 

h2 {

  font-family: Termina, sans-serif;

  font-weight: 800;

  text-transform: uppercase;

  -webkit-text-stroke: 2px white;

  text-stroke: 2px white;

  color: transparent;

  font-size: clamp(3rem, 10vw, 6rem);

  position: absolute;

  top: 25%;

  left: 5%;

  width: 90%;

  height: 50%;

  z-index: 99;

  display: grid;

  place-items: center;

}

 

body:not(.no-js) .image-wrap {

  transition: 1s ease-out;

  transition-delay: 0.2s;

  position: relative;

  width: auto;

  height: 80vh;

  overflow: hidden;

  clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0 100%);

  visibility: hidden;

}

 

body:not(.no-js) .image-wrap img {

  transform: scale(1.3);

  transition: 2s ease-out;

}

 

body:not(.no-js) .animating .image-wrap {

  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);

  visibility: visible;

  transform: skewY(0);

}

 

body:not(.no-js) .animating img {

  transform: scale(1);

  transition: 4s ease-out;

}

 

body:not(.no-js) .fadeup {

  opacity: 0;

  transition: 0.4s ease-out;

  transform: translateY(40px);

}

 

body:not(.no-js) .fading-up {

  opacity: 1;

  transition: 1s ease-out;

  transform: translateY(0px);

  transition-delay: 0.7s;

}

 


JS 소스

document.addEventListener("DOMContentLoaded", function () {

  const options = {

    root: null,

    rootMargin: "0px",

    threshold: 0.4

  };

 

  // IMAGE ANIMATION

 

  let revealCallback = (entries) => {

    entries.forEach((entry) => {

      let container = entry.target;

 

      if (entry.isIntersecting) {

        console.log(container);

        container.classList.add("animating");

        return;

      }

 

      if (entry.boundingClientRect.top > 0) {

        container.classList.remove("animating");

      }

    });

  };

 

  let revealObserver = new IntersectionObserver(revealCallback, options);

 

  document.querySelectorAll(".reveal").forEach((reveal) => {

    revealObserver.observe(reveal);

  });

 

  // TEXT ANIMATION

 

  let fadeupCallback = (entries) => {

    entries.forEach((entry) => {

      let container = entry.target;

      container.classList.add("not-fading-up");

 

      if (entry.isIntersecting) {

        container.classList.add("fading-up");

        return;

      }

 

      if (entry.boundingClientRect.top > 0) {

        container.classList.remove("fading-up");

      }

    });

  };

 

  let fadeupObserver = new IntersectionObserver(fadeupCallback, options);

 

  document.querySelectorAll(".fadeup").forEach((fadeup) => {

    fadeupObserver.observe(fadeup);

  });

});

 


해당 사이트로 이동해서 전체 소스를 확인하실 수 있습니다.

 

Comments