묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨애플 웹사이트 인터랙션 클론!
canvas에 사진이 출력되지 않습니다
해당 강의를 바탕으로 따로 페이지 하나를 제작하고 있는데 사진은 지정이 되지만 사진이 출력되지 않네요 ㅠ 그리고 Uncaught TypeError : Cannot read properties of undefined (reading @@@) 에러가 length랑 style에 뜨는데 원인과 해결방법을 알 수 있을까요? -> 이 부분은 해결했습니다. main.js 코드입니다 + canvas를 통해 (머그컵과 같은) video 모션 이미지들이 들어가는 곳은 section 2,3,4 입니다. (() => { // 변수 모음 let yOffset = 0; // window.pageYOffset 대신 쓸 변수 let prevScrollHeight; // 현재 스크롤 위치 이전의 섹션들의 높이 합 let currentScene = 0; // 현재 보고 있는 씬 scroll-section 몇 번째인지 let enterNewScene = false; // 새로운 세션 시작된 순간 true const sceneInfo = [ { // section 0 - 인트로 type: "sticky", heightNum: 5, // 브라우저 높이의 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 }], 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 }], }, }, { // section 1 - 서비스 리스트 type: "normal", // heightNum: 5, // type normal에서는 필요 없음 scrollHeight: 0, objs: { container: document.querySelector("#scroll-section-1"), content: document.querySelector("#scroll-section-1 .description"), }, }, { // section 2 - 공개행정 type: "sticky", heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector("#scroll-section-2"), // messageABCD canvas: document.querySelector("#video-canvas-2"), context: document.querySelector("#video-canvas-2").getContext("2d"), videoImages: [], }, values: { videoImageCount: 14, imageSequence: [0, 13], canvas_opacity: [1, 0, { start: 0.9, end: 1 }], canvas_opacity_out: [1, 0, { start: 0.95, end: 1 }], // ,assage opacity, translate }, }, { // section 3 - 참여행정 type: "sticky", heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector("#scroll-section-3"), // messageABCD canvas: document.querySelector("#video-canvas-3"), //content: document.querySelector("#scroll-section-3 .description"), context: document.querySelector("#video-canvas-3").getContext("2d"), videoImages: [], }, values: { videoImageCount: 15, imageSequence: [0, 14], canvas_opacity: [1, 0, { start: 0.9, end: 1 }], canvas_opacity_out: [1, 0, { start: 0.95, end: 1 }], // ,assage opacity, translate }, }, { // section 4 - 능률행정 type: "sticky", heightNum: 5, scrollHeight: 0, objs: { container: document.querySelector("#scroll-section-4"), // messageABCD canvas: document.querySelector("#video-canvas-4"), //content: document.querySelector("#scroll-section-4 .description"), //context: document.querySelector("#video-canvas-4").getContext("2d"), videoImages: [], }, values: { videoImageCount: 12, imageSequence: [0, 11], canvas_opacity: [1, 0, { start: 0.9, end: 1 }], canvas_opacity_out: [1, 0, { start: 0.95, end: 1 }], // ,assage opacity, translate }, }, { // section 5 - 마무리 type: "sticky", heightNum: 5, // 브라우저 높이의 5배로 세팅 scrollHeight: 0, objs: { container: document.querySelector("#scroll-section-5"), messageA: document.querySelector("#scroll-section-5 .main-message.a"), messageB: document.querySelector("#scroll-section-5 .main-message.b"), messageC: document.querySelector("#scroll-section-5 .main-message.c"), messageD: document.querySelector("#scroll-section-5 .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_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 }], }, }, ]; function setCanvasImages() { let imgElem1; for (let i = 0; i < sceneInfo[2].values.videoImageCount; i++) { imgElem1 = new Image(); imgElem1.src = `./video/section2_file/section2IMG_${i}.JPG`; sceneInfo[2].objs.videoImages.push(imgElem1); } let imgElem2; for (let i = 0; i < sceneInfo[3].values.videoImageCount; i++) { imgElem2 = new Image(); imgElem2.src = `./video/section3_file/section3IMG_${i}.JPG`; sceneInfo[3].objs.videoImages.push(imgElem2); } let imgElem3; for (let i = 0; i < sceneInfo[4].values.videoImageCount; i++) { imgElem3 = new Image(); imgElem3.src = `./video/section4_file/section4IMG_${i}.JPG`; sceneInfo[4].objs.videoImages.push(imgElem3); } } 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; } // 섹션의 높이를 html에 세팅 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}`); const heightRatio = window.innerHeight / 1080; sceneInfo[2].objs.canvas.style.transform = `translate3d(-50%, -50%, 0) scale(${heightRatio})`; } // 값이 변화되는 걸 계산 // currentYOffset - 현재 섹션에서 얼마나 scroll되었는지 비율 계산 function calcValues(values, currentYOffset) { let rv; // return value 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]; // 0~1 -> 범위 확장 return rv; } 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 = currentYOffset / scrollHeight; //console.log(currentScene, currentYOffset); switch (currentScene) { case 0: // 인트로 // console.log('0 play'); // let sequence = Math.round(calcValues(values.imageSequence, 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 1: // 리스트 break; case 2: // 공개행정 objs.canvas.style.opacity = calcValues( values.canvas_opacity, currentYOffset ); if (scrollRatio <= 0.5) { // in objs.canvas.style.opacity = calcValues( values.canvas_opacity_in, currentYOffset ); } else { // out objs.canvas.style.opacity = calcValues( values.canvas_opacity_out, currentYOffset ); } if (scrollRatio <= 0.25) { // 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.57) { // 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.83) { // 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: // 참여행정 objs.canvas.style.opacity = calcValues( values.canvas_opacity, currentYOffset ); if (scrollRatio <= 0.25) { // 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.57) { // 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.83) { // 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 4: // 능률 행정 objs.canvas.style.opacity = calcValues( values.canvas_opacity, currentYOffset ); if (scrollRatio <= 0.25) { // 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.57) { // 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.83) { // 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 5: // 마무리 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; } } // "현재 활성시킬 스크롤 씬(세션) 결정하기" // 몇 번째 스크롤 섹션 진행중인지 check // 앞파트 스크롤 섹션의 height 합으로 계산 가능 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}`); // currentScene에 맞춰서 body에 하나씩 세팅된다 } if (yOffset < prevScrollHeight) { enterNewScene = true; if (currentScene == 0) return; // 브라우저 바운스 효과로 음수 에러 방지 currentScene--; document.body.setAttribute("id", `show-scene-${currentScene}`); // currentScene에 맞춰서 body에 하나씩 세팅된다 } if (enterNewScene) return; playAnimation(); //console.log(currentScene); // 몇 번째 섹션인지 } //window.addEventListener("resize", setLayout); // height에러 check window.addEventListener("scroll", () => { yOffset = window.pageYOffset; //console.log(yOffset); // 스크롤 페이지 값 scrollLoop(); }); // 새로고침 window.addEventListener("load", setLayout); window.addEventListener("resize", setLayout); setLayout(); setCanvasImages(); })();
-
미해결비전공자를 위한 진짜 입문 올인원 개발 부트캠프
방어코드 작동이 안됩니다
수업대로 if 문안에 name, description, price, seller를 넣고 포스트맨 body에서 seller를 뺀 채로 send해보니 출력에서 res.send안의 내용이 출력되지 않습니다. 어느 부분이 잘못되었는지 궁금합니다.
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진
매니저들 관련 질문입니다.
지금까지 여러가지 매니저들을 만들면서 프레임워크를 구축한 것 같은데 여기에 사용된 코드들을 전부 이해하고 다음 챕터로 넘어가야 할까요? 아니면 일단 사용법만 숙지하고 다음 수업을 들어도 될까요?
-
미해결현업 실무자에게 배우는 Kaggle 머신러닝 입문 - ML 엔지니어 실무 꿀팁
데이터 갯수가 100K 의미
안녕하세요, Ridge & Lasso & ElasticNet Regression 강의의 9분 56초에서 데이터 갯수가 100K 라는 의미가 pandas의 dataframe을 생각해봤을때, 행과 열의 모든 데이터를 말하는 의미일까요?? 예를 들어서 3개의 feature가 있고 4개의 데이터가 있다고할때, 12개의 데이터 갯수가 있는게 맞을가요?
-
미해결코딩으로 학습하는 GoF의 디자인 패턴
Handler 순서 적용 관련
여러 핸드러를 적용시 생성자에 계속 넣어주는 방식은 좋지 않으니다르게 핸들러 순서를 적용하고 싶으면어떤 클래스 HandlerStore?를 지정해두고 해당 클래스에서내부적으로 HanderList를 필드로 갖고 있고,추가적으로 order 필드를 갖게 한 뒤 order를 기준으로 sorting 후 하나씩 적용하도록 하면 될거 같은데요 여기서 HandlerStore를 사용하는 것이 컴포짓 패턴이라고 볼수 있을까요?
-
미해결비전공자를 위한 개발자 취업 올인원 가이드 [통합편]
안녕하세요! '열심히'와 '노력'에 대한 기준에 대해 여쭙고 싶습니다!
안녕하세요 한정수님! 현재 국비지원 개발과정에 참여해서 열심히(?) 달려가고 있는 취준생입니다. 국비과정을 수강하며 혼란스럽고 어려운 점이 정말 많았는데, 우선 이렇게 좋은 강의 만들어주심에 정말 감사하다는 말씀 드려요! 취업을 목표로 선택과 집중이 필요한 시기인데 그런 부분에 대해 구체적이고 명확하게 제시해주는 강의라던가, 자료를 찾기가 쉽지 않았어서 강의를 들으며 정말 많은 도움을 받고 있어 감사했습니다! 다름이 아니라, 강의를 들으면서 한 가지 큰 의문점이 생겼는데요. 저도 늦은 나이에 개발자로 이직을 결심하고 이 길에 들어서게 되면서, 또 강의에서 소개해주시는 다른 많은 열심히 살아가고 계신 개발자님 사례라던가, 한정수님의 사례를 들으며 나는 그동안 열심히 살지 못했구나! 정말 제대로 노력해본 적이 있었던가? 하고 반성이 되더라고요. 그래서 이번에야말로 정말 최선을 다해 노력해보자, 라는 결심을 다지며 또 다시 달려나가려던 차에, 문득 궁금해졌습니다. '열심히'나 '노력'에 대한 기준이 과연 어떤걸까? 하는 사실 보다 근본적인 의문점이기는 한데, 오키에서 보았던 어떤 분의 수기에는, 국비지원 과정만으로 개발자를 준비했고 취업에 성공했는데 매일 14시간 이상씩 개발에 몰두했다던가... 또 소개해주신 사례중에 개발자 황준일님의 회고 글도 보면 굉장히 열심히 사시는 것 같은데, 저런 정도로 열심히 해야 하는 건가? 해서, 어느 정도로 열심히 해야 하는 건지에 대한 감이 잘 잡히지 않아서요. 그런 기준이 있다면 그것을 기준으로 삼아 더 열심히 해보고 싶은데, 몸이 상하는 걸 느끼면서까지 잠도 줄이고 해야 정말 열심히 했다고 할 수 있는 걸까, 그렇게 하면 정말 막연하게 정말 좋은 곳에서 좋은 연봉으로 일할 수 있는걸까, 하는 불안함과 막연함이 같이 생기더라고요. 그래서 앞서 언급드렸던 그 누구보다 열심히 하시고 노력하시는 분들 중 한 분이신 한정수님께 질문을 드려보고 싶었습니다! 좀 더 구체적으로 말씀드리자면 현재 제 위치에서는, 취업이 되기 전까지 자바로 혼자 코드를 구현해서 웹 개발을 충분히 할 수 있을 정도로 연습하고 훈련이 되면(?) 그게 열심히 했다고 할 수 있는 것인지...? 그 정도가 될 때까지 열심히 하면 되는건지..? 그런 것들이 좀 막연하게 느껴져서 이렇게 질문을 드립니다. 감사합니다!!
-
미해결HTML+CSS+JS 포트폴리오 실전 퍼블리싱(시즌1)
hover 시에, 양 방향 전부 효과를 줄 수 있는 방법
선생님 양 옆에서 색을 차게 할 방법은 없나요? 예를 들어서 위->아래 / 왼쪽->오른쪽이 동시에 차는 효과가 생기게끔 하고 싶어요. 색을 채우는 게 아니라 전 시간에 했던 것 처럼 선을 긋는 것도 마찬가지인데요. 테두리가 왼쪽 오른쪽 위쪽 아래쪽 4개가 있는데 호버했을 시에 이 네 방향이 전부 선이 그어지게 하려면 어떻게 해야 할까요?
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
http 통신 질문있습니가.
http 통신을 하고 싶은데 혹시 추천할만한 라이브러리가 있을까요? 그리고 예전에 pocolib를 썼는데 불필요한 파일이 많아질것 같아서 http통신만 할 수 있는 좋은 라이브러리가 있을지 궁금합니다.
-
미해결[리뉴얼] 코딩자율학습 제로초의 자바스크립트 입문
두 코드의 차이점이 궁금합니다.
책에 나와있는 내용인데요. 1. const func = () => { return ()=> { console.log("hello"); }; }; 이렇게 함수를 선언하고 2. const innerFunc = func(); 이렇게 함수를 변수에다 집어넣은 후 3. innerFunc(); 함수를 선언을 하면 콘솔창에 hello라고 제대로 뜨는데 1 번 바로 뒤에 func(); 를 호출하면 왜 콘솔창에 hello가 안뜨는지 궁금합니다.
-
미해결내 업무를 대신 할 파이썬(Python) 웹크롤링 & 자동화 (feat. 주식, 부동산 데이터 / 인스타그램)
네이버 주식 데이터
안녕하세요. 네이버 주식 데이터가 크롤링이 막혔다는 소리를 들었습니다. 그래서 강의에서 배운 내용을 적용할 수 없는 거 같은데 맞나요? 제가 못 찾고 있는지 궁금해서 질문 남깁니다~
-
미해결코딩으로 학습하는 GoF의 디자인 패턴
옵저버 패턴 예제 관련 질문 드립니다.
강의 10분경에 Subscriber interface에 getName이 없어 User class를 사용하신다고 이야기 주신 부분에 대한 질문입니다. 생각하기에는 Subscriber interface에 getName abstract method를 선언하여 사용하면 될 듯 한데, User를 사용한 이유가 있을까요? 이렇게 사용하는 것이 더 좋은 형태인건지 여부가 궁금해서 질문드립니다. 언제나 좋은 강의 감사합니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
테스트 에러
다른분들 에러 내용 확인해보고 설정 다 변경했는데 계속 오류가 뜹니다 이런오류가 뜨는데 어떤 부분이 잘못된 걸까요?
-
미해결시스템엔지니어가 알려주는 리눅스 기초편 Bash Shell Script
/dev/null 에 관해서 질문이요
"curl -o /dev/null ~" 에 경우에 아웃풋 파일을 굳이 /dev/something 이런식으로 해서 아웃풋 파일을 처리하는건가여? 예를들어 /dev/null 이면 그냥 -o 를 지정 안해주면 되지않을까요? 이런식으로 아웃풋 파일을 처리하는 이유가있을까요?
-
미해결스프링과 JPA 기반 웹 애플리케이션 개발
DB 조회를 통한 사용자 정보 참조
안녕하십니까 강사님! 질문있습니다 :) 강의를 보기전에 이번 실습에서의 제목 "현재 인증된 사용자 정보 참조" 를 보고 제가 직접 구현해 본 코드입니다. 혹시 이 방법이 강의에서 구현한 방법과 코드나 성능적인 부분에서 안좋은 점이 있는 지 궁금합니다. (예를들면 DB 를 조회하는 부분이 있기 때문에 성능면에서 좀 더 안좋다 ?) 아니면 큰 차이가 없기 때문에 그냥 사용해도되는지도 궁금합니다.
-
미해결남박사의 파이썬 기초부터 실전 100% 활용
cctv만들기 질문입니다ㅓ.
from skimage.metrics import compare_ssim 작동이 안됩니다. 그래서 아래의 문장을 대체제로 같고왔습니다. from skimage.metrics import structural_similarity as compare_ssim 그런데 화면이 연속으로 찍히지 않고 한장만 찍힙니다. 칭 닫기를 누르면 다음 화면으로 넘어가는데 연속으로 찍히지 않아 질문드립니다.
-
미해결리액트로 나만의 블로그 만들기(MERN Stack)
postDetail scss 문제
안녕하세요. 지금 게시글 상세보기 강의 듣고 있는데 강사님과 똑같이 코드를 쳤는데 레이아웃의 버튼 배치나 사이즈가 똑같이 안됩니다. node-scss node-loadr 도 다 설치되었는데 무엇이 문제일까요.. haeder.js 부분도 이상하게 보입니다. 상세보기 화면 client/package.json { "name": "client", "version": "0.1.0", "private": true, "dependencies": { "@babel/core": "7.12.3", "@babel/plugin-transform-react-jsx": "^7.14.9", "@babel/plugin-transform-react-jsx-self": "^7.14.9", "@ckeditor/ckeditor5-adapter-ckfinder": "^31.0.0", "@ckeditor/ckeditor5-alignment": "^31.0.0", "@ckeditor/ckeditor5-autoformat": "^31.0.0", "@ckeditor/ckeditor5-basic-styles": "^31.0.0", "@ckeditor/ckeditor5-block-quote": "^31.0.0", "@ckeditor/ckeditor5-build-balloon": "^31.0.0", "@ckeditor/ckeditor5-build-classic": "^31.0.0", "@ckeditor/ckeditor5-build-inline": "^31.0.0", "@ckeditor/ckeditor5-dev-utils": "^25.4.5", "@ckeditor/ckeditor5-dev-webpack-plugin": "^25.4.5", "@ckeditor/ckeditor5-easy-image": "^31.0.0", "@ckeditor/ckeditor5-editor-balloon": "^31.0.0", "@ckeditor/ckeditor5-editor-classic": "^31.0.0", "@ckeditor/ckeditor5-essentials": "^31.0.0", "@ckeditor/ckeditor5-font": "^31.0.0", "@ckeditor/ckeditor5-heading": "^31.0.0", "@ckeditor/ckeditor5-image": "^31.0.0", "@ckeditor/ckeditor5-indent": "^31.0.0", "@ckeditor/ckeditor5-link": "^31.0.0", "@ckeditor/ckeditor5-list": "^31.0.0", "@ckeditor/ckeditor5-media-embed": "^31.0.0", "@ckeditor/ckeditor5-paragraph": "^31.0.0", "@ckeditor/ckeditor5-paste-from-office": "^31.0.0", "@ckeditor/ckeditor5-react": "^3.0.3", "@ckeditor/ckeditor5-table": "^31.0.0", "@ckeditor/ckeditor5-theme-lark": "^31.0.0", "@ckeditor/ckeditor5-typing": "^31.0.0", "@ckeditor/ckeditor5-upload": "^31.0.0", "@fortawesome/fontawesome-svg-core": "^1.2.36", "@fortawesome/free-solid-svg-icons": "^5.15.4", "@fortawesome/react-fontawesome": "^0.1.16", "@pmmmwh/react-refresh-webpack-plugin": "0.4.3", "@svgr/webpack": "5.5.0", "@testing-library/jest-dom": "^5.11.4", "@testing-library/react": "^11.1.0", "@testing-library/user-event": "^12.1.10", "@typescript-eslint/eslint-plugin": "^4.5.0", "@typescript-eslint/parser": "^4.5.0", "axios": "^0.23.0", "babel-eslint": "^10.1.0", "babel-jest": "^26.6.0", "babel-loader": "8.1.0", "babel-plugin-named-asset-import": "^0.3.7", "babel-preset-react-app": "^10.0.0", "bfj": "^7.0.2", "bootstrap": "^5.1.3", "camelcase": "^6.1.0", "case-sensitive-paths-webpack-plugin": "2.3.0", "connected-react-router": "^6.9.1", "css-loader": "4.3.0", "dotenv": "8.2.0", "dotenv-expand": "5.1.0", "eslint": "^7.11.0", "eslint-config-react-app": "^6.0.0", "eslint-plugin-flowtype": "^5.2.0", "eslint-plugin-import": "^2.22.1", "eslint-plugin-jest": "^24.1.0", "eslint-plugin-jsx-a11y": "^6.3.1", "eslint-plugin-react": "^7.21.5", "eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-testing-library": "^3.9.2", "eslint-webpack-plugin": "^2.5.2", "file-loader": "6.1.1", "fs-extra": "^9.0.1", "history": "^4.7.2", "html-webpack-plugin": "4.5.0", "identity-obj-proxy": "3.0.0", "jest": "26.6.0", "jest-circus": "26.6.0", "jest-resolve": "26.6.0", "jest-watch-typeahead": "0.6.1", "mini-css-extract-plugin": "0.11.3", "node-sass": "^4.14.1", "optimize-css-assets-webpack-plugin": "5.0.4", "pnp-webpack-plugin": "1.6.4", "postcss-flexbugs-fixes": "4.2.1", "postcss-loader": "3.0.0", "postcss-normalize": "8.0.1", "postcss-preset-env": "6.7.0", "postcss-safe-parser": "5.0.2", "prompts": "2.4.0", "raw-loader": "^3.1.0", "react": "^17.0.2", "react-app-polyfill": "^2.0.0", "react-bootstrap": "^2.0.1", "react-dev-utils": "^11.0.3", "react-dom": "^17.0.2", "react-helmet": "^6.1.0", "react-redux": "^7.2.5", "react-refresh": "^0.8.3", "react-router-dom": "^5.3.0", "reactstrap": "^8.10.0", "redux": "^4.1.1", "redux-saga": "^1.1.3", "resolve": "1.18.1", "resolve-url-loader": "^3.1.2", "sass-loader": "^10.0.5", "semver": "7.3.2", "style-loader": "1.3.0", "terser-webpack-plugin": "4.2.3", "ts-pnp": "1.2.0", "url-loader": "4.1.1", "web-vitals": "^1.0.1", "webpack": "4.44.2", "webpack-dev-server": "3.11.1", "webpack-manifest-plugin": "2.2.0", "workbox-webpack-plugin": "5.1.4" }, "scripts": { "start": "node scripts/start.js", "build": "node scripts/build.js", "test": "node scripts/test.js" }, "eslintConfig": { "extends": [ "react-app", "react-app/jest" ] }, "proxy": "http://localhost:700", "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "jest": { "roots": [ "<rootDir>/src" ], "collectCoverageFrom": [ "src/**/*.{js,jsx,ts,tsx}", "!src/**/*.d.ts" ], "setupFiles": [ "react-app-polyfill/jsdom" ], "setupFilesAfterEnv": [], "testMatch": [ "<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}", "<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}" ], "testEnvironment": "jsdom", "testRunner": "C:\\Users\\skylm\\vscode\\blog\\client\\node_modules\\jest-circus\\runner.js", "transform": { "^.+\\.(js|jsx|mjs|cjs|ts|tsx)$": "<rootDir>/config/jest/babelTransform.js", "^.+\\.css$": "<rootDir>/config/jest/cssTransform.js", "^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js" }, "transformIgnorePatterns": [ "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$", "^.+\\.module\\.(css|sass|scss)$" ], "modulePaths": [], "moduleNameMapper": { "^react-native$": "react-native-web", "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy" }, "moduleFileExtensions": [ "web.js", "js", "web.ts", "ts", "web.tsx", "tsx", "json", "web.jsx", "jsx", "node" ], "watchPlugins": [ "jest-watch-typeahead/filename", "jest-watch-typeahead/testname" ], "resetMocks": true }, "babel": { "presets": [ "react-app" ] } } postDetail.js import React, { useEffect } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { Helmet } from 'react-helmet'; import { POST_DETAIL_LOADING_REQUEST, POST_DELETE_REQUEST, USER_LOADING_REQUEST } from '../../redux/types'; import { Col, Row, Button } from 'reactstrap'; // import {Col, Row, Button} from 'react-bootstrap'; import { CKEditor } from "@ckeditor/ckeditor5-react"; import { Link } from 'react-router-dom'; import { GrowingSpinner } from '../../components/spinner/Spinner'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import { faPencilAlt, faCommentDots, faMouse, } from "@fortawesome/free-solid-svg-icons"; import BalloonEditor from "@ckeditor/ckeditor5-editor-balloon/src/ballooneditor"; import { editorConfiguration } from '../../components/editor/EditorConfig'; const PostDetail = (req) => { const dispatch = useDispatch(); const { postDetail, creatorId, title, loading} = useSelector((state) => state.post); const { userId, userName } = useSelector((state) => state.auth); console.log(req, "postDetail REQ"); useEffect(() => { dispatch({ type : POST_DETAIL_LOADING_REQUEST, payload : req.match.params.id, }); //작성자만 삭제 버튼 보이게 dispatch({ type : USER_LOADING_REQUEST, payload : localStorage.getItem("token") }); }, []); const onDeleteClick = () => { dispatch({ //작성자만 게시글 삭제 type : POST_DELETE_REQUEST, payload : { id : req.match.params.id, toekn : localStorage.getItem("token") } }); }; const EditButton = ( <> <Row className="d-flex justify-content-center pb-3"> <Col className="col-md3 mr-md-3"> <Link to="/" className="btn btn-primary btn-block"> 홈 </Link> </Col> <Col className="col-md3 mr-md-3"> <Link to={`/post/${req.match.params.id}/edit`} className="btn btn-success btn-block"> 수정 </Link> </Col> <Col className="col-md3"> <Button className="btn-block btn-danger" onClick={onDeleteClick}> 삭제 </Button> </Col> </Row> </> ) const HomeButton = ( <> <Row className="d-flex justify-content-center pb-3"> <Col className="col-sm-12 com-md-3"> <Link to="/" className="btn btn-primary btn-block"> 홈 </Link> </Col> </Row> </> ); const Body = ( <> {userId === creatorId ? EditButton : HomeButton} <Row className="border-bottom border-top border-primary p-3 mb-3 d-flex justify-content-between"> {(() => { if (postDetail && postDetail.creator) { return ( <> <div className="font-weight-bold text-big"> <span className="mr-3"> <Button color="info"> {postDetail.category.categoryName} </Button> </span> {postDetail.title} </div> <div className="align-self-end">{postDetail.creator.name}</div> </> ); } })()} </Row> {postDetail && postDetail.comments ? ( <> <div className="d-flex justify-content-end align-items-baseline small"> <FontAwesomeIcon icon={faPencilAlt} /> <span> {postDetail.date}</span> <FontAwesomeIcon icon={faCommentDots} /> <span>{postDetail.comments.length}</span> <FontAwesomeIcon icon={faMouse} /> <span>{postDetail.views}</span> </div> <Row className="mb-3"> <CKEditor editor={BalloonEditor} data={postDetail.contents} config={editorConfiguration} disabled="true" /> </Row> </> ) : ( <h1>hi</h1> )} </> );; return ( <div> <Helmet title={`Post | ${title}`} /> {loading === true ? GrowingSpinner : Body } </div> ); }; export default PostDetail; header.js import React from 'react'; import {Row, Col} from 'reactstrap'; // import {Row, Col} from 'react-bootstrap'; const Header = () => { return ( <div id="page-header" className="mb-3"> <Row> <Col md="6" sm="auto" className="text-center m-auto"> </Col> </Row> </div> ) }; export default Header; server package.json { "name": "blog", "version": "1.0.0", "main": "index.js", "scripts": { "dev": "nodemon ./server/server.js --exec babel-node --ignore './client'" }, "author": "heymi", "license": "ISC", "keywords": [], "description": "", "dependencies": { "aws-sdk": "^2.1016.0", "babel-watch": "^7.6.0", "bcryptjs": "^2.4.3", "cors": "^2.8.5", "dotenv": "^8.2.0", "express": "^4.17.1", "helmet": "^3.22.0", "hpp": "^0.2.3", "jsonwebtoken": "^8.5.1", "moment": "^2.26.0", "mongoose": "^5.9.18", "multer": "^1.4.3", "multer-s3": "^2.10.0", "node-sass": "^6.0.1", "path": "^0.12.7", "sass-loader": "^12.2.0" }, "devDependencies": { "@babel/cli": "^7.10.1", "@babel/core": "^7.10.2", "@babel/node": "^7.10.1", "@babel/polyfill": "7.10.1", "@babel/preset-env": "^7.10.2", "babel-loader": "^8.1.0", "morgan": "^1.10.0", "nodemon": "^2.0.4" }, "repository": { "type": "git", "url": "git+https://github.com/jazzyfact/my-blog-site.git" }, "bugs": { "url": "https://github.com/jazzyfact/my-blog-site/issues" }, "homepage": "https://github.com/jazzyfact/my-blog-site#readme" }
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
이해2
1번째 했던 질문이랑 연결됩니다. 해당영상 11:30에 dispatch는 loginRequestAction 인데 11:34에서 LOG_IN_REQUEST의 액션이 실행되는 이유는 액션 생성기에서 먼저 와서 해당 type을 saga에서 찾는걸까요 ? 그리고 다시 saga의 리턴값을 data에 담아서 그걸 다시생성기로 가져가고 생성기에 type을 reducre에 action으로 전달하여 action case에 맞는 state로 store 변경 와 진짜 한 8번은 돌려본것같네요 ㅠㅠㅠ 힘드네요..
-
미해결스프링 기반 REST API 개발
안녕하세요 강사님. ObjectMapper가 @Autowired 못읽어오는데 어디서 잘못된건지 모르겠습니다.
안녕하세요. 강의 매우 잘 듣고 있습니다 ! 다름이 아니라 @WebMvcTest 을 빼고 @AutoConfigureMockMvc 를 사용했을 떄, @Autowired ObjectMapper objectMapper;이 쪽에서 에러가 발생하는데 어디쪽을 보면 될까요..?Could not autowire. No beans of 'ObjectMapper' type found.감사합니다.
-
미해결운영체제 공룡책 강의
안녕하세요 퀴즈 11 2번 문제 질문입니다.
안녕하세요, 좋은 강의를 올려주시고 질문도 이렇게 받아주셔서 먼저 감사합니다. 다름이 아니라 제가 퀴즈 11-2번(10.8)문제를 푸는데 LRU 알고리즘으로 페이지 부재를 계산하는데 이 과정에 있어서 질문 드립니다. 1 2 3 4 5 3 4 1 6 7 8 7 8 9 5 4 5 4 2 <- 이걸 계산하면 1o 2o 3o 4o 5o 3 4 1o 6o 7o 8o 7 8 9o 5o 4o 5 4 2o 이렇게 총 13번의 페이지 부재가 일어나는 것 아닌가요? 제가 뭔갈 착각하고 있는건지 모르겠어서 질문드립니다.
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
선생님 제가 이해한게 맞을까요 ?
지금 saga쪼개고 리듀서 연결하기 까지 본상태인데... 1. 이벤트등록 2. view에서 dispatch로 해당액션 호출 3. addPost함수실행 4. addPostApi 값실행 5. 결국엔 api값받아와서 addPost에서 해당값으로 트라이/캣츠 실행해서 해당 구문안에서 설정된 액션의 데이터를 data객체에 담아놓고 reducer에서 설정 정한 ADD_POST_SUCCESS란 액션생성기 이름이 있다면 이쪽으로 담은 data가오고 액션생성기 type에서 리듀서로 case retrun처리 state 변경