묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결애플 웹사이트 인터랙션 클론!
id를 통한 display: none 을 block 으로 변경 시 적용 문제
안녕하세요. 강의를 수강하는 학생입니다. document.body.setAttribute 를 이용하여 scene 을 보이게 하는데 있어서 문제가 생겨 문의를드립니다. display:none이 block으로 변경되는 부분에 있어서 잘되지 않아 질문을 올려봅니다. 해당문제 아래와 같이 깃헙 주소로 공유해봅니다. https://github.com/Mr-SY/CloneAppleSite 확인 바랍니다! 감사합니다!
-
해결됨따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
const renderRadioBox일때의 중괄호
const rendorRadioBox=()=>( props.lists&&props.lists.map(value=>( <Radio key={value._id} value> {/*key는 오류를 없애기 위해서 준다. */} {value.name} </Radio> )) ) 이 부분에서 const rendorRadioBox=()=>{ props.lists&&props.lists.map(value=>( <Radio key={value._id} value> {/*key는 오류를 없애기 위해서 준다. */} {value.name} </Radio> )) } 처럼 renderRadioBox를 { 가 아닌 ( 로 해야지만 제대로 동작하던데 지금껏 습관적으로 { 를 썻는데 { 와 (는 무슨 차이인거죠..ㅠ
-
미해결애플 웹사이트 인터랙션 클론!
씬마다 currentScene 바뀌는 시점이 제각각이예요;
빨간 테두리도 메인화면에서 브라우저에 선생님처럼 꽉 차게 나오지 않고.. 어떤 씬은 맞게 바뀌고 어떤 씬은 따로 바뀌고 제각각인데 왜이런거죠ㅠ //js코드 (() => { let yOffset = 0; let prevScrollHeight = 0; // 현재 스크롤 위치(yOffset)보다 이전에 위치한 스크롤 섹션들의 스크롤 높이 합 let currentScene = 0; // 현재 활성화된 scroll-section const sceneInfo = [ { // currentScene 0 type: 'sticky', heightNum: 5, // 브라우저 높이의 5배로 총 scrollHeight 세팅 scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-0') } }, { // currentScene 1 type: 'normal', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-1') } }, { // currentScene 2 type: 'sticky', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-2') } }, { // currentScene 3 type: 'sticky', heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-3') } } ]; function setLayout() { // 각 스크롤 섹션의 높이 세팅 prevScrollHeight = 0; 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`; } } function scrollLoop() { prevScrollHeight = 0; for(let i=0; i<currentScene; i++) { prevScrollHeight += sceneInfo[i].scrollHeight; } if (yOffset > sceneInfo[currentScene].scrollHeight + prevScrollHeight) { currentScene++; } if (yOffset < prevScrollHeight) { currentScene--; } console.log(`prevScrollHeight = ${prevScrollHeight}, pageYOffset=${yOffset}, currentScene=${currentScene}`); } // 리사이징 하면 그에 맞는 높이 다시 세팅 window.addEventListener('resize', setLayout); window.addEventListener('scroll', () => { yOffset = window.pageYOffset; scrollLoop(); }); setLayout(); })(); // css 코드 @charset 'utf-8'; html { font-family: 'Noto Sans KR', sans-serif; font-size: 14px; } body { overflow-x: hidden; color: rgb(29, 29, 31); letter-spacing: -0.05em; background: white; } p { line-height: 1.6; } .global-nav { position: absolute; top: 0; left: 0; width: 100%; height: 44px; padding: 0 1rem; } .local-nav { position: absolute; top: 45px; left: 0; width: 100%; height: 52px; padding: 0 1rem; border-bottom : 1px solid #ddd; } .global-nav-links, .local-nav-links { max-width: 1000px; display: flex; align-items: center; height: 100%; margin: 0 auto; } .global-nav-links { justify-content: space-between; } .global-nav-links a { font-size: 1.2rem; } .product-name { margin-right: auto; font-size: 1.4rem; font-weight: bold; } .local-nav-links a:not(.product-name) { margin-left: 2em; font-size: 1rem; } a { color : rgb(29, 29, 31); text-decoration: none; } .scroll-section { padding-top: 50vh; border: 3px solid red; } #scroll-section-0 h1 { font-size: 4rem; text-align: center; } .main-message { display: flex; align-items: center; justify-content: center; margin: 5px 0; height: 3em; font-size: 2.5rem; } .main-message p { line-height: 1.2; font-weight: bold; text-align: center; } .main-message small{ display: block; margin-bottom: 0.5em; font-size: 1.4rem; } #scroll-section-2 .main-message { font-size: 3.5rem; } .description { max-width: 1000px; margin: 0 auto; padding: 0 1rem; font-size: 1.2rem; color: #888; } .description strong { float: left; margin-right: 0.2em; font-size: 3rem; color: rgb(29, 29, 31); } .desc-message { font-weight: bold; width: 50%; max-width: 385px; } .pin { width: 1px; height: 100px; background-color: rgb(29, 29, 31); } .mid-message { max-width: 1000px; margin: 0 auto; padding: 0 1rem; font-size: 2rem; color: #888; } .mid-message strong { color: rgb(29, 29, 31); } .canvas-caption { max-width: 1000px; margin: 0 auto; padding: 0 1rem; color: #888; font-size: 1.2rem; } .footer { display: flex; align-items: center; justify-content: center; height: 7rem; background-color: tan; color: white; } .sticky-elem { display: none; position: fixed; top: 0; left: 0; width: 100%; } #show-scene-0 #scroll-section-0 .sticky-elem, #show-scene-1 #scroll-section-1 .sticky-elem, #show-scene-2 #scroll-section-2 .sticky-elem, #show-scene-3 #scroll-section-3 .sticky-elem { display: block; } @media (min-width: 1024px) { #scroll-section-0 h1 { font-size: 9vw; } .main-message{ font-size: 4vw; } .description { font-size: 2rem; } .description strong{ font-size: 6rem; } #scroll-section-2 .main-message { font-size: 6vw; } .main-message small { font-size: 2vw; } .desc-message { width: 20%; } .mid-message { font-size: 4vw; } .canvas-caption { font-size: 2rem; } }
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
tilemap_collision이 tilemap_base보다 큰 경우가 있을 수 있을 것 같은데 어떻게 하면 되나요?
tmBase와 tm의 cellBounds를 비교하여 더 큰 값을 취하면 되나요?
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part7: MMO 컨텐츠 구현 (Unity + C# 서버 연동 기초)
타일맵의 크기 변경하기
Tilemap_Collision의 영역이 저렇게 크게 설정되어있는데, 저 네모 영역을 줄이고 싶으면 어떻게 설정해야 하나요?
-
미해결공공데이터로 파이썬 데이터 분석 시작하기
ProfileReport 생성시 한글 부분적으로 깨짐 해결
안녕하세요. profileReport 생성시, 한글이 부분만 깨지는 경우가 있는데, 혹시 보신적이 있나요? 실행은 아래 그림처럼 했습니다. 실행은 되고, 파일은 저장이 되었습니다.
-
미해결공공데이터로 파이썬 데이터 분석 시작하기
잘못질문했어요!
사진이 안올라가서 무슨오류인지 안알려주신거 같아요 바로 이 오류에요 그리고 %ls data 를 쓰면 C 드라이브의 볼륨에는 이름이 없습니다. 볼륨 일련 번호: C442-F4C0 C:\Users\LGPC\Downloads 디렉터리 파일을 찾을 수 없습니다. 이것만 나오구요ㅠㅠ 윈도우라 그냥 여긴 넘어갔는데 데이터를 못불러온건가요?? 데이터를 못가져오겠어요 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
안녕하세요 영한님! jpa관련 질문입니다!
안녕하세요 영한님 수업 듣는도중에 EntityManager를 사용하시는데 설명 도중에 스프링 빈? 스프링이 생성한 EntityManager에 주입한다?라고 하시는데 이게 무슨말인지 잘 모르겠습니다 jpa의 EntityManager를 스프링이 생성한 빈즈에 주입하는건가요?
-
해결됨실전 리액트 프로그래밍
다음 강의 계획 질문
안녕하세요 강사님 강의 잘듣고 있습니다. 그런데 제가 React기초는 알고 있어, 빠르게 실습적인 강의를 듣고 싶은데 다음 강의 계획이 있으신지 궁금합니다.
-
미해결공공데이터로 파이썬 데이터 분석 시작하기
이건 무슨오류에요????
File "<ipython-input-10-1748e36fecc8>", line 1 pd.read_csv("data/전국 신규 민간 아파트 분양가격 동향_20200331.csv" ^ SyntaxError: unexpected EOF while parsing 그리구 맥북은 자동완성이되는데 윈도우는 안되거든요 그런데 자꾸 자동완성하셔서 혼자 빨리진행하셔서 햇갈려요 윈도우는 어떤방식으로 하라고 정확하게 알려주셔야지 질문창들 보고야 알았어요 ㅜ 데이터불러오는것도 그냥 업로드로 하구요
-
미해결웹 게임을 만들며 배우는 React
세팅방법설명해주셔서..감사합니다 ..
다른강의는 ..create-react-app 만써대서 저걸왜하는지 이해가안갔는데 고맙습니당!
-
미해결애플 웹사이트 인터랙션 클론!
콘솔창에 에러나는데 왜 이러는 걸까요 ㅠㅠ
(() => { let yOffset = 0; // window.pageYOffset 대신 쓸 변수 let prevScrollHeight = 0; // 현재 스크롤 위치 (yOffset) 보다 이전에 위치한 스크롤 섹션들의 스크롤 높이 합 let currentScene = 0; // 현재 활성화 된(눈 앞에 보고 있는) 씬 (scroll-section) let enterNewScene = false; // 새로운 씬이 시작 된 순간 true 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'), canvas: document.querySelector('#video-canvas-0'), context: document.querySelector('#video-canvas-0').getContext('2d'), videoImages: [] }, values: { videoImageCount: 300, imageSequenc: [0, 299], 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 }], // 20=> translateY를 20%만큼 조정, %는 밑에 playAnimation()에서 붙여줄 거임 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 }] } }, //1 { type: 'normal', // heightNum: 5, // type normal에서는 필요없음 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'), canvasCaption: document.querySelector('.canvas-caption') }, values: { } } ]; function setCanvasImages() { let imgElem; for (let i = 0; i < sceneInfo[0].values.videoImageCount; i++) { // imgElem = document.createElement('img'); imgElem = new Image(); imgElem.src = `./video/001/IMG_${6726 + i}.JPG`; sceneInfo[0].objs.videoImages.push(imgElem); } } 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}`); } function calcValues(values, currentYOffset) { let rv; // 현재 씬(스크롤섹션)에서 스크롤 된 범위를 0~1 사이의 비율로 구하기 const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset / scrollHeight; if (values.length === 3) { // start ~ end 사이에 애니메이션 실행 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() { const objs = sceneInfo[currentScene].objs; const values = sceneInfo[currentScene].values; const currentYOffset = yOffset - prevScrollHeight; // 현재 씬에서 얼만큼 스크롤했는지를 확인 const scrollHeight = sceneInfo[currentScene].scrollHeight; // const scrollRatio = yOffset / 현재 씬의 scrollHeight; const scrollRatio = currentYOffset / scrollHeight; switch (currentScene) { case 0: // console.log('0 play'); let sequence = Math.round(calcValues(values.imageSequenc, currentYOffset)); objs.context.drawImage(objs.videoImages[sequence], 0, 0); if (scrollRatio <= 0.22) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } 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 2: // console.log('2 play'); if (scrollRatio <= 0.32) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.67) { // in objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } else { // out objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } if (scrollRatio <= 0.93) { // in objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } else { // out objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } break; case 3: // console.log('3 play'); 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; playAnimation(); } window.addEventListener('scroll', () => { yOffset = window.pageYOffset; scrollLoop(); }); // window.addEventListener('DOMcontentLoaded', setLayout) // 이미지가 업로드 되기 전에 실행 window.addEventListener('load', setLayout); window.addEventListener('resize', setLayout); })();
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
saga 가 실행이 안됩니다..
사가 가 실행이 안되네요 ㅠㅠ 콘솔창에 확인해보니 아래와 같이 에러가 납니다 loginForm에서 dispatch로 data는 잘 넘겨줬는데 왜 이럴까요..?
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
콜백함수
여러 이벤트를 콜백함수로 처리해주는 이유가 다른 곳에서도 쉽게 사용하기 위해서 Action.Invoke으로 호출해주는건가요??
-
미해결애플 웹사이트 인터랙션 클론!
opacity out 이 안되는데 검토 한번만 해주세요
(() => { 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 }], messageA_opacity_out: [1, 0, { start: 0.25, end: 0.3 }], } }, { // 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') } }, { // 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++) { sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight; // sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px` } let totalScrollHeight = 0; let 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 - partScrollHeight) / 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 = (yOffset - prevScrollHeight) / scrollHeight; console.log(currentScene) switch (currentScene) { case 0: // calcValues = (values의 선명도, 현재 스크롤의 위치) const messageA_opacity_in = calcValues(values.messageA_opacity_in, currentYOffset) const messageA_opacity_out = calcValues(values.messageA_opacity_out, currentYOffset) if (scrollRatio <= 0.22) { // in objs.messageA.style.opacity = messageA_opacity_in; } else { // out objs.messageA.style.opacity = messageA_opacity_out; } 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); })()
-
해결됨인터랙티브 웹 개발 제대로 시작하기
1분이가 계속 한자리에만 생기는데요. info.xPos가 일분이에게 안들어가는거 같아요. 놓친부분이 있는거겠죠?
(function(){//즉시 실행 함수 const stageElem = document.querySelector('.stage'); const houseElem = document.querySelector('.house'); const barElem = document.querySelector('.progress-bar'); const mousePos = {x:0,y:0}; let maxScrollValue; function resizeHandler(){ maxScrollValue = document.body.offsetHeight - window.innerHeight; } window.addEventListener('scroll',function(){ // pageYoffset 스크롤 한 값 // console.log(this.pageYOffset); // 스크롤 범위 지정하기 // console.log( pageYOffset/maxScrollValue); const scrollPer = pageYOffset/maxScrollValue const zMove =scrollPer*970 -490; houseElem.style.transform = 'translateZ('+zMove+'vw)'; // progress bar barElem.style.width = scrollPer *100 + '%'; }) window.addEventListener('mousemove',function(e){ // console.log(e.clientX,e.clientY) 마우스 위치 알아내기 mousePos.x = -1+(e.clientX /window.innerWidth)*2; mousePos.y = 1-(e.clientY /window.innerHeight)*2; stageElem.style.transform='rotateX('+(mousePos.y*5)+'deg) rotateY('+(mousePos.y*5)+'deg)'; // console.log(mousePos); }) window.addEventListener('resize',resizeHandler) resizeHandler(); stageElem.addEventListener('click',function(e){ // console.log(e.clientX/window.innerWidth*100) new Character({//객체의 속성으로 넣어야 함. 다른 것들도 추가해야 하기때문에 xPos :e.clientX/window.innerWidth*100 }); }) })() function Character(info) { this.mainElem = document.createElement('div'); this.mainElem.classList.add('charactor'); this.mainElem.innerHTML = '' + ' <div class="character" >' + ' <div class="character-face-con character-head">' + '<div class="character-face character-head-face face-front"></div>' + '<div class="character-face character-head-face face-back"></div>' + '</div>' + ' <div class="character-face-con character-torso">' + '<div class="character-face character-torso-face face-front"></div>' + '<div class="character-face character-torso-face face-back"></div>' + ' </div>' + '<div class="character-face-con character-arm character-arm-right">' + ' <div class="character-face character-arm-face face-front"></div>' + ' <div class="character-face character-arm-face face-back"></div>' + '</div>' + ' <div class="character-face-con character-arm character-arm-left">' + '<div class="character-face character-arm-face face-front"></div>' + '<div class="character-face character-arm-face face-back"></div>' + '</div>' + ' <div class="character-face-con character-leg character-leg-right">' + '<div class="character-face character-leg-face face-front"></div>' + '<div class="character-face character-leg-face face-back"></div>' + '</div>' + ' <div class="character-face-con character-leg character-leg-left">' + '<div class="character-face character-leg-face face-front"></div>' + '<div class="character-face character-leg-face face-back"></div>' + '</div>' + '</div>'; document.querySelector('.stage').appendChild(this.mainElem); this.mainElem.style.left= info.xPos+'%'; }
-
해결됨HTML+CSS+JS 포트폴리오 실전 퍼블리싱(시즌1)
가상클래스 hover 활용한 실전 퍼블리싱 04(위아래로 분리되는 호버 네비게이션 이펙트) 정렬에 대해서...
인라인블록으로 했는데 정렬이 안되고 자꾸 붙습니다...ㅠㅠ 올려주신 완성본 파일 css를 붙여넣어도 정렬이 안되네요..ㅠㅠ
-
미해결단 두 장의 문서로 데이터 분석과 시각화 뽀개기
Library 질문입니다.
안녕하세요 Library 다음에 method 지정하는데, melt는 pd.에 나오고, pivot은 df.에 따르는데, 어떤 규칙이 있나요. logic에서도 마찬가지여서, 작성하면서 혼돈이 많이 되네요. 아님 그냥 외워야 되는건지요. 그리고 별개의 질문인데요. data 읽어 올 때 list of dictionary 하고 list of list 개념 설명 부탁합니다. 어떤 차이점이 있고 어떤 방식으로 활용해야 되는지요
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
cannot find symbol
이런 에러가 뜨는데 어떻게 수정하면 될까요?
-
미해결웹 개발자와 정보보안 입문자가 꼭 알아야 할 웹 해킹 & 시큐어 코딩
[실습4-1] XXE Injection 공격 실습
[실습4-1] XXE Injection 공격 실습 편에서 아래와 같이 외부 개체 참조 테스트를 위해 XML을 입력하면 secret_info.txt 파일 내용이 보이지 않는 경우가 있습니다. PHP5 에서는 문제가 없는 것 같고 PHP7에서 문제가 되네요. xmlparser.php 내 simplexml_load_string 함수를 호출할 때 아래와 같이 옵션을 지정해주면 secret_info.txt 문자열을 정상적으로 확인할 수 있습니다. 혹시라도 저 처럼 AMP 환경이 아닌 곳에서 학습을 진행하고 계시다면 참고하시면 좋을 것 같습니다.