본문 바로가기
Web/JAVASCRIPT

Sticky를 활용해서 넘어가는 카드 UI 만들기 (애플 뮤직사이트)

by print_soo 2023. 8. 4.

결과물 미리보기

 

 

우선 해당 프로젝트를 진행하기 위해서는 Sticky라는 속성에 대해서 알아야한다. 

 

Sticky란 

: 스크롤이 되어서 해당 요소가 화면에 나오면 해당요소를 고정시킨다는 특징이 있는 속성이다.

: fixed와 뭐가 다르냐고 물으면 fixed는 항상 화면에 고정되는 특징이 있는 속성이지만 sticky는 스크롤이 되어 해당 요소가 화면에 나오면 해당 요소를 고정한다는 점이 다르다라고 할 수 있다.

 

sticky를 사용하려면 sticky 효과를 주고싶은 요소에 아래의 작업이 필요하다.

.box {
    position: sticky; /*포지션을 sticky로 설정*/
    top: 400px; /*sticky가 될 상단 위치를 정해준다.*/
}

💡 sticky가 될 위치를 정해주지 않으면 해당 속성을 실행되지 않는다!

 


프로젝트 

 

1. 뼈대 만들기 (HTML)

<div class="card-background">
    <h1 style="text-align: center;">
        <b>
            It's as easy 
            <br>
            as it sounds.
        </b>
    </h1>
    <div class="card-box">
        <img src="img/card1.png">
    </div>
    <div class="card-box">
        <img src="img/card2.png">
    </div>
    <div class="card-box">
        <img src="img/card3.png">
    </div>
</div>

 

 


 

2. CSS로 꾸며주기 + sticky 설정하기 

.card-background {
    height: 3000px;
    margin-top: 800px;
    margin-bottom: 1600px;
}

 

.card-box img {
    display: block;
    margin: auto;
    max-width: 80%;
}

 

.card-box {
    position: sticky;
    top: 400px;
    margin-top: 50px;
}

 

 

3. JS로 카드가 사라지고 줄어드는 효과 만들기

 

우선 스크롤 되는 동안 투명도가 올라가고 사이즈가 줄어드는 효과가 작동 되어야하기 때문에 이벤트 리스너 'scroll'을 만들어보자.

 

$(window).scroll(function () {
	var scrollHeight = $(window).scrollTop();
    console.log(scrollHeight);
}

 

 

 

이렇게 자바스크립트를 작성하고 콘솔창을 보면 스크롤하는 위치가 계속 출력된다. 

이제 지정한 시작 위치에서 첫 번째 카드 이미지의 속성이 변경되어 지정한 끝 위치에서 속성 변경이 끝나야한다. 

 

[시작 위치 : 400px]

첫 번째 카드 이미지가 고정되고 두 번째 카드 이미지가  움직이기 시작하는 때의 스크롤 정도에서 첫 번째 카드 이미지의 opacity와 scale은 1이 되어야한다.

 

[끝 위치 : 1020px]

첫 번째 카드 이미지가 두 번째 카드 이미지에 완전히 가려지는 스크롤 정도에서 첫 번째 카드 이미지의 opacity는 0이 되고  scale은 0.9가 되어야한다.

 

즉, 아래의 영상처럼 스크롤이 진행되는 동안 첫 번째 카드 이미지의 opacity는 1에서 0으로, scale은 1에서 0.9로 변경되어야 한다. 

 

따라서 우리는 스크롤 정도가 400 ~ 1020이 될 때 opacity는 1 ~ 0 scale은 1 ~ 0.9가 되게하는 가변적 Y를 구해야한다.

어떻게 y를 구해야할까?

💡 y = a*x+ b를 통해서 x를 스크롤 값이라 치고 y를 opacity, scale이라 치고 a와 b를 구해야한다. 

그래프로 시각화

 

 

 

y와 x에 각각 값을 넣어 아래 2개의 식을 만들고 이 방적식을 풀면 a와 b가 도출된다.

 

 

결국 a는 -1/620  b는 102/62 가 도출된다. 

 

따라서 y = -1/620*스크롤 정도 + 102/62라는 식이 나오게 된다. 이 식을 스크롤 이벤트 리스너에 넣고 css를 조정하면 스크롤에 따라 투명도가 변경되는 효과를 볼 수 있다. 

$(window).scroll(function () {
    var scrollHeight = $(window).scrollTop();
    var opacityValueOne = -((1/620)*scrollHeight) + (102/62)
    $('.card-box').eq(0).css('opacity', opacityValueOne);
});

투명도 변경 결과물

 

이런 방식으로 첫 번째 카드 이미지의 투명도와 크기를 조정하고 두 번째 카드 이미지의 투명도와 크기를 조정하면 맨 처음본 결과물을 볼 수 있다. 

 

 


 

최종 코드

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <link rel="stylesheet" href="main.css">

    <title></title>
</head>

<body>

    

    <div class="card-background">
        <h1 style="text-align: center;">
            <b>
                It's as easy 
                <br>
                as it sounds.
            </b>
        </h1>
        <div class="card-box">
            <img src="img/card1.png">
        </div>
        <div class="card-box">
            <img src="img/card2.png">
        </div>
        <div class="card-box">
            <img src="img/card3.png">
        </div>
    </div>

    <!-- jQeury install -->
    <script src="https://code.jquery.com/jquery-3.7.0.min.js"
        integrity="sha256-2Pmvv0kuTBOenSvLm6bvfBSSHrUJ+3A7x6P5Ebd07/g=" crossorigin="anonymous"></script>

    <!-- JavaScript -->
    <script>
        $(window).scroll(function () {
            var scrollHeight = $(window).scrollTop();
            var opacityValueOne = -((1/620)*scrollHeight) + (102/62)
            // var sizeValueOne = -((1/6200)*scrollHeight) + (66/62)
            console.log(scrollHeight);
        //     var opacityValueTwo = -((1/620)*scrollHeight) + (163/62)
        //     var sizeValueTwo = -((1/6200)*scrollHeight) + (721/620)

            $('.card-box').eq(0).css('opacity', opacityValueOne);
        //     $('.card-box').eq(0).css('transform', `scale(${sizeValueOne})`);
        //     $('.card-box').eq(1).css('opacity', opacityValueTwo);
        //     $('.card-box').eq(1).css('transform', `scale(${sizeValueTwo})`);
        });

    </script>

    <!-- bootstrap install -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous">
        </script>

</body>

</html>