• 지금의 나

    2022. 9. 19.

    by. 고구마달랭이

    얼마나 자주 올릴지는 모르겠지만 갑자기 생각나서 쓰러왔당 ㅎㅎ

    아무거나 쓰다 보면 기록하는 습관이 늘지 않을까 하고 ~ ~ ~

    Three.js 프로젝트도 얼른 올리고 싶은데 차근차근.. 언젠간 올리겠지? ?

     

    그래서 오늘 쓸 건 아이폰 새로 나온 기념으루다가

    간단하게 연습해본 에어팟프로2 스크롤 기반 인터랙션이당

    나중의 내가 지금 쓴 코드를 보면 어떤 생각이 들깝 ㅎㅎㅎ

     

    내 에어팟 왼쪽 이상해서 교체받아야되는뎅 온제받지

    아이폰 출시할 때 마다 느끼는 건데

    나는 폰 욕심은 진짜 없는고같당

    아직 XR 쓰는 중인데 너무 튼튼해 내 엑스알 최고

    암텅 ~~

     

     


     

        <section class="section01">
            <article>
                <span class="same">완전히 새로운</span>
                <h2 class="text">AirPodsPro</h2>
                <p class="text">듣는다는 것을 다시 생각하다.</p>
                <div class="same">
                    <p>출시일은 추후 공개됩니다.</p>
                    <ul>
                        <li><a href="/">동영상 시청하기</a></li>
                        <li><a href="/">이벤트 시청하기</a></li>
                    </ul>
                </div>
                <figure>
                    <img src="../img/airpod-sequence/0.png" alt="airpod img">
                </figure>
            </article>
        </section>
        <section class="section02"></section>
        <section class="section03"></section>

    우선 HTML은 대충 요렇게 ~!~!

    연습용으로 후다닥 만들어서 지저분하지만..🙈

     

    섹션당 높이는 100vh를 줬고

    section01에는 300vh를 줬다! 스크롤 해야하니까 ~~

     

    이제 나의 작고 귀여운 Javascript Time^ㅇ^

     

     


     

     

    1. scrollY값 구하기

        let scrollTop = 0;
    
        addEventListener('scroll', () => {	// document.addEvent~ -> document 생략
            scrollTop = scrollY;	// window.scrollY -> window 생략
        });

    가장 먼저 스크롤값을 구해야겠찌 ? ? 당연함

     

     


     

     

    2. 사용할 변수들과 애니메이션에 필요한 수치들을 객체에 정리

    const sceneInfo = {
    
      objs : {  // 인터랙션에 필요한 대상들! 클래스 모음집이라 생각하면 편함
        section01_el : document.querySelector('.section01'),
        section01_title : document.querySelector('.section01 h2'),
        section01_txt : document.querySelector('.section01 p'),
        section01_eyebrow : document.querySelectorAll('.section01 .same'),
        section01_img : document.querySelector('.section01 img')
      },
    
      values : {  // 수치시작점, 수치끝점, {비율시작점, 비율끝점}
        titleScale : [1, 1.2, {start: 0, end: 0.7}], // 비율의 0부터 0.7까지 scale(1) -> scale(1.2)로 주겠다는 뜻
        titleOpacity : [1, 0, {start: 0.3, end: 0.6}],
    
        textScale : [0.8, 1, {start: 0.65, end: 0.8}],
        textOpacityIn : [0, 1, {start: 0.65, end: 0.8}],
        textOpacityOut : [1, 0, {start: 0.8, end: 0.9}],
    
        eyebrowOpacity : [1, 0 , {start: 0.18, end: 0.4}],
    
        imgCount : [0, 29, {start: 0, end: 0.8}],
        imgScale : [1, 5, {start: 0, end: 0.8}],
        imgTranslateY : [20, 100, {start: 0, end: 0.8}],
      },
    };

    이건 따로 설명할 게 없당

    구냥 말 그대로 여러가지 정보들을 담아 놓는 곳~! 찾기 편하게용

    음.. 책에 필요한 부분 마다 라벨 붙여 놓은 너낌..?

     

     


     

     

    3. 스타일 주는 함수 만들고 섹션 scrollY와 비율 구하기

    let scrollTop = 0;
    
    addEventListener('scroll', () => {	// document.addEvent~ -> document 생략
        scrollTop = scrollY; // window.scrollY -> window 생략
        addStyle(scrollTop) // 스크롤 이벤트 함수에서 구한 scrollY값을 style함수에 인자로 넘겨줌
    });
    
    
    const objs = sceneInfo.objs; // 객체에서 가져올 건데 길게 쓰기 귀찮으니까 변수에 담아줌
    const values = sceneInfo.values;
    
    let sectionScrollY, sectionScrollRatio;
    
    function addStyle(scroll){ // 인자로 받은 scrollY를 style함수에선 scroll이라 부를고임
        sectionScrollY = Math.max(0, (scroll - objs.section01_el.offsetTop));
        sectionScrollRatio = Math.min(1, (sectionScrollY / (objs.section01_el.offsetHeight - innerHeight)));
    };

    왜 Math.max를 썼냐면!!

    우선 지금 내가 만드는 구간은 첫 섹션인 section01이기 때문에 scrollY 또한 0에서 시작하지만

    예시로 높이가 100px인 section들 중 두 번째인 section02의 scrollY를 구해보잡

     

    sectionScrollY = scroll - section02.offsetTop을 하게 되면??

    sectionScrollY의 값은 -100 부터 시작하다 section02의 offsetTop에 닿는 순간 부터 0이 되겠징?

    좌: 최댓값 0 설정 안 한 예시 속 section02의 scrollY / 우: 최솟값 1 설정 안 한 ratio

    내가 필요한 건

     

    1. 인터랙션을 줄 섹션의 scrollY를 0으로 만들어주기

    2. 그 섹션의 스크롤 비율(0 ~ 1) 구하기 ~! 별표★

     

    때문에 0 이하의 숫자는 버리는 것

    마찬가지로 Ratio도!! 스크롤을 계속 내리면

    아래에 더 있는 섹션들 만큼 ratio 수치가 쭉쭉 올라갈테니까 최대치를 1로 잡아준 것이당~~

     

     


     

     

    4. 스타일 함수에 스타일 넣어주기(?)

    function addStyle(scroll){
        sectionScrollY = Math.max(0, (scroll - objs.section01_el.offsetTop));
        sectionScrollRatio = Math.min(1, (sectionScrollY / (objs.section01_el.offsetHeight - innerHeight)));
    
        if(sectionScrollRatio < values.titleScale[2].end + 0.02){
        	objs.section01_title.style.transform = `scale(${calcValue(sectionScrollY, values.titleScale, objs.section01_el)})`
        }
    };

    코드 길어지면 괜히 읽기 싫어지니까 ㅎㅎ~~ 우선 하나만 줘보장

    sectionScrollRatio는 0~1 이니까! 요게

    객체에 내가 미리 넣어둔 titleScale의 end 즉 0.7 보다 작을 때 까지만 스타일을 바꾸라는 말!

     

    뒤에 + 0.02는 뭐냐면 마우스 휠을 굴릴 때 ratio를

    0.00001, 0.00002, 0.00003 이렇게 정확!!하게 잡아주지 않기 때문에

     오차범위(?)를 안전빵으로 넣어준 것이당~ 0.02 정도 넣어주면 대충 잘 잡힌다 ㅎㅎ

     

    헉 근데 scale()안에 숫자가 아니라 calcValue() 함수가 들어있다! !!

    세 개의 인자도 가지고 있지롱

    요게 뭐냐면 ~ ~ ~

     

     


     

     

    5. 범위 자동 계산 함수 만들기

    let start, end, range, rangeY, rangeRatio; 
    
    function calcValue(scroll, value, el){
        start = (el.offsetHeight - innerHeight) * value[2].start; // 인터랙션 시작점
        end = (el.offsetHeight - innerHeight) * value[2].end; // 인터랙션 끝점
        range = end - start; //애니메이션범위
        rangeY = Math.max(0, (scroll - start)); // 범위의 스크롤Y
        rangeRatio = Math.min(1, (rangeY / range)); // 범위의 비율
    
        styleVal = rangeRatio * (value[1] - value[0]) + value[0]; // 스타일값
    
        return styleVal;
    };

    어떻게 설명을 쓰지?? 움. .. 예를 들어서

    스크롤이 AirPodsPro 구간에 닿을 때 인터랙션을 주기 위해선

    해당 구간의 scrollY랑 ratio를 또 구해야겠지!?

    높이가 100px인 element에 시작점 0.2를 곱하면~?~? 또, 끝점 0.3을 곱하면 ~??

    start = 20px, end = 30px 짜잔 ~~

     

    아까 위에선 offsetTop으로 구했던 방식이

    element에 비율을 곱하는 방식으로 조금 달라졌을 뿐 같은 공식이당

     

    styleVal은 내가 부여하는 스타일 값 그대로를 계산한 건데

    매개변수로 받아와서 계산한 스타일값을

    리턴해줘야 하니까 선언해준 것이당 ~~

    자판기에 동전 넣으면 음료수 나오자나?

    calcValue()에 scroll, value, el 넣었더니 styleVal 나온겨 ~~ 와아

     

    calcValue 함수 없이도 직접 계산식을 쓰면서

    노가다로 수치를 넣어줄 순 있지만

    그러면 코드도 길어지고 귀찮자낭

    알아서 계산해주는 착한 calcValue() ^ㅇ^

     

    objs.section01_title.style.transform = `scale(${calcValue(sectionScrollY, values.titleScale, objs.section01_el)})`

    그럼 다시 이 부분을 보며 calcValue가 어떻게 쓰였나 ~~ 생각해보깅 ㅎㅇㅎ

    이러면 끝이다! 스크롤 수치에 맞춰 스타일 수치 주기 끝!

     

    근데 만약 scale이 0.4 ~ 0.8 구간 동안 커지기만 하는데

    같은 구간 동안에 opacity가 0에서 1됐다가 다시 0이 되길 원한다면 !?

    if(sectionScrollY < values.opacityIn_02[2].end + 0.02){
    	objs.overview02_txt[1].style.opacity = `${calcValue2(currentPageScrollVal, values.opacityIn_02, objs.overview02_el)}`
    }else{
    	objs.overview02_txt[1].style.opacity = `${calcValue2(currentPageScrollVal, values.opacityOut_02, objs.overview02_el)}`
    }

    간단함ㅋ else로 주면 된당ㅎㅎ

    하지만 sceneInfo에서 수치를 잘 맞춰줘야게찌 ??

     

     


     

     

    6. 마지막으로 초간단 이미지 시퀀스

    if(sectionScrollY < values.imgScale[2].end + 0.02){
        objs.section01_img.style.transform = `translateY(-${calcValue(sectionScrollY, values.imgTranslateY, objs.section01_el)}%) scale(${calcValue(sectionScrollY, values.imgScale, objs.section01_el)})`
        objs.section01_img.src = `../img/airpod-sequence/${Math.floor(calcValue(sectionScrollY, values.imgCount, objs.section01_el))}.png`
    }

    여러장의 이미지를 스크롤에 맞춰 보여주며

    애니메이션 처럼 보이게 하는 기법~!

    나는 총 30장의 이미지라 imgCount = 30이라고 주었당

    스타일 주는 것 처럼 src에 넣어주면 끝!

    정수로 떨어져야 하니까 Math.floor 주는 거 잊지말기 ~~

     

     


     

     

    완성작 ^_^ ㅋㅋㅋㅋㅋㅋㅋㅋ

    ㅋ ㅋㅋㅋ ㅋㅋㅋ ㅋㅋㅋㅋ 아

    수치도 대강 때려 맞춰서 넣고.. 느낌대로 한거라

    영 볼품없지만은 ㅎㅎ ㅋㅋ ㅋ ㅋㅋㅋ

    이게 지금 나의 최선이어따..

    난 이것도 만족해!! 앞으로 경험치 쌓고 레벨업하면 되찌~!!!!

    내 눈엔 이것도 나름 예뿌다 히 히

     

    우와 근데 맨날 일기나 써봤지 이런 건 처음 써봐서 그른가??

    짱어렵다 !!! 설명글 쓰는 건 되게 어려운 거구나! !!

    설명이 아주 많이 생략된 누낌 ^ㅇ^

    쓸데 없는 설명은 또 많은 누낌 ^ㅇ^

     

    딱 한 섹션만 한 건데두... ㅎㅎ 어렵따

    그래도 다음 섹션은 간단하니까 짧게 쓸 수 있을거같당~~

    언제 또 쓰러올지가 의문이지만 히히

     

    지금은 반복되는 코드도 많고 잘 정리가 안되어있어서

    코드를 왔다갔다 하면서 봐야되는데

    다다음 글이나 다다다음 글 쯤에선

    더 정리가 잘 된 함수로 다른 섹션 정리글 쓰지 않을까 싶네욤 ~ ~

     

    아 일기도 쓰고싶당 할 말 짱 많은데 ㅜㅇㅜ

    잊기 싫은 것만 간단하게 캘린더에 쓰고이따 호호

     

    근데 왜 아직도 월요일? 얼룬 토요일 됐으면 좋겠당~~~ 두근두근

    '🦄' 카테고리의 다른 글

    카메라 가지고 놀기 1탄  (6) 2022.10.04
    벌써 10월  (0) 2022.10.01
    🔗  (0) 2022.09.22

    댓글