월 15,400원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결애플 웹사이트 인터랙션 클론!
버그가 있는것 같아요`
화면상단에서 100px 정도 스크롤 한 상태에서 새로 고침 하면. 0번 째 씬 이미지 로드한 뒤 initAfterLoadImages() 를 호출하면서 화면이 스스륵 밀려 올라가는데, 0번 째 씬 로드 후 2번째 씬 이미지 마저 모두 로드되면 initAfterLoadImages()를 또한 번 호출 하면서 다시한번 스스륵 밀려 올라가네요~ 중복으로 올라가요~~ 추후에 시간이 되시면 개선 버전 파일도 올려주시면 좋을 것 같아요~
- 미해결애플 웹사이트 인터랙션 클론!
opacity_out 질문입니다
messageA_opacity_out이 실행이 안 되고 scrollRatio가 2.5일때 messageA가 사라집니다 (function () { let yOffset = 0; //window.pageYOffset 대신 쓸 변수 let prevScrollHeight = 0; //현재 스크롤 위치(yOffset)보다 이전에 위치한 스크롤 섹션들의 스크롤 높이값의 합 let currentScene = 0; //눈앞에 보고 있는 씬 let enterNewScene = false; //새로운 scene이 시작된 순간 true const sceneInfo = [ { //0 type: 'sticky', heightNum: 5, 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}], messageA_opacity_out:[1,0,{start : 0.25, end: 0.3}] } }, { //1 type: 'normal', heightNum: 5, scrollHeight: 0, objs:{ container:document.querySelector('#scroll-section-1') } }, { //2 type: 'sticky', heightNum: 5, scrollHeight: 0, objs:{ container:document.querySelector('#scroll-section-2') } }, { //3 type: 'sticky', heightNum: 5, scrollHeight: 0, objs:{ container:document.querySelector('#scroll-section-3') } } ]; //각 스크롤 섹션의 높이 세팅1 function setLayout() { for (let i = 0; i < sceneInfo.length; i++) { sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight; sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`; } // 현재씬을 자동으로 세팅하는 것 yOffset= window.pageYOffset; let totalScrollHeight = 0; for(let i = 0; i < sceneInfo.length; i++){ totalScrollHeight += sceneInfo[i].scrollHeight; //totalscrollheight가 yoffset 보다 커지면 현재 i를 currentscene으로 세팅하고 for문을 빠져나온다 if(totalScrollHeight >= yOffset){ currentScene = i; break; } } // 바디에다가 현재씬 갱신한 것 세팅,새로고침할 때 id를 잘 넣어준다 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 사이에 애니메이션 실행, values[2]는 start:0.1,end:0.2 const partScrollStart = values[2].start * scrollHeight; const partScrollEnd = values[2].end * scrollHeight; const partScrollHeight = partScrollEnd - partScrollStart; // 스크롤이 애니메이션 실행하는 사이에 있을 때 if(currentYOffset >= partScrollStart && currentYOffset <= partScrollEnd){ rv = (currentYOffset - partScrollStart) / partScrollHeight * (values[1] - values[0] + values[0]); } // 스크롤이 애니메이션 샐행하기전에 있을 때 else if(currentYOffset < partScrollStart){ rv = values[0]; } // 스크롤이 애니메이션 실행 후에 있을 때 else if(currentYOffset > partScrollEnd){ rv = values[1]; } }else{ rv = scrollRatio * (values[1] - values[0] + values[0]); } return rv; } function playAnimation(){ //container에서 가져온것 const objs = sceneInfo[currentScene].objs; const values = sceneInfo[currentScene].values; //현재 씬의 yoffset,씬이 넘어가면 그 씬이 yOffset을 새로 세팅해준다 const currentYOffset = yOffset - prevScrollHeight; const scrollHeight = sceneInfo[currentScene].scrollHeight; // 현재씬에서 얼마나 스크롤 했는지 비율이 나온다 const scrollRatio = currentYOffset / scrollHeight; console.log(scrollRatio); switch(currentScene){ case 0: const messageA_opacity_in = calcValues(values.messageA_opacity_in,currentYOffset); const messageA_opacity_out = calcValues(values.messageA_opacity_out,currentYOffset); if(scrollRatio <= 0.22){ objs.messageA.style.opacity = messageA_opacity_in; } else{ objs.messageA.style.opacity = messageA_opacity_out; } break; case 1: break; case 2: break; case 3: break; } } //햔제 스크린이 몇번 씬에 있는지 알려줌2 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; // scene이 바뀌는 순간 -값을 방지 currentScene++; document.body.setAttribute('id',`show-scene-${currentScene}`) } if(yOffset < prevScrollHeight){ enterNewScene = true; // scene이 바뀌는 순간 -값을 방지 if(currentScene ===0) return; //위로 바운스효과 때문에(모바일) currentScene--; // 현재 씬에 맞춰서 바디에 아이디가 세팅된다,바뀌는 순간(resize)에만 체크 document.body.setAttribute('id',`show-scene-${currentScene}`) } //scene이 바뀌는 순간에 함수를 종료해서 playanimation이 한 턴 걸러진다 if(enterNewScene) return; playAnimation(); } // scroll해서 section을 넘어가면 currentScene[i]값이 실시간으로 바뀐다 window.addEventListener('scroll',function(){ yOffset = window.pageYOffset; scrollLoop(); }); window.addEventListener('load',setLayout); window.addEventListener('resize',setLayout); })();
- 미해결애플 웹사이트 인터랙션 클론!
opacity out을 추가한 이후부터 in이 제대로 작동하지 않아서 문의드립니다
opacity in 만 적용했을 땐 잘 됬는데, out을 추가한 후부터 스크롤을 살짝만 내려도 바로 opacity가 1이 됩니다ㅠㅠ out은 정상적으로 작동하지만 스크롤을 맨 위로 올리게 되면 opacity가 0이 되야 하는데 1로 남아있어서요ㅠㅠ 검토좀 부탁드립니다 이부분에서 계속 꼬여서 중간부터 다시 하는데 또 꼬여버리네요.. (() => { let yOffset = 0; // 현재 스크롤 위치 - window.pageOffset 대신 사용 할 변수, 블럭 내부의 어디서든 접근 가능 let prevScrollHeight = 0; // yOffset보다 이전에 위치한 스크롤 섹션 스크롤 높이값의 합 let currentScene = 0; // 현재 활성화 된(내가 보고 있는) 씬의 번호(scroll-section) let enterNewScene = false; // 새로운 scene이 시작된 순간 true로 바뀜 const sceneInfo = [ { // scroll-section 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-messagqe.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_translateY_in: [20, 0, { start: 0.1, end: 0.2 }], messageB_translateY_in: [20, 0, { start: 0.3, end: 0.4 }], messageC_translateY_in: [20, 0, { start: 0.5, end: 0.6 }], messageD_translateY_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_translateY_out: [0, -20, { start: 0.25, end: 0.3 }], messageB_translateY_out: [0, -20, { start: 0.45, end: 0.5 }], messageC_translateY_out: [0, -20, { start: 0.65, end: 0.7 }], messageD_translateY_out: [0, -20, { start: 0.85, end: 0.9 }] }, }, // { // // scroll-section 1 // type: "normal", // heightNum: 5, // scrollHeight: 0, // objs: { // container: document.querySelector("#scroll-section-1"), // }, // }, // { // // scroll-section 2 // type: "sticky", // heightNum: 5, // scrollHeight: 0, // objs: { // container: document.querySelector("#scroll-section-2"), // }, // }, // { // // scroll-section 3 // type: "sticky", // heightNum: 5, // scrollHeight: 0, // objs: { // container: document.querySelector("#scroll-section-3"), // }, // }, ]; // 각 스크롤섹션의 높이 셋팅 function setLayout() { 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`; } yOffset = window.pageYOffset; let totalScrollHeight = 0; 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}`); } // 현재 섹션에서 스크롤이 얼마나 움직였는지의 비율(0~1)을 계산해서 css에 적용하기 위한 함수 function calcValues(values, currentYOffset) { let rv; // 현재 씬(스크롤 섹션)에서만 스크롤 된 범위를 비율로 구하기 const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset / sceneInfo[currentScene].scrollHeight; // start ~ end 사이에 애니메이션 실행 (values의 길이가 3일 때, 세번째 원소가 존재할 때 작동하도록 함) if (values.length === 3) { const partScrollStart = values[2].start * scrollHeight; const partScrollEnd = values[2].end * scrollHeight; const partScrollHeight = partScrollEnd - partScrollStart; if ( (currentYOffset >= partScrollStart) && (currentYOffset <= partScrollEnd)) { rv = (currentYOffset - partScrollStart) / partScrollHeight * (values[1] - values[0]) + values[0]; } else if (currentYOffset < partScrollStart) { rv = values[0]; } else if (currentYOffset > partScrollEnd) { rv = values[1]; } } else { rv = scrollRatio * (values[1] - values[0]) + values[0]; } return rv; // return 값이 존재해야 계산된 값을 사용할 수 있음 } function playAnimation() { const objs = sceneInfo[currentScene].objs; const values = sceneInfo[currentScene].values; const currentYOffset = yOffset - prevScrollHeight; // 전체 스크롤값에서 이전 섹션들의 스크롤값 총합을 뺀 값 const scrollHeight = sceneInfo[currentScene].scrollHieght; const scrollRatio = currentYOffset / scrollHeight; // currentYOffest을 사용하는 이유는, 첫번째 섹션이 아닌 이상 yOffset에서 이전 섹션들의 스크롤합은 빼주어야 하기 때문 switch (currentScene) { case 0: // messageA가 0에서 등장하기 때문에 'in'으로 구분하기(나가는건 out) // opacity의 start와 end시점의 중간지점의 비율을 잡아서 그 지점보다 작을땐 in에 해당되는 효과를, 클땐 out에 해당되는 효과를 나타나게 함 if ( scrollRatio <= 0.22 ) { // in일 때 objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translateY(${calcValues(values.messageA_translateY_in, currentYOffset)}%)`; } else { // out일 때 objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translateY(${calcValues(values.messageA_translateY_out, currentYOffset)}%)`; } if (scrollRatio <= 0.42) { // in objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.62) { // in objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.82) { // in objs.messageD.style.opacity = calcValues(values.messageD_opacity_in, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageD.style.opacity = calcValues(values.messageD_opacity_out, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_out, currentYOffset)}%, 0)`; } 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; // 가끔 브라우저별로 바운스 효과가 일어나게 되면 currentScened이 -1이 되는 경우가 있기 때문 (모바일) currentScene--; document.body.setAttribute("id", `show-scene-${currentScene}`); } if (enterNewScene) return; // enterNewScene이 true라면 멈추게 해서 playAnimation이 한턴 걸러지게 되도록 함 (1에서 다시 스크롤을 위로 올렸을 때 음수가 나오는 것을 막아줌) playAnimation(); } window.addEventListener("scroll", () => { yOffset = window.pageYOffset; scrollLoop(); }); window.addEventListener("load", setLayout); // 이미지와 텍스트가 같이 로드되어야 하기 때문, 페이지가 다 로드되기 이전에 나오는 로드표시까지 함께 작동하게 하기 위함 window.addEventListener("resize", setLayout); })();
- 미해결애플 웹사이트 인터랙션 클론!
이미지 블렌드 캔버스에 mp4를 적용하려하는데요!
자꾸 반복된 질문 드려 죄송합니다. 애플 맥북 사이트를 보니 gif가 아니라 캔버스에 mp4를 반복재생하는 방법을 사용하고 있더라고요. 그래서 강사님 https://www.youtube.com/watch?v=p8TsTUJj-kY&t=389s&ab_channel=1%EB%B6%84%EC%BD%94%EB%94%A9 이 사이트에 나와있는 방법 참고해서 이미지블렌드캔버스 부분에 코드 적용해보았는데 첫번째 캔버스가 sticky로 바뀐이후에도 아무런 반응이 없더라고요 ㅠㅠ. 이부분 어떻게 해결해야하는지 궁금합니다. 코드 첨부합니다. c참고로 콘솔창에서 에러가 생기진 않습니다! 아무래도 addEventListener부분이 문제인 것 같아요.. if (scrollRatio < values.rect1_x[2].end) { step = 1; console.log("step1"); obj.canvas.classList.remove("sticky-canvas"); } else { step = 2; console.log("step2"); //이미지 블렌드 //imageBlendY :[0, 0, { start: 0, end: 0 }]; const owlVideo = document.querySelector(".owl-video"); owlVideo.addEventListener("canplaythrough", render); function render() { obj.context.drawImage(owlVideo, 0, 0); requestAnimationFrame(render); } obj.canvas.classList.add("sticky-canvas"); obj.canvas.style.top = `${ -(obj.canvas.height - obj.canvas.height * canvasScaleRatio) / 2 }px`; } break; }
- 미해결애플 웹사이트 인터랙션 클론!
두번째 캔버스에 img가 아닌 gif를 업로드가 가능한가요?
그냥 업로드를 하면 gif가 재생되지 않고 멈춰있더라구요. 그래서 https://konvajs.org/docs/sandbox/GIF_On_Canvas.html#page-title 여기 있는 konva js와 gifler를 이용해 gif애니메이션을 업로드하려 했는데 이번에는 이런 에러가 생기더라고요..
- 미해결애플 웹사이트 인터랙션 클론!
질문이 있습니다.
여기 강좌까지 제대로 따라온 것 같습니다.. 그런데 브라우저의 창 크기를 줄이거나 늘리면 캔버스의 하얀 박스 부분 위치값이 변경이 되질 않아 새로고침을 하지 않는 이상 스크롤을 위아래로 내려도 해당 브라우저 창 크기에 맞게 바뀌질 않네요ㅠㅠ 이 현상이 맞는 걸까요??
- 미해결애플 웹사이트 인터랙션 클론!
수업 자료 관련 질문이 있습니다.
안녕하세요, 수업 자료를 다운 받았는데 videotest 폴더에 02-image.html 파일이 한 개 있는데 해당 파일 코드가 선생님이 강의중에서 설명하신 파일과 다릅니다. 강의에서 설명하신 02-image-2.html 파이링 02-image.html 로 덮어쓰기 된 것 같습니다.. 강의에서 설명해주신 코드는 강의를 보면서 코드를 따라 쓰는 방법외엔 없을까요?
- 미해결애플 웹사이트 인터랙션 클론!
질문있습니다!
삭제된 글입니다
- 미해결애플 웹사이트 인터랙션 클론!
질문 있습니다!
강의와 관련있는 질문을 남겨주세요.• 강의와 관련이 없는 질문은 지식공유자가 답변하지 않을 수 있습니다. (사적 상담, 컨설팅, 과제 풀이 등)• 질문을 남기기 전, 비슷한 내용을 질문한 수강생이 있는지 먼저 검색을 해주세요. (중복 질문을 자제해주세요.)• 서비스 운영 관련 질문은 인프런 우측 하단 ‘문의하기’를 이용해주세요. (영상 재생 문제, 사이트 버그, 강의 환불 등) 질문 전달에도 요령이 필요합니다.• 지식공유자가 질문을 좀 더 쉽게 확인할 수 있게 도와주세요.• 강의실 페이지(/lecture) 에서 '질문하기'를 이용해주시면 질문과 연관된 수업 영상 제목이 함께 등록됩니다.• 강의 대시보드에서 질문을 남길 경우, 관련 섹션 및 수업 제목을 기재해주세요. • 수업 특정 구간에 대한 질문은 꼭 영상 타임코드를 남겨주세요! 구체적인 질문일수록 명확한 답을 받을 수 있어요.• 질문 제목은 핵심 키워드를 포함해 간결하게 적어주세요.• 질문 내용은 자세하게 적어주시되, 지식공유자가 답변할 수 있도록 구체적으로 남겨주세요.• 정확한 질문 내용과 함께 코드를 적어주시거나, 캡쳐 이미지를 첨부하면 더욱 좋습니다. 기본적인 예의를 지켜주세요.• 정중한 의견 및 문의 제시, 감사 인사 등의 커뮤니케이션은 더 나은 강의를 위한 기틀이 됩니다. • 질문이 있을 때에는 강의를 만든 지식공유자에 대한 기본적인 예의를 꼭 지켜주세요. • 반말, 욕설, 과격한 표현 등 지식공유자를 불쾌하게 할 수 있는 내용은 스팸 처리 등 제재를 가할 수 있습니다.
- 미해결애플 웹사이트 인터랙션 클론!
질문이 있습니다.
안녕하세요. 강의 항상 잘 듣고 있습니다. 이번 강의를 보다 관련해서 질문이 있는데 프레임 당 높이를 설정한다 하셨는데 예시를 들어 주실 수 있을까요? 예를들어 60프레임에는 6000px과 같이 현재 만드는 것에선 어떻게 기준을 잡고 설정을 하는지 궁금합니다. 감사합니다.
- 미해결애플 웹사이트 인터랙션 클론!
최신 02-image.html에서 질문있습니다.
안녕하세요. 선생님 수업 잘 보고 있습니다. 02-images.html 스크립트 마지막 부분인 window.addEventListener('load', init); setImages(); 위 코드 부분에서 코드 순서와 동작 순서가 잘 이해가 안가서 질문 남깁니다. 단순히 실행 순서만 생각했을 때는 setImages 함수가 먼저 실행되서 이미지 소스의 경로값을 지정한 다음에 'load'이벤트로 이미지 파일을 로드해야 된다고 생각했는데, 실제로 실행되는 것을 보니 두 코드의 순서는 상관없이 작동은 setImages()가 첫번째로 잘 동작하더라구요. 제가 생각했을 때는 setImages()를 실행하지 않으면 window load 이벤트가 받아올 이미지 경로를 못 찾을 거라고 생각했거든요. 제가 모르고 있는 부분이 혹시 어떤 부분일까요! 도움 부탁드립니다.
- 해결됨애플 웹사이트 인터랙션 클론!
사용하신 vscode 플러그인 궁금합니다.
html 작성하실 때 queryselector처럼 작성하시면 hmlt tag로 변환되던데, 어떤 플러그인 사용하신 건가요? (예: `a.global-nav-item`라고 쓰면, `<a class="global-nav-item></a>`로 변환) 쉽게 찾을 수 있을 것 같았는데 찾지 못해 질문드립니다.
- 미해결애플 웹사이트 인터랙션 클론!
모바일 버전으로는 못하나요?
모바일버전 최적화 웹페이지 만들고있는데 씬활성화가 웹일때만 먹히는데 방법이 없을까요?
- 미해결애플 웹사이트 인터랙션 클론!
선생님 답변을 보고 이미지 최적화를 진행해봤는데요,
선생님 답변을 보고 이미지 최적화를 진행해봤는데 그래도 로딩이 오래걸리더라구요 선생님 말씀처럼 첫번째 씬 이미지만 로드하도록 하고 그 후 이미지를 처리하게 하는게 방법인 것 같은데구글링을 해봤는데 어떻게 첫번째 씬 이미지만 로드시킬 수 있는지 잘 모르겠습니다..ㅠ 힌트나 방법을 좀 알 수 있을까요.. https://github.com/feelslikemmmm/Airmug-Pro/blob/master/js/main.js소스코드 깃허브입니다 제 생각에는 setcanvasImage 함수를 분기별로 나눠서 어떻게 해야할 것 같긴한데 ㅠㅠ 잘 모르겠습니다..
- 미해결애플 웹사이트 인터랙션 클론!
애플 사이트는 동영상 블렌딩도 되던데 동영상은 어떻게 적용할 수 있을까요??
맥북 페이지 동작을 참고하셨다고 해서 맥북 페이지 구경했는데요, 거기는 이미지 블렌딩도 있고 동영상이 블렌딩 되는 섹션도 있더라고요?? 신기하더라고요. 동영상으로 응용해보고 싶은데 동영상이 블렌딩 되도록 하려면 어디부터 시작해야할까요??
- 애플 웹사이트 인터랙션 클론!
yOffet값을 확인할 수 없습니다ㅠㅠ
삭제된 글입니다
- 미해결애플 웹사이트 인터랙션 클론!
scene3 오류 발생
scene3를 끝까지 스크롤한 후 다시 올렸을 때 canvas-caption이 첨부한 사진처럼 일분이와 함께 나타납니다.. 어디서 문제가 발생한것인지 모르겠어서 질문드립니다.,,
- 미해결애플 웹사이트 인터랙션 클론!
currentScene이 늘어날때 마다 currentYOffset이 초기화가 되지 않습니다 ㅠㅠ
(() => { let yOffset = 0; // window.pageYOffest 대신 쓸 변수 let prevScrollHeight = 0; // 현재 스크롤 위치(yOffset)보다 이전에 위치한 scroll-section의 스크롤 높이값의 합 let currentScene = 0; // 현재 활성화 된(눈 앞에 보고 있는) 씬(scroll-section) // 각 scene의 정보를 담고 있는 배열 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: [0, 1] } }, { //1 type: 'normal', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-1') } }, { //2 type: 'sticky', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-2') } }, { //3 type: 'sticky', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-3') } }, ] function setLayout() { // 각 스크롤 섹션의 높이 세팅 for (let i = 0; i < sceneInfo.length; i++) { // i번째 sceneInfo의 scrollHeight를, i번째 sceneInfo에 있는 heightNum(변수)와 window.innerHeight의 곱한 값으로 해주세요. sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight; // scroll-section-i의 높이를, sceneInfo의 scrollHeight px값만큼 설정해주세요. // `` -> 템플릿 문자열 / `${기본적으로 문자열이지만 변수도 넣을 수 있음.}` sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`; } // load, setLayout -> 현재 스크롤 위치에 맞춰서 currentScene을 배정 yOffset = window.pageYOffset; let totalScrollHeight = 0; for (let i = 0; i < sceneInfo.length; i++) { totalScrollHeight += sceneInfo[i].scrollHeight; // totalScrollHeight가 현재 스크롤 위치보다 크거나 같아졌을 때, for문을 멈추고 currentScene을 i번째로 설정 if (totalScrollHeight >= yOffset) { currentScene = i; break; } } //currentScene의 값에 맞춰 body의 id를 세팅함. document.body.setAttribute('id', `show-scene-${currentScene}`) } function calcValues(values, currentYOffset) { //currentYOffset -> 현재 씬에서 얼마나 스크롤 됐는지 } function playAnimation() { const objs = sceneInfo[currentScene].objs; const values = sceneInfo[currentScene].values; const currentYOffset = yOffset - prevScrollHeight; console.log(currentScene, currentYOffset); switch (currentScene) { case 0: //console.log('0play') let messageA_opacity_0 = values.messageA_opacity[0]; let messageA_opacity_1 = values.messageA_opacity[1]; break; case 1: //console.log('1play') break; case 2: //console.log('2play') break; case 3: //console.log('3play') break; } } function scrollLoop() { // 현재 눈 앞에 몇번째 scroll-section이 스크롤 되는지 확인하는 함수 let prevScrollHeight = 0; for (let i = 0; i < currentScene; i++) { // 이전 진행된 스크롤 값 = i번째 sceneInfo의 scrollHeight값. // prevScrollHeight = prevScrollHeight + sceneInfo[i].scrollHeight; // += -> 왼쪽의 피연산자에 오른쪽의 피연산자를 더한 후, 그 결괏값을 왼쪽의 피연산자에 대입함. prevScrollHeight += sceneInfo[i].scrollHeight; } // yOffest > 이전 스크롤 값 + 현재 활성화 된 scroll-section의 스크롤 값 if (yOffset > prevScrollHeight + sceneInfo[currentScene].scrollHeight) { currentScene++; //currentScene의 값에 맞춰 body의 id를 세팅함. document.body.setAttribute('id', `show-scene-${currentScene}`) } if (yOffset < prevScrollHeight) { if (currentScene === 0) return; // 브라우저 바운스 효과로 인해 마이너스가 되는 것을 방지(모바일) currentScene--; //currentScene의 값에 맞춰 body의 id를 세팅함. document.body.setAttribute('id', `show-scene-${currentScene}`) } playAnimation(); } // 창 사이즈가 바뀔 때마다 resize하면 setLayout이라는 함수가 작동하도록 // window.addEventListener('DOMContentLoaded', setLayout); window.addEventListener('load', setLayout); window.addEventListener('resize', setLayout); // 익명함수, 구체적인 역할을 하는 함수들을 여러개 호출할 예정. window.addEventListener('scroll', () => { yOffset = window.pageYOffset; // 스크롤 될 때마다 값을 보여줌. scrollLoop(); // 스크롤 될때 실행되는 함수 }) setLayout(); })();
- 미해결애플 웹사이트 인터랙션 클론!
currentScene과 sceneInfo[i].scrollHeight의 상관관계
해석하다 보니까 궁금한 점이 생겨버렸습니다. 반복문을 보면 currentScene이 0일때, 0 = 0 + sceneInfo[0].scrollHeight 라서 0 = 0 + 3725 이 되고 결국엔 스크롤 높이가 3725가 되는 건데, 콘솔로그창에 prevScrollHeight를 찍고 스크롤 했을 때 처음부터 3725가 나와야하는 것 아닌가요...?
- 미해결애플 웹사이트 인터랙션 클론!
선생님 궁금한점이 생겨서 질문드립니다
우선 좋은 강의 만들어주셔서 감사합니다 제가 프로젝트에 적용하려고 우선 강의보면서 만든 사이트를 배포 먼저 해두었는데요, Video폴더의 이미지가 워낙 많아서 그런지 웹 페이지 로딩 시간이 정말 정말 오래걸립니다로딩 시간을 줄이기 위해서 할 수 있는 방법이 뭐가 있을까요?,,