묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트
장고는 원래 서버가 잘 죽나요?
강사님 안녕하세요~ 서버가 잘 죽는데~ 실제로 장고를 배포하고 서비스를 24시간 7일 운영하려면 서버가 안전성이 있어야 하는데~ 혹시 코드를 안전하게 구현을 못해서 강습보며 따라할때 잘 죽는건가요? 아니면 장고 프래임워크로 짠 서버가 원래 잘 죽는건가요? 스프링보다 장고가 훨씬 시장이 작은데 강습보며 연습하다 서버가 잘 주는걸 보고 장고 웹 프레임워크가 성능이 안좋아서 장고 쓰는 회사가 스프링에 비해 적은건가? 라는 스스로 걱정이 있어서 질문드립니다~
-
미해결쉽고 빠르게 익히는 Excel 파워 쿼리
폴더 내 함께 합칠 수 있는 파일들의 컬럼이 조금씩 다를 때 병합 가능 여부
안녕하세요, 파워피벗 강의 듣다가 데이터 전처리가 필요한 것 같아 파워 쿼리 강의도 수강하게 되었습니다^^ 1. 폴더에 엑셀 파일1,2,3을 모아두었는데요. 이 중 2,3은 컬럼 항목이 완전히 동일한데 1은 대부분의 컬럼만 동일하나 (a,b,c 컬럼) 2,3에는 없는 일부 컬럼이 (d,e 컬럼) 추가되어 있습니다. 이 경우 1,2,3 파일을 하나의 파워 쿼리로 합치는 것이 불가한지요? 2. 파일 1,2,3이 합쳐진 쿼리가 존재하고, 파일 3에는 시트 1,2가 이미 병핟뵌 상태에서 만약 파일3에 시트3을 추가한다면 (새로운 데이터를 업데이트) 파워 쿼리에서 새로고침을 한다면 시트3도 기존 데이터에 추가가 될지요? 3. 파일 1,2,3이 합쳐진 쿼리가 존재하는 경우, 파일4를 기존 데이터에 함께 병합하고 싶다면 어떻게 해야 하나요? 답답하네요... 감사합니다 ㅜㅜ
-
해결됨공공데이터로 파이썬 데이터 분석 시작하기
질문있습니다.
pairplot을 사용하면 수치형 데이터 한정 짝을 이뤄서 그래프가 나오는 것까지는 이해했는데요! 연도/연도, 월/월, 분양가격/분양가격 <이렇게 짝을 이룬 그래프의 의미를 잘 모르겠습니다. 대충 짐작해서 생각해보기에 저는 그래프가 y=x 그래프의 선 상에서 sactter 형식으로 그 수치상에 데이터가 존재하는지의 여부를 나타내어주는게 최선이라고 생각했는데요 그와는 다르게 결과들이 나오는 것 같은데 이걸 x축의 데이터 값을 확인하고 해당 y의 수치를 확인- A 거꾸로 y축에서 데이터 값을 확인하고 해당 x의 수치를 확인 -B라고하면 A==B이어야 할 것 같은데 A와 B가 과연 같은지 잘 모르겠어서 질문드립니다 가령 막대그래프를 해석할때에도 A는 한눈에 들어오지만 B는 어떻게 해석에야 맞는건지 잘 모르겠습니다...
-
미해결[리뉴얼] React로 NodeBird SNS 만들기
검색 필터링 조건 관리 방법
안녕하세요 강좌 바탕으로 토이 프로젝트를 해보고 있습니다. 상품목록 페이지에 필터링 조건이 많이 있고, 검색어, 페이징처리까지 있습니다. 한가지 조건이 변경되었을때 다른조건은 유지하면서 새로 api조회를 해야할텐데 1. 상품목록page에서 조건들을 useState로 관리하고, 각 component에서 조건변경시 router push 쿼리 이용하여 목록페이지로 쏴주면 조건업데이트해서 조회 2. 리덕스에서 조건들을 관리하고 각 component에서 useDispatch, useSelector 사용 이런 경우 어느방법이 더 잘 쓰이고 효율적인지 조언 부탁드립니다. 감사합니다.
-
미해결[2026년 출제기준] 웹디자인개발기능사 실기시험 완벽 가이드
웹다지안기능사 용량 질문있습니다.
안녕하세요~ 웹디자인기능사 실기 제출파일 용량이 5메가가 초과되면 안되는데 제가 실습 다 하고 파일 총 용량이 5.31KB (5,439 바이트) 평균 이렇게 나오는데 이거 5메가 넘는건가요?? 인터넷에 검색해봐도 정확히 이해가 안되서 여쭤봅니다.
-
미해결쉽고 빠르게 익히는 Power BI 심화 1 (시각화와 파워 쿼리)
현재날짜를 기준으로 금월, 전월, 금분기 금액을 구하고 싶어요.
안녕하세요. POWER BI 보고서에서 현재 날짜(시간)을 기준으로 [금월 매출], [전월 매출], [전년 동월매출], [금분기 금액] 등만을 기준으로 표시하는 시각화 개체를 만들고 싶습니다. 슬라이서에 [월], [연도] 등을 선택한 채로 보고서를 저장하면 선택은 되어 있지만, 매월 다시 슬라이서를 바꿔서 다시 게시하는 불편함이 있어서 DAX식으로 작성해보려고 했습니다. 측정값으로 아래와 같이 [금월 매출] 수식을 넣어봤고, 작동하면 [매출]이 아니라 [금월 매출]로 데이터를 사용하면 될 것 같은데 오류가 나네요. 작성수식> 금월매출:=calculate([매출],'달력'[월 번호]=month(today()) && '달력'[년]=year(today())) 오류> 의미 체계 오류: 식에 여러 열이 포함되어 있지만 테이플 필터 식으로 사용되는 True/False 식에는 하나의 열만 사용할 수 있습니다. * 식 테스트는 power bi desktop이 아니라 엑셀에서 해보고 있습니다. 전일은 '달력'[Date]=(TODAY()-1) 라는 조건을 사용해서 계산이 되었는데, 이 경우 조건이 두개라서 에러인 것 같기도 한데 어떻게 해야할지 모르겠습니다. 좋은 강의 감사드립니다.
-
미해결따라 하다 보면 완성되는, Ionic 훑어보기
웹 개발을 위한 ionic
안녕하세요회사에서 ionic이 필요하여 급하게 강의를 찾다가 신청하게 되었습니다. 현재 구성이 ionic으로 되있는 웹 플랫폼 하나를 수정할 필요가 생겼는데 후에 android, ios앱으로 확장 가능성이 적은 웹 app 개발에도 ionic이 갖는 장점이 있을까요?
-
미해결문과생도, 비전공자도, 누구나 배울 수 있는 파이썬(Python)!
강의자료
강의자료는 다운 받았는데 강의 화면 처럼 어떻게 오픈 하나요??
-
해결됨자바스크립트 알고리즘 문제풀이 입문(코딩테스트 대비)
코드 중 질문 있습니다.
let pos=-1; for(let i=0; i<size; i++) if(x===answer[i]) pos=i; 이 부분 indexOf 내장함수 사용해도 괜찮은 걸까요? const pos = answer.indexOf(x) 이런식으로요 동일한 기능을 하는 것 같은데 내장함수를 사용해도 괜찮은지 질문드립니다.
-
해결됨따라하며 배우는 NestJS
password 암호화 시점
password 암호화 시점에 대해서 궁금한 점이 있어서 문의 드립니다. 현재 코드에서는 repository 내에서 암호화가 진행되는데 service 에서 암호화한 데이터를 보내는 게 아니라 repository에서 암호화를 진행하는 이유가 무엇일까요? repository가 DB와 연결되어서 관련 작업을 수행하는 역할로 보았을 때, service단에서 암호화를 진행한 뒤에 HashedPassword가 추가된 dto를 하나 추가로 만들어서 validation을 진행하고 repository에서는 데이터 저장하는 역할만 수행하는 것도 괜찮을 거 같다는 생각이 들어서 문의 납깁니다!
-
미해결시스템엔지니어가 알려주는 리눅스 실전편 Bash Shell Script
강의 교재를 공유해주실 수 있을까요?
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요? 제가 리눅스 강좌를 수강하고 있습니다. 리눅스 기초편과 활용편으로 듣고 있는데 강사님께서 강의하시는 교재가 있을까요? 가능하다면 공유해주시면 고맙겠습니다. 건강 조심하십시오. 감사합니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
@Transactional 어노테이션 롤백 관련 질문입니다.
안녕하세요 영한님. 퀄리티 좋은 강의 정말 잘 듣고 있습니다. JPA와 트랜잭션과 관련하여 혼자 공부하던 중 조금 이해되지 않는 부분이 있어 질문 올립니다. @Transactional 어노테이션의 경우 rollbackFor에 명시한 예외가 발생한 경우 롤백을 시키는 것으로 알고 있었고 해당 어노테이션도 수업때 배운 내용처럼 try {} catch(Exception e ) { tx.rollback(); } 처럼 처리되어 아래의 코드의 경우 외부 메소드와 내부 메소드 둘 다 에러 처리가 되어있지 않아 롤백 되어야 된다고 생각하였습니다. 하지만 결과는 team1, team2 둘 다 DB에 반영되어서 잘 이해가 되지 않아 조심스럽게 질문 올립니다. @Service@RequiredArgsConstructorpublic class TestService { private final EntityManager entityManager; @Transactional(rollbackFor = RuntimeException.class)public void transactionTest(){Team team1 = new Team(); team1.setTeamName("새로운 팀"); entityManager.persist(team1); entityManager.flush(); innerMethod();}@Transactional(rollbackFor = RuntimeException.class)public void innerMethod(){Team team2 = new Team(); team2.setTeamName("새로운 팀2"); entityManager.persist(team2); entityManager.flush(); throw new RuntimeException();}}
-
미해결프로그래밍 시작하기 : 파이썬 입문 (Inflearn Original)
예제파일이 어디에 있나요?
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
-
미해결[초급편] 안드로이드 커뮤니티 앱 만들기(Android Kotlin)
코틀린으로 작업하고
강의를 보면서 코틀린으로 작업하고 나중에 java로 변경해서 해봐도 그대로 되나요?? 아니면 코트 중에 .kt 이렇게 되어있는 부분들을 일일이 다 수정해야하나요???
-
미해결애플 웹사이트 인터랙션 클론!
캔버스 동작 오류
안녕하세요 강의 보면서 따라하던 도중 오류가 생겼는데 어떻게 해결을 해야할지 감이 안와서 질문 남깁니다.. 문제) case3 에서 캔버스가 그려지고 난후 clear가 되지 않아서 계속 겹쳐져서 그려짐 (아래 이미지 첨부) -> clearRect를 사용했더니 fillstyle이 적용안됨 ㅠㅠ 강의를 다시 돌려보면서 혹시 오타라도 났나 싶어 계속 오류를 찾아보고 있는데 발견을 못하겠습니다ㅠㅠ 이 경우에는 어떻게 접근해야 좋을까요? 아래 이미지는 검은색 영역이 그려지고 없어지지 않아서 이미지와 겹쳐있습니다. (이미지는png라서 배경을 따로 줬어요! 배경을 없애도 똑같네요 ㅠ) 근대 캔버스가 움직이는건 아무리 해도 모르겠네요 ㅠㅠ 참고! 가끔 아래서 새로고침후, 위로 올릴때만 정상적으로 동작합니다! 선생님 코드와 다른점 ) 영상을 사진으로 변화한것은 예제와 다른걸 썻는데 , 크기가 제각각이라 제가 임의로 heightRatio를 다르게 썻습니다. 그래서 스크롤을 빠르게 하거나 창크기가 바뀌면 하얀 부분이 나오는데 이거는 제가 다시 계산해서 할 수 있을꺼 같습니다. 그 외 나머지는 css가 조금 다른것 빼고 html, js부분은 똑같습니다. 아래쪽에 제 코드 첨부합니다 (() => { let yOffset = 0; //window.pageYOffset 대신 사용할 변수 let prevScrollHeight = 0; //현재 스크롤위치(yoffset)보다 이전에 위치한 스크롤 섹션들의 스크롤 높이의 합 let currentScene = 0; //현재활성화된 씬((지금 보고있는 스크린)(=scroll-section) let enterNewScene = false; //새로운 씬이 시작되는 순간 True (씬이 바뀔때 생기는 오류 방지변수) const sceneInfo = [ // 배열 객체는 4개를 만든다(섹션이 4개이기 때문) {//1 type:'sticky', //브라우저 높이의 5배로 scrollHeight 세팅 heightNum:5, // 스크롤높이 scrollHeight:0, objs: { container: document.querySelector('#scroll-section-1'), messageA: document.querySelector('#scroll-section-1 .main-message.a'), messageB: document.querySelector('#scroll-section-1 .main-message.b'), messageC: document.querySelector('#scroll-section-1 .main-message.c'), messageD: document.querySelector('#scroll-section-1 .main-message.d'), canvas: document.querySelector('#video-canvas-0'), context: document.querySelector('#video-canvas-0').getContext('2d'), videoImages: [] }, values: { videoImageCount: 313, imageSequence:[0, 312], canvasOpacity:[1,0,{start:0.9, end:1}], messageA_opacity_in:[0, 1, {start: 0.1, end: 0.2}], messageA_translateY_in:[20, 0, {start: 0.1, end: 0.2}], messageA_opacity_out:[1, 0, {start: 0.25, end: 0.3}], messageA_translateY_out:[0, -20, {start: 0.25, end: 0.3}], messageB_opacity_in:[0, 1, {start: 0.3, end: 0.4}], messageB_translateY_in:[20, 0, {start: 0.3, end: 0.4}], messageB_opacity_out:[1, 0, {start: 0.45, end: 0.5}], messageB_translateY_out:[0, -20, {start: 0.45, end: 0.5}], messageC_opacity_in:[0, 1, {start: 0.5, end: 0.6}], messageC_translateY_in:[20, 0, {start: 0.5, end: 0.6}], messageC_opacity_out:[1, 0, {start: 0.65, end: 0.7}], messageC_translateY_out:[0, -20, {start: 0.65, end: 0.7}], messageD_opacity_in:[0, 1, {start: 0.7, end: 0.8}], messageD_translateY_in:[20, 0, {start: 0.7, end: 0.8}], messageD_opacity_out:[1, 0, {start: 0.85, end: 0.95}], messageD_translateY_out:[0, -20, {start: 0.85, end: 0.95}], } }, {//2 type:'nomal', // 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'), messageA: document.querySelector('#scroll-section-3 .a'), messageB: document.querySelector('#scroll-section-3 .b'), messageC: document.querySelector('#scroll-section-3 .c'), pinB: document.querySelector('#scroll-section-3 .b .pin'), pinC: document.querySelector('#scroll-section-3 .c .pin'), canvas: document.querySelector('#video-canvas-2'), context: document.querySelector('#video-canvas-2').getContext('2d'), videoImages: [] }, values: { videoImageCount: 292, imageSequence:[0, 291], canvasOpacity_in:[0,1,{start:0, end:0.1}], canvasOpacity_out:[1,0,{start:0.9, end:1}], messageA_opacity_in: [0, 1, { start: 0.15, end: 0.2 }], messageA_translateY_in: [20, 0, { start: 0.15, end: 0.2 }], messageA_opacity_out: [1, 0, { start: 0.3, end: 0.35 }], messageA_translateY_out: [0, -20, { start: 0.3, end: 0.35 }], messageB_opacity_in: [0, 1, { start: 0.5, end: 0.55 }], messageB_translateY_in: [50, 30, { start: 0.5, end: 0.55 }], messageB_opacity_out: [1, 0, { start: 0.58, end: 0.63 }], messageB_translateY_out: [30, 0, { start: 0.58, end: 0.63 }], messageC_opacity_in: [0, 1, { start: 0.72, end: 0.77 }], messageC_translateY_in: [50, 30, { start: 0.72, end: 0.77 }], messageC_opacity_out: [1, 0, { start: 0.85, end: 0.9 }], messageC_translateY_out: [30, 0, { start: 0.85, end: 0.9 }], pinB_scaleY: [0.5, 1, { start: 0.5, end: 0.55 }], pinC_scaleY: [0.5, 1, { start: 0.72, end: 0.77 }], pinB_opacity_in: [0, 1, { start: 0.5, end: 0.55 }], pinC_opacity_in: [0, 1, { start: 0.72, end: 0.77 }], pinB_opacity_out: [1, 0, { start: 0.58, end: 0.63 }], pinC_opacity_out: [1, 0, { start: 0.85, end: 0.9 }] } }, {//4 type:'sticky', heightNum:5, scrollHeight:0, objs: { container:document.querySelector('#scroll-section-4'), canvasCaption: document.querySelector('.canvas-caption'), canvas: document.querySelector('.image-blend-canvas'), context: document.querySelector('.image-blend-canvas').getContext('2d'), imagePath: [ './images/mecolro.PNG', './images/IMG_1667.JPG' ], images: [], }, values: { rect1X: [0, 0, {start:0, end: 0}], rect2X: [0, 0, {start:0, end: 0}], rectStartY: 0, } } ]; function setCanvasImage(){ let imgElem; for (let i = 0; i < sceneInfo[0].values.videoImageCount; i++){ imgElem = new Image(); imgElem.src = `/video/myhome_30frame_4k/frame_${1 + i}.jpg`; sceneInfo[0].objs.videoImages.push(imgElem); }; let imgElem2; for (let i = 0; i < sceneInfo[2].values.videoImageCount; i++){ imgElem2 = new Image(); imgElem2.src = `/video/logo_30frame/frame_${1 + i}.jpg`; sceneInfo[2].objs.videoImages.push(imgElem2); }; let imgElem3; for (let i = 0; i < sceneInfo[3].objs.imagePath.length; i++){ imgElem3 = new Image(); imgElem3.src = sceneInfo[3].objs.imagePath[i]; sceneInfo[3].objs.images.push(imgElem3); }; }; setCanvasImage(); 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 == 'nomal'){ 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}`); // console.log(sceneInfo); let heightRatio = sceneInfo[currentScene].scrollHeight / 2160 / 3; // if(heightRatio > 0.7){heightRatio = 0.7;}; sceneInfo[0].objs.canvas.style.transform = `translate3d(-50%, -50%, 0) scale(${heightRatio})`; sceneInfo[2].objs.canvas.style.transform = `translate3d(-50%, -50%, 0) scale(${heightRatio})`; // console.log(currentScene); // console.log(heightRatio); }; function calcValues(values, currentYOffset){ let rv; const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset / scrollHeight; //star와 end의 애니메이션 실행 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; } 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; switch (currentScene){ case 0: let sequence = Math.round(calcValues(values.imageSequence, currentYOffset)); objs.context.drawImage(objs.videoImages[sequence],0 ,0); objs.canvas.style.opacity = calcValues(values.canvasOpacity, currentYOffset); if(scrollRatio <= 0.22){ objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else{ 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){ objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; } else{ 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){ objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; } else{ 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){ objs.messageD.style.opacity = calcValues(values.messageD_opacity_in, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_in, currentYOffset)}%, 0)`; } else{ 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: let sequence2 = Math.round(calcValues(values.imageSequence, currentYOffset)); objs.context.drawImage(objs.videoImages[sequence2],0 ,0); if(scrollRatio <= 0.5){ objs.canvas.style.opacity = calcValues(values.canvasOpacity_in, currentYOffset); } else{ objs.canvas.style.opacity = calcValues(values.canvasOpacity_out, currentYOffset); } if(scrollRatio <= 0.22){ objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else{ 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){ objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } else{ objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } if(scrollRatio <= 0.83){ objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } else{ objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } // case3에서 그려질 canvas를 case2에서 미리 동작하게 만들어주자 (코드는 반복, 수치만 살짝 바꿈) if(scrollRatio > 0.9){ // case2에서 사용되는 objs와 values값이 다르지만 if문을 통해 영역을 설정했으므로 const로 다시 선언해준다! const objs = sceneInfo[3].objs; const values = sceneInfo[3].values; const widthRatio = window.innerWidth / objs.canvas.width; const heightRatio = window.innerHeight / objs.canvas.height; let canvasScaleRatio; if(widthRatio <= heightRatio){ canvasScaleRatio = heightRatio; } else {canvasScaleRatio = widthRatio;} objs.canvas.style.transform = `scale(${canvasScaleRatio})`; objs.context.fillStyle = 'white'; objs.context.drawImage(objs.images[0],0 ,0); const canvasCalcWidth = document.body.offsetWidth / canvasScaleRatio; const whiteRectWidth = canvasCalcWidth * 0.2; values.rect1X[0] = (objs.canvas.width - canvasCalcWidth) / 2; values.rect1X[1] = values.rect1X[0] - whiteRectWidth; values.rect2X[0] = values.rect1X[0] + canvasCalcWidth - whiteRectWidth; values.rect2X[1] = values.rect2X[0] + whiteRectWidth; // 시작위치는 초기값으로 설정 (values.rectnX[0]) objs.context.fillRect( parseInt(values.rect1X[0]), 0, parseInt(whiteRectWidth), objs.canvas.height ); objs.context.fillRect( parseInt(values.rect2X[0]), 0, parseInt(whiteRectWidth), objs.canvas.height ); } break; case 3: let step = 0; // 가로세로 모두 꽉차게 하기 위해 여기에 세팅 (계산 필요) const widthRatio = window.innerWidth / objs.canvas.width; const heightRatio = window.innerHeight / objs.canvas.height; let canvasScaleRatio; if(widthRatio <= heightRatio){ canvasScaleRatio = heightRatio; // 캔버스보다 브라우저창이 홀쭉한 경우 } else {canvasScaleRatio = widthRatio;} // 캔버스보더 브라우저창이 납작한 경우 objs.canvas.style.transform = `scale(${canvasScaleRatio})`; objs.context.fillStyle = 'black'; objs.context.drawImage(objs.images[0],0 ,0); // 캔버스 사이즈에 맞춰 가정한 innerwidth와 innerheight const canvasCalcWidth = document.body.offsetWidth / canvasScaleRatio; const canvasCalcHeight = window.innerHeight / canvasScaleRatio; if(!values.rectStartY){ values.rectStartY = objs.canvas.offsetTop + (objs.canvas.height - objs.canvas.height * canvasScaleRatio)/2; values.rect1X[2].start = (window.innerHeight /2) / scrollHeight; values.rect2X[2].start = (window.innerHeight /2) / scrollHeight; values.rect1X[2].end = values.rectStartY / scrollHeight; values.rect2X[2].end = values.rectStartY / scrollHeight; } // 캔버스 폭 넓이 조절 const whiteRectWidth = canvasCalcWidth * 0.2; values.rect1X[0] = (objs.canvas.width - canvasCalcWidth) / 2; values.rect1X[1] = values.rect1X[0] - whiteRectWidth; values.rect2X[0] = values.rect1X[0] + canvasCalcWidth - whiteRectWidth; values.rect2X[1] = values.rect2X[0] + whiteRectWidth; objs.context.fillRect( parseInt(calcValues(values.rect1X, currentYOffset)), 0, parseInt(whiteRectWidth), objs.canvas.height ); objs.context.fillRect( parseInt(calcValues(values.rect2X, currentYOffset)), 0, parseInt(whiteRectWidth), objs.canvas.height ); console.log(parseInt(calcValues(values.rect1X, currentYOffset))); //캔버스가 브라우저 상단에 닿은 경우부터 이미지 블랜드된 후 다시 스크롤되는 것을 3단계 step으로 나눈다 if(scrollRatio < values.rect1X[2].end / 9){ //캔버스가 브라우저 상단에 닿지 않은 단계 step = 1; console.log('before') objs.canvas.classList.remove('sticky'); } else { //이미지가 블랜드되고 스케일이 조정되는 단계까지 step = 2; console.log('after') objs.canvas.classList.add('sticky'); objs.canvas.style.top = `${-(objs.canvas.height - objs.canvas.height * canvasScaleRatio)/2}px`; // if(){ // //스케일 조정되고 다시 스크롤 되는 단계 // step = 3; // }; }; break; } // console.log(currentScene); } 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('load', () => { setLayout(); sceneInfo[0].objs.context.drawImage(sceneInfo[0].objs.videoImages[0],0 ,0); }); //DOMContentLoaded 도 많이사용 (이미지가 로딩안되도 로딩시키는 매서드) 하지만 여기서는 이미지가 중요하기 때문에 로드를 사용한다 window.addEventListener('resize',setLayout); })();
-
미해결파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트
코드 for문을 이용해 포스팅 업로드시 발생하는 에러
안녕하세요 강사님 "장고 기본 CBV API (Generic display views) (2)" 보며 강사님과 같이 포스트를 여러개 만들기 위해서 for문을 이용했는데요~ 위와 같은 에러가 떠서 구글링을 해봤지만 찾지 못했는데 혹시 해결할 수 있는 힌트가 있을까요? 감사합니다..
-
미해결[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버
안녕하세요 궁금한 점이 있어 질문 드립니다
1. 소켓 송수신 버퍼가 실제로 TCP 단에서 다루는 버퍼가 되는 것인가요? 2. send() 함수가 실패하는 경우는 송신 버퍼가 가득 차는 경우인데 수신 측에서 recv를 하지 않는 경우를 제외하고 어떤 경우에 실패하는지 너무 궁금합니다. 3. 실제로 유저 애플리케이션 계층에서 송신 데이터가 많다고 할 때 TCP가 어느 정도 속도로 송신버퍼를 비우는지(얼마나 빨리 보내주는지) 알기 위해서 어떤 정보를 확인해야 될까요?
-
미해결따라하면 취업되는 게임기획 강의!
시스템 구조도
게임초보라서 시스템 구조도가 잘 와닿지 않는데요 일반 it프로젝트 시스템 아키텍쳐의 클래스 다이어그램과 연결지을 수 있을까요? 어떻게 생각해야 할까요
-
미해결Vue.js 시작하기 - Age of Vue.js
v-model 한글
좋은 강의 감사합니다! 질문이 있어 글 남깁니다. <input v-model="message" type="text" /> <p>{{ message }}</p> 강의대로 위와같이 코드를 짰고, 영어는 input에 치는 즉시 아래에 잘 나옵니다! 다만 한글은 바로 나오지가 않고 엔터를 누르거나 영어를 입력해야 아래에 뜹니다ㅠㅠ 왜 이런 문제가 발생하는지 궁금합니다!!
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
index.html 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. MemberListServlet에서 강의와 동일하게 w.write("<a href=\"/index.html\">메인</a>"); 이렇게 했는데 회원 등록 후 "메인"을 누르면 http://localhost:8080/index.html 이것이 아닌 http://localhost:8080/servlet/members/index.html 여기로 이동하면서 오류 화면이 나옵니다. 코드는 동일하게 했는데 어디서 문제가 발생 한건가요?