기초부터 시작하는 코딩/Javascript

Javascript를 이용한 사이트 만들기! - 패럴랙스 효과사이트 만들기03

kebab00 2023. 5. 17. 21:54

728x90

- 스크롤을 할 때마다 정해둔 위치에 오면 사진과 함께 흰색/ 주황색 효과가 나타났다 사라집니다.

- 코드를 보시죠

<style>
    .reveal > div,
    .reveal > span {
        opacity: 0;
    }
    .reveal.show > div,
    .reveal.show > span {
        animation: opacity 1s linear forwards;
    }
    .reveal {
        position: relative;
    }
    .reveal::before {
        content: '';
        position: absolute;
        left: 0;
        top: 0;
        width: 0;
        height: 100%;
        background-color: #fff;
        z-index: 1;
    }
    .reveal.reveal-TWO::after {
        content: '';
        position: absolute;
        left: 0;
        top: 0;
        width: 0;
        height: 100%;
        z-index: 1;
        background-color: orange;
    }
    /* 1개 */
    .reveal.show::before {
        animation: reveal 1s cubic-bezier(0, 0.78, 0.58, 1);
    }
    .reveal.reveal-RTL.show::before {
        animation: reveal-RTL 1s cubic-bezier(0, 0.78, 0.58, 1);
    }
    .reveal.reveal-TTB.show::before {
        animation: reveal-TTB 1s cubic-bezier(0, 0.78, 0.58, 1);
    }
    .reveal.reveal-BTT.show::before {
        animation: reveal-BTT 1s cubic-bezier(0, 0.78, 0.58, 1);
    }
    /* 2개 */
    .reveal.show::after {
        animation: reveal 1s 0.5s cubic-bezier(0, 0.78, 0.58, 1);
    }
    .reveal.reveal-RTL.show::after {
        animation: reveal-RTL 1s 0.5s cubic-bezier(0, 0.78, 0.58, 1);
    }
    .reveal.reveal-TTB.show::after {
        animation: reveal-TTB 1s 0.5s cubic-bezier(0, 0.78, 0.58, 1);
    }
    .reveal.reveal-BTT.show::after {
        animation: reveal-BTT 1s 0.5s cubic-bezier(0, 0.78, 0.58, 1);
    }
    /* animation */
    @keyframes opacity {
        0%   {opacity: 0;}
        60%  {opacity: 0;}
        70%  {opacity: 1;}
        100% {opacity: 1;}
    }
    @keyframes reveal {
        0%   {width: 0;    left: 0;}
        50%  {width: 100%; left: 0;}
        80%  {width: 100%; left: 0;}
        100% {width: 0;    left: 100%;}
    }
    @keyframes reveal-RTL {
        0%   {width: 0;    left: auto; right: 0;}
        50%  {width: 100%; left: auto; right: 0;}
        80%  {width: 100%; left: auto; right: 0;}
        100% {width: 0;    left: auto; right: 100%;}
    }
    @keyframes reveal-TTB {
        0%   {width: 100%; height: 0;    top: 0;}
        50%  {width: 100%; height: 100%; top: 0;}
        80%  {width: 100%; height: 100%; top: 0;}
        100% {width: 100%; height: 0;    top: 100%;}
    }
    @keyframes reveal-BTT {
        0%   {width: 100%; height: 0;    bottom:0;    top: auto;}
        50%  {width: 100%; height: 100%; bottom:0;    top: auto;}
        80%  {width: 100%; height: 100%; bottom:0;    top: auto;}
        100% {width: 100%; height: 0;    bottom:100%; top: auto;}
    }
    .parallax__item__num,
    .parallax__item__title {
        display: none;
    }
</style>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
<script>
    // 만약 reveal클래스를 추가하면 자식요소에 span으로 감싸주기
    document.querySelectorAll("p.reveal").forEach(text => {
        text.innerHTML =  `<span>${text.innerHTML}</span>`;

    })

    function scroll(){
        let scrollTop = window.scrollY || window.pageYOffset;

        const reveals = document.querySelectorAll(".reveal");

        reveals.forEach(reveal => {
            let revealOffset = reveal.offsetTop + reveal.parentElement.offsetTop
            let revealDelay = reveal.dataset.delay;

            // if (scrollTop >= revealOffset - window.innerHeight){
            //     reveal.classList.add("show");
            // }
            if (scrollTop >= revealOffset - window.innerHeight){
                if(revealDelay == undefined){
                    reveal.classList.add("show");
                } else {
                    setTimeout(() => {
                        reveal.classList.add("show");
                    },revealDelay)
                }
            }
        });
        document.querySelector(".scroll span").innerText = Math.round(scrollTop)
        requestAnimationFrame(scroll)
    }
    scroll()
</script>

- CSS와 스크립트 부분입니다.

- 오늘은 특히 CSS부분이 많은데 천천히 보시죠

- 우선 스크립트 입니다.

- reveal 이라는 클라스가 있는 p태그 안의 글자를 span태그로 감싸주었습니다.

- 그리고 scroll이라는 함수를 만들고 requestAnimationFrame을 주어 첫 실행후 scroll이라는 함수가 초당60번 재생되게 만들어 주었습니다.

- 그리고 reveals라는 선택자를 만들어 모든 reveals를 선택한 뒤 forEach를 통해 함수를 실행시켜주었습니다.

- 먼저 reveal들 안에 있는 이미지 태그들의 높이 값을 구했습니다.

- 그냥 오프셋값을 넣으면 부모태그부터의 높이 값만 나오기 때문에 부모태그의 높이 값 + 부모태그부터 이미지태그의 높이값 해서 총 높이 값을 구해주었습니다.

- 그리고 해당 높이에 갔을 때 이미지에 show라는 클라스가 추가되며 원하는 효과가 CSS를 통해 발현됩니다.

- 그래서 CSS가 좀 많이 깁니다.

- 먼저 opacity:0을 주어 안보이다가 show가 붙으면 1이 되어 보이는 것부터 딜레이를 주어 순차적으로 나오게 하는 것까지 다양한 애니메이션 효과를 CSS를 통해 줄 수 있습니다.

- 끝!