inflearn logo
강의

Khóa học

Chia sẻ kiến thức

Bản sao tương tác trang web của Apple!

chi tiết ứng dụng main.js

안녕하세요. 실행 오류가 뜨는데 질문드립니다

522

tprkd230605

12 câu hỏi đã được viết

0

(() => {
    let yOffset = 0; //window.pageOffset 대신 쓸 수 있는 변수
    let prevScrollHeight = 0 // 현재 스크롤 (yOffset)보다 이전에 위치한 스크롤 높이값의 함
    let currentScene = 0; // 현재 활성화된 (눈앞에 보고 있는) 씬(scroll-section)
    let enterNewScene = false;

    const sceneInfo = [
        {
            // 0
            type: 'sticky',
            heightNum: 5, //브라우저 높이의 5배로 scrollheight 세팅
            scrollHeight: 0,
            objs: {
                container: document.querySelector('#scroll-section-0'),
                messageA: document.querySelector('#scroll-section-0 .main-message.a'),
                messageB: document.querySelector('#scroll-section-0 .main-message.b'),
                messageC: document.querySelector('#scroll-section-0 .main-message.c'),
                messageD: document.querySelector('#scroll-section-0 .main-message.d')
            },
            values: {
                // 글자 구간과 선명도를 지정 하는 역할
                messageA_opacity_in: [0, 1, { start: 0.1, end: 0.2 }],
                messageB_opacity_in: [0, 1, { start: 0.3, end: 0.4 }],
                messageC_opacity_in: [0, 1, { start: 0.5, end: 0.6 }],
                messageD_opacity_in: [0, 1, { start: 0.7, end: 0.8 }],



                messageA_translate_in: [20, 0, { start: 0.1, end: 0.2 }],
                messageB_translate_in: [20, 0, { start: 0.3, end: 0.4 }],
                messageC_translate_in: [20, 0, { start: 0.5, end: 0.6 }],
                messageD_translate_in: [20, 0, { start: 0.7, end: 0.8 }],



                messageA_opacity_out: [1, 0, { start: 0.25, end: 0.3 }],
                messageB_opacity_out: [1, 0, { start: 0.45, end: 0.5 }],
                messageC_opacity_out: [1, 0, { start: 0.65, end: 0.7 }],
                messageD_opacity_out: [1, 0, { start: 0.85, end: 0.9 }],


                messageA_translate_out: [0, -20, { start: 0.25, end: 0.3 }],
                messageA_translate_out: [0, -20, { start: 0.45, end: 0.5 }],
                messageA_translate_out: [0, -20, { start: 0.65, end: 0.7 }],
                messageA_translate_out: [0, -20, { start: 0.85, end: 0.9 }],
            }
        },
        {
            // 1
            type: 'normal',
            // heightNum: 5, //브라우저 높이의 5배로 scrollheight 세팅
            scrollHeight: 0,
            objs: {
                container: document.querySelector('#scroll-section-1')
            }
        },
        {
            // 2
            type: 'sticky',
            heightNum: 5, //브라우저 높이의 5배로 scrollheight 세팅
            scrollHeight: 0,
            objs: {
                container: document.querySelector('#scroll-section-2'),
                messageA: document.querySelector('#scroll-section-2 .a'),
                messageB: document.querySelector('#scroll-section-2 .b'),
                messageC: document.querySelector('#scroll-section-2 .c'),
                pinB: document.querySelector('#scroll-section-2 .b .pin'),
                pinC: document.querySelector('#scroll-section-2 .c .pin'),
            },
            values: {
                messageA_translateY_in: [20, 0, { start: 0.15, end: 0.2 }],
                messageB_translateY_in: [30, 0, { start: 0.6, end: 0.65 }],
                messageC_translateY_in: [30, 0, { start: 0.87, end: 0.92 }],
                messageA_opacity_in: [0, 1, { start: 0.25, end: 0.3 }],
                messageB_opacity_in: [0, 1, { start: 0.6, end: 0.65 }],
                messageC_opacity_in: [0, 1, { start: 0.87, end: 0.92 }],
                messageA_translateY_out: [0, -20, { start: 0.4, end: 0.45 }],
                messageB_translateY_out: [0, -20, { start: 0.68, end: 0.73 }],
                messageC_translateY_out: [0, -20, { start: 0.95, end: 1 }],
                messageA_opacity_out: [1, 0, { start: 0.4, end: 0.45 }],
                messageB_opacity_out: [1, 0, { start: 0.68, end: 0.73 }],
                messageC_opacity_out: [1, 0, { start: 0.95, end: 1 }],
                pinB_scaleY: [0.5, 1, { start: 0.6, end: 0.65 }],
                pinC_scaleY: [0.5, 1, { start: 0.87, end: 0.92 }]
            }
        },
        {
            // 3
            type: 'sticky',
            heightNum: 5, //브라우저 높이의 5배로 scrollheight 세팅
            scrollHeight: 0,
            objs: {
                container: document.querySelector('#scroll-section-3')
            }
        },
    ];

    function setLayout() {
        // 각 section 의 높이 세팅
        for (let i = 0; i < sceneInfo.length; i++) {
            if (sceneInfo[i].type === 'sticky') {
                sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight;
            } else if (sceneInfo[i].type === 'normal') {
                sceneInfo[i].scrollHeight = sceneInfo[i].objs.container.offsetHeight;
            }
            sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`
        }

        let totalScrollHeight = 0;
        yOffset = window.pageYOffset;
        // 새로고침 버튼 눌렀을때 그 씬 장면이 유지 될 수 있게 해주는 역할
        for (let i = 0; i < sceneInfo.length; i++) {
            totalScrollHeight += sceneInfo[i].scrollHeight;
            if (totalScrollHeight >= yOffset) {
                currentScene = i;
                break
            }
        }
        document.body.setAttribute('id', `show-scene-${currentScene}`)
    }







    function calcValues(values, currentYOffset) {
        let rv;
        //현재 씬(스크롤 섹션)애서 스크롤된 범위를 비율로 구하기
        const scrollHeight = sceneInfo[currentScene].scrollHeight;
        const scrollRatio = currentYOffset / scrollHeight;

        if (values.length === 3) {
            // start ~ end 사이에 애니메이션 진행 
            const partStart = values[2].start * scrollHeight
            const partEnd = values[2].end * scrollHeight
            const partScrollHeight = partEnd - partStart;

            if (currentYOffset <= partEnd && currentYOffset >= partStart) {
                rv = (currentYOffset - partStart) / partScrollHeight * (values[1] - values[0]) + values[0];
            } else if (currentYOffset < partStart) {
                rv = values[0];
            } else if (currentYOffset > partEnd) {
                rv = values[1];
            }

        } else {
            rv = scrollRatio * (values[1] - values[0]) + values[0];
        }

        return rv;

    }






    function playAinmation() {
        const objs = sceneInfo[currentScene].objs;
        const values = sceneInfo[currentScene].values;
        const currentYOffset = yOffset - prevScrollHeight;
        const scrollHeight = sceneInfo[currentScene].scrollHeight;
        const scrollRatio = currentYOffset / scrollHeight;

        // console.log(currentScene)
        switch (currentScene) {
            case 0:

                // calcValues = (values의 선명도, 현재 스크롤의 위치    

                if (scrollRatio <= 0.22) {
                    // in
                    objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset);
                    objs.messageA.style.transform = `translateY(${calcValues(values.messageA_translate_in, currentYOffset)}%)`;
                } else {
                    // out
                    objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset);
                    objs.messageA.style.transform = `translateY(${calcValues(values.messageA_translate_out, currentYOffset)}%)`;
                }

                if (scrollRatio <= 0.42) {
                    objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset);
                    objs.messageB.style.transform = `translateY(${calcValues(values.messageB_translate_in, currentYOffset)}%)`
                }

                else {
                    objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset);
                    objs.messageB.style.transform = `translateY(${calcValues(values.messageB_translate_out, currentYOffset)}%)`;
                }

                if (scrollRatio <= 0.62) {
                    objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset);
                    objs.messageC.style.transform = `translateY(${calcValues(values.messageC_translate_in, currentYOffset)}%)`
                }

                else {
                    objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset);
                    objs.messageC.style.transform = `translateY(${calcValues(values.messageC_translate_out, currentYOffset)}%)`;
                }
                if (scrollRatio <= 0.82) {
                    objs.messageD.style.opacity = calcValues(values.messageD_opacity_in, currentYOffset);
                    objs.messageD.style.transform = `translateY(${calcValues(values.messageD_translate_in, currentYOffset)}%)`
                }

                else {
                    objs.messageD.style.opacity = calcValues(values.messageD_opacity_out, currentYOffset);
                    objs.messageD.style.transform = `translateY(${calcValues(values.messageD_translate_out, currentYOffset)}%)`;
                }


                break;
            case 1:

                break;
            case 2:

                break;
            case 3:
                break;
        }
    }









    function scrollLoop() {
        enterNewScene = false
        prevScrollHeight = 0
        for (let i = 0; i < currentScene; i++) {
            prevScrollHeight += sceneInfo[i].scrollHeight;
        }
        if (yOffset > prevScrollHeight + sceneInfo[currentScene].scrollHeight) {
            enterNewScene = true
            currentScene++;
            document.body.setAttribute('id', `show-scene-${currentScene}`)
        }
        if (yOffset < prevScrollHeight) {
            enterNewScene = true
            if (currentScene === 0) // 브라우저 바운스 효과로 인해 마이너스가 되는 것을 방지
                return
            currentScene--;
            document.body.setAttribute('id', `show-scene-${currentScene}`)
        }

        // 마이너스 나오는 오류를 잡아주기 위한 역할
        if (enterNewScene) return;
        playAinmation()
    }
    window.addEventListener('scroll', () => {
        yOffset = window.pageYOffset;
        scrollLoop()
    });











    window.addEventListener('resize', setLayout);
    window.addEventListener('load', setLayout);


})()

svg 웹 디자인 javascript 인터랙티브-웹 HTML/CSS 클론코딩

Câu trả lời 4

0

tprkd230605

감사합니다 덕분에 해결 했어요

0

studiomeal

sceneInfo에 아래 부분이 전부다 A로 되어있네요- ABCD로 각각 바꾸어주시면 될거에요.

messageA_translate_out: [0, -20, { start: 0.25, end: 0.3 }],
messageA_translate_out: [0, -20, { start: 0.45, end: 0.5 }],
messageA_translate_out: [0, -20, { start: 0.65, end: 0.7 }],
messageA_translate_out: [0, -20, { start: 0.85, end: 0.9 }],

0

tprkd230605

2번째 문장은 나오는데 3번째 부터 스크롤 하면 저런 오류가 나옵니다 어떻게 해결 해야되나요??

0

tprkd230605

이미지 배경 문의

0

80

1

[크로스브라우징] safari에서 동영상 영역 미노출

0

123

1

항상 궁금했는데 크림슨 컬러 선택하셨을때 활용했던 사이트 좀 알려주세요~

0

130

2

vue강의는안하시나요?!

0

124

1

스크롤 속도에 따른 messageA_opacity_out

0

130

1

drawImage(objs.videoImages[sequence], 0, 0); error

0

94

1

선생님 캔버스 width 크기는 이미지 크기에맞게 해줘야하나요?

0

137

0

선생님 안녕하세요. 혹시 메인개발(?)분야가 뭔지 궁금합니다.

0

219

1

React에서 load 상태를 어떻게 감지할 수 있을까요?

0

699

1

[섹션7-3: 버그수정 2] tempYOffset 오류

0

207

1

스크롤할 때 캔버스로 하신 이유가 있으신가요? 그냥 성능 떄문에 캔버스로 하신건가요?

0

326

2

게속 오류떠서 글 작성해봐요....

0

531

2

Vanilla JavaScript로 SPA 만드는 자료 혹은 선택 기준을 추천해주실 수 있으신가요?

1

500

1

특정 타이밍 스크롤 애니메이션 적용하기 섹션 수강중입니다.

0

464

2

[#svg, #이미지프레임과 텍스트 싱크] 스크롤 값에 움직이는 svg path, 이미지프레임과 텍스트 싱크 맞추는 것, 2가지 질문이 있습니다.

0

460

2

페이지가 처음 로딩 되었을 때 애니메이션 처리가 되지 않는 느낌입니다

0

443

1

섹션2 번째, opacity=0 되지 않고 잔상이 남습니다.

0

538

1

원래 쿼리셀렉터에서는 띄워쓰기 하면안되나요?

0

605

2

라이브러리 질문

1

419

2

translateY대신 애플에서 사용한 것 처럼 matrix로 scale의 크기를 주려고 하는데

0

416

1

[스크롤 높이 세팅] scrollHeight값이 3990아닌 4645로만 나오는데 뭐가 문제일까요? ㅠㅠ

0

606

2

scrollLoop 함수 질문

0

482

2

도메인 웹호스팅시 이미지가 안 뜨는데 누가 좀 알려주세요ㅠㅜ

0

1242

2

load 이벤트시 첫 비디오 이미지가 뜨네요.

0

512

2