반응형
Notice
Recent Posts
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Today
Total
관리 메뉴

오식랜드

[javascript motion] 스크롤 반응 모션 본문

dev-log/html·css·js

[javascript motion] 스크롤 반응 모션

개발하는 오식이 2021. 4. 30. 16:56
반응형

여러 요소에 공통 모션

1. 요소의 위치 절대값을 구해서 배열에 모은다.

2. 요소의 위치가 scrollY값을 넘게 되면 style을 수정해준다.

3. css에서 transition으로 모션의 속도를 조정해준다

4. eleOffset에 -600 등 으로 모션 실행 오프셋을 조정해준다.

scroll motion  demo1

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>scroll motion</title>
    <style>
        body{
            width: 100%;
            background-color: rgb(77, 175, 255);
        }
        .title{
           width: 100%;
           opacity: 0;
           transform: translatey(50px);
           transition: all 0.5s;
           font-size: 30px;
           margin: 400px;
           text-align: center;
           color: #fefefe;
        }
    </style>
</head>
<body>
    <h1 class="title">제목1</h1>
    <h2 class="title">제목2</h2>
    <h2 class="title">제목3</h2>

     
    <script>
        window.addEventListener('scroll', function(){
            scrollMotion()
        });

        function scrollMotion(){
            const ele = document.querySelectorAll('.title');
            let eleOffsetArr = [];

            ele.forEach(e => {
                let eleOffset = e.getBoundingClientRect().top + window.pageYOffset - 300;
                eleOffsetArr.push(eleOffset)
                console.log(eleOffset)
            });
            
            eleOffsetArr.forEach((offset, idx) => {
                    ele[idx].style.cssText = ( window.scrollY > offset 
                    ? 'opacity:1; transform: translateY(0);'
                    : 'opacity:0; transform: translateY(50px);' )
            });
        }
    </script>

</body>
</html>

 

한 요소에 도달했을 때, 요소와 밀접한 다른 요소의 연속 모션

위와 같은 코드에서

ele2를 넣어주고, 모션이 실행되는 forEach문 안에 setTimeout안에 ele2의 모션을 넣어준다.

0.2초의 간격을 주며 연속적으로 일어나게 하면 된다.

scroll motion demo2

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>scroll motion</title>
    <style>
        body{
            background-color: rgb(77, 175, 255);
            width: 100%;
        }
        div{
            position: relative;
            height: 500px;
            width: 100%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            margin: 400px;
        }
        .title{
           opacity: 0;
           transform: translatey(50px);
           transition: all 0.5s;
           font-size: 30px;
           color: #fefefe;
        }
        img{
            width: 240px;
            height: 300px;
            opacity: 0;
            transform: translateX(-100px);
            transition: all 0.5s;
        }
    </style>
</head>
<body>
    <div>
        <h1 class="title">Woody</h1>
        <img src="img/image1.jpg" alt="" class="images">
    </div>
    <div>
        <h2 class="title">Buzz Lightyear</h2>
        <img src="img/image2.jpg" alt="" class="images">
    </div>
    <div>
        <h2 class="title">Bo Peep</h2>
        <img src="img/image3.jpg" alt="" class="images">
    </div>



     
    <script>
        window.addEventListener('scroll', function(){
            scrollMotion()
        });

        function scrollMotion(){
            const ele = document.querySelectorAll('.title'),
            ele2 = document.querySelectorAll('.images');
                    
            let eleOffsetArr = [];

            ele.forEach(e => {
                let eleOffset = e.getBoundingClientRect().top + window.pageYOffset - 300;
                eleOffsetArr.push(eleOffset)
            });
            
            eleOffsetArr.forEach((offset, idx) => {
                if( window.scrollY > offset ){
                    ele[idx].style.cssText = 'opacity:1; transform: translateY(0);'
                    setTimeout(function () {
                        ele2[idx].style.cssText = 'opacity:1; transform: translateX(0)';
                    }, 200);
                }else{
                    ele[idx].style.cssText = 'opacity:0; transform: translateY(50px);'
                    setTimeout(function () {
                        ele2[idx].style.cssText = 'opacity:0; transform: translateX(-100px)';
                    }, 200);
                }
            });
        }
    </script>

</body>
</html>

 

한 요소에 도달했을 때 연속으로 여러개 나타나기

title들이 연속적으로 나타나야 할 때

1. 제일 첫번째 요소를 통해 offset을 구한다.

2. 요소들을 n초 x 요소의 index 초씩 딜레이를 준다.

 

이것은 TweenMax의 staggerTo와 같은 모션을 나타내준다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>scroll motion</title>
    <style>
        body{
            width: 100%;
            background-color: rgb(77, 175, 255);

            padding-top: 500px;
            padding-bottom: 1000px;
        }
        .title{
           width: 100%;
           opacity: 0;
           transform: translatey(50px);
           transition: all 0.5s;
           font-size: 30px;
           margin: 40px;
           text-align: center;
           color: #fefefe;
        }
    </style>
</head>
<body>
    <h1 class="title">제목1</h1>
    <h2 class="title">제목2</h2>
    <h2 class="title">제목3</h2>
    <h2 class="title">제목4</h2>

     
    <script>
        window.addEventListener('scroll', function(){
            scrollMotion()
        });

        function scrollMotion(){
            const ele = document.querySelectorAll('.title'),
      		      eleOffset = ele[0].getBoundingClientRect().top + window.pageYOffset - 300;

            if(window.scrollY > eleOffset){
                ele.forEach((ele, idx) => {
                setTimeout(() => {
                    ele.style.cssText = 'opacity: 1; transform: translateY(0);'
                }, 180*idx);
                });
            }else{
                ele.forEach((ele, idx) => {
                setTimeout(() => {
                    ele.style.cssText = 'opacity: 0; transform: translateY(50);'
                }, 180*idx);
                });
            }
        }
    </script>

</body>
</html>
반응형
Comments