묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
build 방법에 관해 질문 드립니다.
좋은 강의 감사한 맘으로 열심히 듣고 있습니다.빌드에 관한 질문을 드립니다. 강의를 빌드해서 깃헙의 웹 서비스에서 뛰어보려고 하는데현재 프로젝트 구조가 client / server로 되어 있고build script는 client의 package.json에만 정의 되어 있습니다. 이런 경우는 어떻게 빌드를 해야 하는지 알려주시면 감사하겠습니다.. 바쁘시겠지만 답변 부탁 드리겠습니다.
-
미해결윤재성의 Java 기반 Android 9.0(pie) App 개발 고급 3단계
에러
Unable to start activity ComponentInfo{com.cartris.a1201_draw_layout/com.cartris.a1201_draw_layout.DrawLayoutActivity}: android.view.InflateException: Binary XML file line #15 in com.cartris.a1201_draw_layout:layout/activity_draw_layout: Binary XML file line #19 in com.cartris.a1201_draw_layout:layout/content_draw_layout: Error inflating class fragment이런 에러가 뜹니다 왜 그런걸까요?? activity_draw_layout 에 있는 코드 내용은 아래와 같습니다 <?xml version="1.0" encoding="utf-8"?><androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:openDrawer="start"> <include android:id="@+id/app_bar_draw_layout" layout="@layout/app_bar_draw_layout" android:layout_width="match_parent" android:layout_height="match_parent"/> <com.google.android.material.navigation.NavigationView android:id="@+id/nav_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" android:fitsSystemWindows="true" app:headerLayout="@layout/nav_header_draw_layout" app:menu="@menu/activity_draw_layout_drawer" /></androidx.drawerlayout.widget.DrawerLayout>content_draw_layout 에 있는 코드 내용은 아래와 같습니다 <?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:showIn="@layout/app_bar_draw_layout"> <fragment android:id="@+id/nav_host_fragment_content_draw_layout" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:navGraph="@navigation/mobile_navigation" /></androidx.constraintlayout.widget.ConstraintLayout>
-
미해결모든 개발자를 위한 HTTP 웹 기본 지식
Host, Port
안녕하세요, 복습 중에 궁금해서 질문글을 올립니다. 아래 질문글들을 다 봤는데요, Host를 찾고 그 안에서 다시 port를 찾는 것이라면 aaa.com 의 포트번호 100번에 배달의 민족 주문 서비스(하나의 .jar파일 실행이라고 가정) bbb.com 의 포트번호 100번에 카카오 선물하기 서비스 이런식으로 따로 연결이 된다는 말씀이신거죠? 그렇다면 200.200.200.2의 포트번호 100에는 또다른 프로그램(서비스)을 연결할 수가 있는 것인가요?
-
미해결파이썬/장고 웹서비스 개발 완벽 가이드 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가 어느 정도 속도로 송신버퍼를 비우는지(얼마나 빨리 보내주는지) 알기 위해서 어떤 정보를 확인해야 될까요?