본문 바로가기
Effect/Parallax Effect

패럴랙스 이펙트05

by 코딩 척척학사 2022. 9. 20.
728x90

패럴랙스 이펙트 5

이번 패럴랙스 효과는 스크롤이 내려가면 사진과 텍스트가 스크롤과 달리 움직이며 이질감을 주는 효과입니다. 이질감을 주는 방법을 알아볼까요?

HTML 코드

이번 패럴랙스는 메뉴 없이 컨텐츠로만 구성하였으며, scrollTop 정보를 볼 수 있는 info를 추가해주었습니다.

HTML 보기
<main id="parallax__cont">
    <div id="contents">
        <section id="section01" class="content__item">
            <span class="content__item__num">01</span>
            <h2 class="content__item__title">section1</h2>
            <figure class="content__item__imgWrap">
                <div class="content__item__img"></div>
            </figure>
            <p class="content__item__desc">질병은 입을 쫓아 들어가고 화근은 입을 좇아 나온다.</p>
        </section>
        <!-- //section01 -->
        .
        .
        .
    </div>
</main>
<!-- main -->

<aside id="parallax__info">
    <div class="scroll">scrollTop : <span>0</span>px</div>
</aside>
<!-- info -->

CSS 코드

이번 패럴랙스는 gsap를 활용하여 애니메이션을 주었기 때문에, 트랜지션 속성은 주석처리 해주었습니다.

CSS 보기

/* parallax__cont */
#parallax__cont {
    max-width: 1600px;
    width: 98%;
    margin: 0 auto;
    /* background-color: rgba(255,255,255,0.1); */
}
.content__item {
    width: 1000px;
    max-width: 70vw;
    margin: 30vw auto;
    /* background-color: rgba(255,255,255,0.3); */
    text-align: left;
    margin-right: 0;
    position: relative;
    padding-top: 9vw;
}
.content__item:nth-child(even) {      /* 2n: n은 변수, even: 짝수만 선택 */
    margin-left: 0;
    text-align: right;
}
.content__item:nth-child(even) .content__item__num {
    left: auto;  /*left 값 초기화 */
    right: -5vw;
}
.content__item__num {
    font-size: 35vw;
    font-family: 'Lato';
    font-weight: 100;
    position: absolute;
    left: -5vw;
    top: -13vw;
    opacity: 0.07;
    z-index: -2;
}
.content__item__title {
    font-weight: 400;
    text-transform: capitalize;     /* 첫글자만 대문자 */
}
.content__item__imgWrap {
    width: 100%;
    padding-bottom: 56.25%;
    background-color: #000;
    position: relative;
    overflow: hidden;
    z-index: -1;
}
.content__item__img {
    position: absolute;
    background-image: url(../assets/img/effect_img10-min.jpg);
    background-repeat: no-repeat;
    background-position: center center;
    width: 110%;
    background-size: cover;
    height: 110%;
    left: -5%;
    top: -5%;
    filter: saturate(0%);
    /* transition: all 1s; */
}
.content__item:nth-child(1) .content__item__img {
    background-image: url(../assets/img/effect_img10-min.jpg);
}
.content__item:nth-child(2) .content__item__img {
    background-image: url(../assets/img/effect_img09-min.jpg);
}
.content__item:nth-child(3) .content__item__img {
    background-image: url(../assets/img/effect_img08-min.jpg);
}
.content__item:nth-child(4) .content__item__img {
    background-image: url(../assets/img/effect_img07-min.jpg);
}
.content__item:nth-child(5) .content__item__img {
    background-image: url(../assets/img/effect_img06-min.jpg);
}
.content__item:nth-child(6) .content__item__img {
    background-image: url(../assets/img/effect_img05-min.jpg);
}
.content__item:nth-child(7) .content__item__img {
    background-image: url(../assets/img/effect_img04-min.jpg);
}
.content__item:nth-child(8) .content__item__img {
    background-image: url(../assets/img/effect_img03-min.jpg);
}
.content__item:nth-child(9) .content__item__img {
    background-image: url(../assets/img/effect_img02-min.jpg);
}
.content__item__desc {
    font-size: 4vw;
    line-height: 1.4;
    margin-top: -5vw;
    margin-left: -4vw;
    word-break: keep-all;
}
.content__item:nth-child(even) .content__item__desc {
    margin-left: auto;
    margin-right: -4vw;
}
@media(max-width: 800px) {
    #parallax__cont {
        margin-top: 70vw;
    }
}

#parallax__info {
    position: fixed;
    left: 20px;
    bottom: 20px;
    z-index: 2000;
    background-color: rgba(0,0,0,0.6);
    color: #fff;
    padding: 15px 20px;
    border-radius: 10px;
}

스크립트 요약

1. 스크롤 값을 구해, 스크롤이 내려감에 따라 이미지나 텍스트가 같이 움직이도록 합니다.
2. 구한 스크롤 값을 info에 나타냅니다.
3. 각각의 컨텐츠 구성요소가 스크롤 할 때 같이 움직이도록 합니다.
4. 스크롤 이벤트가 발생하면 해당 함수가 실행되도록 합니다.

전체 스크립트 보기
function scroll(){
    let scrollTop = window.pageYOffset || document.documentElement.scrollTop;

    document.querySelector("#parallax__info span").innerText = Math.ceil(scrollTop);

    document.querySelectorAll(".content__item").forEach(item => {
        const target1 = item.querySelector(".content__item__img");
        const target2 = item.querySelector(".content__item__desc");
        const target3 = item.querySelector(".content__item__num");

        let offset1 = (scrollTop - item.offsetTop) * 0.1;
        let offset2 = (scrollTop - item.offsetTop) * 0.15;
        let offset3 = (scrollTop - item.offsetTop) * 0.2;

        // target1.style.transform = `translateY(${offset1}px)`;
        // target2.style.transform = `translateX(${offset2}px)`;

        gsap.to(target1, {duration: .3, y: offset1, ease: "power4.out"});
        gsap.to(target2, {duration: .3, y: offset2});
        gsap.to(target3, {duration: .3, y: offset3, ease: "expo.out"});
    });

    requestAnimationFrame(scroll);
}
scroll();

스크립트 뜯어보기

스크립트를 차근차근 뜯어보며 이해해 봅시다!

> 함수 작성하기
: scroll이라는 함수를 작성하고 실행문도 함께 작성해 줍니다. 이 함수는 스크롤 이벤트가 발생할 때마다 실행시킬 예정입니다.

function scroll(){};
scroll();

> scroll 함수 실행문 작성 01
: scrollTop 변수를 만들어 스크롤 값을 구해 저장해 줍니다. 이번에는 간단히 두개만 저장해 주었습니다.

변수에 하나 이상의 값을 모두 저장하는 이유
⇒ 특정 브라우저에서 호환성의 문제로 앞의 값을 불러오지 못할 때, 대안으로 뒤의 값을 불러오기 위함입니다.
let scrollTop = window.pageYOffset || document.documentElement.scrollTop;

> scroll 함수 실행문 작성 02
: scrollTop 값을 보여줄 info 요소의 글씨가 들어가는 부분을 선택하고, innerText를 이용해 scrollTop 값을 넣어줍니다.

Math.ceil() ?
⇒ 소수점까지 보이지 많도록 값을 올림하여 줍니다.
document.querySelector("#parallax__info span").innerText = Math.ceil(scrollTop);

> scroll 함수 실행문 작성 03
: 모든 컨텐츠 요소를 선택하여, forEach문을 통해 스크롤 이벤트가 발생할 때마다 각 요소가 같이 움직이는 애니메이션이 실행되도록 합니다.

forEach문 뜯어보기
item?
⇒ ForEach의 대상인 .content__item들 각각의 요소를 의미합니다.(section01, section002, …)

target1~3 ?
⇒ 각각 해당 섹션의 이미지, 텍스트, 번호 요소를 선택합니다.

offset1~3 ?
⇒ 만약 섹션의 크기가 window의 크기와 정확히 일치한다면, (scrollTop - item.offsetTop)의 값은 0이 됩니다. 그러나 그런 경우는 거의 없기 때문에 어떤 값이 나타나게 되고, 그 값에 0.1 등을 곱하게 되면 스크롤이 100만큼 움직일 때 요소는 1만큼 움직이게 되며 이질감을 주게 됩니다. 곱한 값이 클수록 빨리(많이) 움직이게 됩니다.

gsap.to(~) ?
⇒ gsap.to(대상 요소, {애니메이션 속성});
- duration : 지속시간
- y : y축으로 이동
- ease : 전환 효과
document.querySelectorAll(".content__item").forEach(item => {
    const target1 = item.querySelector(".content__item__img");
    const target2 = item.querySelector(".content__item__desc");
    const target3 = item.querySelector(".content__item__num");

    let offset1 = (scrollTop - item.offsetTop) * 0.1;
    let offset2 = (scrollTop - item.offsetTop) * 0.15;
    let offset3 = (scrollTop - item.offsetTop) * 0.2;

    // target1.style.transform = `translateY(${offset1}px)`;
    // target2.style.transform = `translateX(${offset2}px)`;

    gsap.to(target1, {duration: .3, y: offset1, ease: "power4.out"});
    gsap.to(target2, {duration: .3, y: offset2});
    gsap.to(target3, {duration: .3, y: offset3, ease: "expo.out"});
});

> scroll 함수 실행문 작성 04
: requestAnimationFrame() 메서드를 이용해, 스크롤 이벤트가 발생하면 scroll 함수를 실행하도록 합니다.

requestAnimationFrame() ?
⇒ requestAnimationFrame() 메서드는 addEventListener()의 scroll과 같이 스크롤 이벤트를 발생시키는 메서드입니다. 그러나, 브라우저에 최적화 되어 있기 때문에 addEventListener()보다 훨씬 부드럽고 가볍다는 장점이 있습니다.
재귀함수
⇒ 이 스크립트의 경우처럼, 어떤 함수 안에 그 함수 자신의 실행문이 존재하는 것을 재귀함수라고 합니다.
requestAnimationFrame(scroll);

> 완성 페이지 보기

728x90

'Effect > Parallax Effect' 카테고리의 다른 글

패럴랙스 이펙트07  (1) 2022.10.20
패럴랙스 이펙트06  (4) 2022.09.29
패럴랙스 이펙트04  (2) 2022.09.18
패럴랙스 이펙트03  (7) 2022.09.10
패럴랙스 이펙트02  (3) 2022.09.10

댓글


HTML이 적힌 썸네일 이미지
CSS가 적힌 썸네일 이미지
JAVASCRIPT가 적힌 썸네일 이미지

JAVASCRIPT

자세히 보기