묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결[개정판] 딥러닝 컴퓨터 비전 완벽 가이드
MMdetection으로 학습한 모델 윈도우에서 사용 문의 및 기타 질문이 있습니다
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요 드디어 Mask RCNN 까지 들었습니다 (중간에 남은게 있지만... ㅠㅠ) 선생님 덕분에 Detection의 전반과 훈련 inference까지 이해하게 되어 정말 감사드립니다 1. 저 같은 경우 서비스를 제공하는데 엔드유저가 윈도우를 사용하기 때문에 아무래도 윈도우에서 적용이 가능하게끔 만들고 싶습니다. 현재는 텐서플로 기반이라 Pyqt로 로컬프로그램을 만들어 제공하고 있는데 MMDetection이 리눅스에서만 적용되어서 로컬 프로그램으로는 한계가 있을까요? 이를테면 MMDetection이나 Detectron으로 만든 모델만 Pytorch로 불러온다든지 그런 사례가 있는지 궁금합니다 AWS로 웹서버를 구축하는 법도 있겠지만 보안문제도 있고 그쪽 지식은 부족해서 여쭈어 봅니다 2. 또한 Detection 모델은 여러가지 물체는 한번에 잡지만 visualization을 할때는 for 문을 쓸수밖에 없는 구조인가요? 만약 물체가 1000개씩 있으면 오히려 visualization이 병목이 될 수도 있을 것 같은데 제가 이해한 것이 맞는지 문의드립니다 멀티프로세싱 같은 것을 통해 잡아야 하는것인가요? 3. 마지막으로 강의에서는 MMdetection으로 faster rcnn이나 mask rcnn을 다뤄주셨는데 solo, yolact를 비롯한 다른 최신 모델들도 포함되어 있어서 좋은 것 같습니다 이런 최신 모델들도 cfg만 바꾸어 사용하면 되나요? yolact를 사용해봤는데 debuging을 해봐야겠지만 training 이후 여러 이미지 inference에서 문제가 있는거 같아 혹시 MMdetection이 faster rcnn, mask rcnn 계열에만 최적화 되어있는지 아님 다른 모델을 적용할 때 주의사항이 있는지 문의드립니다 항상 감사드립니다!!
-
미해결파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트
브라우저에서 회원가입시 SMTP 에러가 발생합니다
안녕하세요? 벌써 두번째 인사드리는 것 같은데, 몇번이나 인사를 드릴까봐 겁나네요 ㅠㅠ 우선 그전 강의의 끝에서 마지막까지 진행한 후, 회원가입을 했을 때 다음과 같은 에러가 발생합니다 아마 메일이 발송될 수 없다는 것 같은데요 쉘에서는 다음과 같이 발송이 됩니다. 실제로 제 메일로 발송된 것을 확인했습니다. 아마 문제가 실제 브라우저에서 회원가입시 문제가 되는 부분이, env.bat파일때문이지 않을까 추측하고 있습니다.(윈도우 환경입니다) 일단 env.bat파일을 다음과 같이 만들어 두었습니다 set SENDGRID_API_KEY=SG.-sXxPoBP~ 그냥 sendgrid_api_key만 적어두니까 env.bat이라는 cmd명령어를 실행했을 떄, 실행이 되지 않더라구요.. 아무튼 제 추측이 맞다면, 항상 저 명령어가 실행되도록 해서 API_KEY를 가지고 있도록 해야할 것 같은데.. ㅠㅠ 답변 부탁드리겟습니다 ㅠㅠ 늘 좋은 강의와 성실한 답변 감사합니다.
-
미해결프론트엔드 개발자를 위한, 실전 웹 성능 최적화(feat. React) - Part. 1
강의와 다르게 성능측정이 발생하는 현상
안녕하세요. 다름이아니라 강의시청중에 build된 파일 성능측정하는데 검사결과가 다르게 측정되어서 질문드립니다.
-
미해결딥러닝 CNN 완벽 가이드 - TFKeras 버전
모델에 대하여 질문이 있습니다.
Dog image classification을 하는데 모델을 Xception과 EfficientNet b0, b1 으로 예시를 보여주셨는데요. VGG, ResNet, Inception, MobileNet, DenseNet, NASNetMobile 의 다른모델들도 있는데 Xception 과 EfficientNet b0, b1 을 개 이미지 사진 분류에 사용하신 이유가 있으시면 좀 알려주셨으면 합니다. 그리고 EfficientNet 모델 종류가 b0~b7 까지 있더라구요. 차이점이 어떻게 되는지요? 수업 잘듣고 있습니다. 감사합니다!
-
미해결비전공자를 위한 개발자 취업 올인원 가이드 [통합편]
개발을 잘한다의 기준을 잘 모르겠습니다!
안녕하세요 비전공자이고 프론트엔드 개발자를 희망하고 있습니다. 개발을 시작한지는 2달정도 됐습니다. 현재 부트캠프를 참여 중이에요. 참여한지 얼마 안됐지만 의문점이 생겨서 질문을 올리게 됐습니다. 1. 개발을 잘하는 기준이 무엇인가요? 제목과 같습니다. 현재 부트캠프의 한 일화를 말씀드리고 싶은데요. 과제가 주어졌고 클론코딩을 진행하고 있습니다. 필수로 수행해야하는 기능구현과 앞의 필수기능을 모두 구현했다면 추가 기능을 구현하게 되는데요. 벌써부터 주위에 잘하시는 분들은 필수, 추가 기능 모두 완료하고 다음 과정을 대비해서 예습을 진행하고 있어요. 저는 조급함에 구글을 통해서 찾아보다가 비슷한 코드가 있으면 "이 코드를 왜 이렇게 작성했는지"라는 생각보단 "지금 과제의 기능구현에 초점"을 두고 과제를 하고 있다는 생각이 듭니다. 그래서 지금 과제를 필수구현만 모두 완료하고 추가기능은 몇 가지하되, 전체적인 코드의 지저분한 점들, 변수명 함수명 또는 더 직관적인 코드로 변경시켜보는 과정을 해보고 싶은데요. 정수님의 생각이 궁금합니다. 속도를 내서 따라가는게 맞는건지, 아니면 나의 페이스를 유지하되, 구글 검색 등을 통해 코드를 베끼는게 아니라 그 코드를 참고해서 내 코드의 근거를 마련하는 방향으로 학습해야할지. 어떻게 생각하시는지 답변부탁드립니다. 그리고 정수님께서 잘하는 분들과의 비교가 될 때가 있으셨는지요, 어떻게 생각하시고 방향을 어떻게 정하셨는지도 궁금합니다. 질문이 좀 무례했다면 죄송합니다. 정수님의 생각이 궁금해서 여쭤보게 됐어요! 강의는 잘보고 있습니다. 정성이 가득담긴 강의라서 한번보고 두번 세번 찾게 되는 파트도 있네요 ㅎㅎ 감사합니다!
-
미해결모든 개발자를 위한 HTTP 웹 기본 지식
get에 쿼리파라미터가 있으면 캐시는 어떻게 처리되나요?
get은 uri를 키로 사용하니까 쿼리 파라미터가 있더라도 uri로 캐시를 하나요? /members/sort=desc&page=1 이럴 경우
-
미해결파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트
form의 메소드 // 7장이후의 강의내용에 대해 질문드립니다.
안녕하세요? 늘 좋은 강의와 친절한 답변에 대해서 감사드립니다 1. form에 대해서 질문드립니다 def signup(request): if request.method == 'POST': form = SignupForm(request.POST) #signupform의 인스턴스 생성 if form.is_valid(): form.save() messages.success(request,"회원가입을 환영합니다") next_url=request.GET.get('next','/') #Get메소드로 들어왔을 때, next라는 인자가 있으면 그걸 가져오고, 없으면 그냥 /를 가져온나 return redirect(next_url) else: form = SignupForm() return render(request,'accounts/signup_form.html',{'form':form}) 위에서 보면 첫번째 if문에서 메소드가 post일 경우 내용을 처리해주는 것 같은데요 그 바로 밑에보면 request.Get.get이 있습니다. GET메소드에서 next가 있으면 들고오고 없으면 /를 반환하라는 것 같은데, 어째서 가능한지 모르겠습니다 ㅠ POST와 GET메소드 요청이 함께 올 수 있나요? 2. 7장 이후의 (즉 8장부터)강의 내용에 대해 질문드릴려고 합니다. 현재 7장을 들으면서 인스타그램을 만들어보고 잇습니다만 ㅠㅠ 허덕이는 제자신을 보니 아무래도 강의를 여러번 들으면서 다시 정리를 해야겠다는 생각이 많이 듭니다. 저는 4월초에 백엔드 개발자가 되기 위한 부트캠프를 들어가는데요, 그전까지 선생님의 강의로 장고를 좀 잘다듬고 싶은 마음이 있습니다. 다만 지금 제 수준을보니.. 시간이 많이 걸릴 것 같아 선택을 해야만 할 것 같습니다.ㅠㅠ 11장, 배포에 관한 부분은 부트캠프를 다니면서 나중에 들을 생각이구요 지금 고민이 되는 부분이 , 강의를 끝까지 완강을 하고 전체강의를 한두번 더들을지, 혹은 특정강까지만 강의를 듣고 그까지 3-4회정도 반복을 할까 고민중입니다. 8,9,10장의 내용이 백엔드 개발자로서, 프론트가 어떤식으로 돌아가는지 알 수있는 반드시 필요한 내용이라거나 혹은 어차피 DRF(뭔진 잘 모르겠지만 ㅠ)와 같은 기능을 장고개발자로서 반드시 쓸 수 밖에 없다면 , 앞의 내용(1~7장까지)에 조금 소홀해지더라도 10장까지 강의를 듣고 나서 2회정도 다시 강의를 들을 생각입니다. 하지만 그렇지 않다면 8장 정도까지만 강의를 듣고, 처음부터 8장정도까지 3-4회정도 반복을 하면서 좀 탄탄하게 다지고 싶은 마음이 큽니다.(선생님의 강의를 허덕이면서 따라가는 제자신을 보니, 기초적인 내용을 반복하고 싶다는 마음이 좀 가득합니다 ㅠㅠ) 서론이 너무 길었네요. 질문을 요약하면, 9-10장의 내용이 혹시 백엔드개발자로서 뗄수 없는 부분인가? 인듯 합니다.정답은 없는 부분일지도 모르지만, 선택을 위한 조언을 구합니다 ㅠㅠ 초조한 마음에 실례되는 질문을 드린게 아닐까 걱정이되네요. 늘 좋은 강의와 답변 감사합니다.
-
해결됨스프링 기반 REST API 개발
HATEOAS 방식에서 ResponseEntity .notFound() 반환처리 질문입니다.
아무도 안물어보시는것 같아서, 묻게되었습니다.영상 7분 9초 경 - 영상에 없는 "추가적인 NOT_FOUND 반환값"을 갖도록 해서, 문서처리를 하려고합니다이는, ResponseEntity.notFount() 반환값이, HeadersBuilder 인터페이스 타입이라서..ResponseEntity.HeadersBuilder이 경우 body(..) 가 없고, header( .. ) 만 있는데, 본문을 담을 수 없습니다. 그래서 Header 만 추가되도록 구성해야 하는데요, 학생들에게 구현하도록 두신건지,너무 간단해서 언급 안하신건지, 구현하려고 하니 검색자료가 잘 나오질 않아 해매고 있습니다.질문입니다HATEOAS 의 경우, 이런 부분은 일반적으로 어떻게 처리가 되는지요?아래 코드에서 ".header(HttpHeaders.?, ...?)"에 Location 속성에 경로값 설정만 하면 될까요?@GetMapping("/{id}") public ResponseEntity getEvent(@PathVariable Integer id) { var dtoOut = eventRepository.findById(id)... if (dtoOut.isEmpty()) return ResponseEntity .notFound() .header(HttpHeaders.??, ...???) <<< .build(); ... return ResponseEntity.ok(...) }또는, 구현할 필요가 없나요? (HATEOAS 가 전후방 이동경로를 제공하는 메커니즘이라면, 이 경우에도 방향을 잃지 않도록 제공해야 할까요? 아니면 필요가 없나요? 또는 redirect.. )궁금합니다
-
미해결[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part2: 자료구조와 알고리즘
#region 문제
코드를 똑같이 작성하고 실행을 해보니 아무것도 화면에 출력되지 않아 강의 목차에 오른손 법칙 강의에 올려주신 파일을 다운받아 코드를 돌려봐도 똑같이 아무것도 화면에 출력되지 않았습니다. 혹시몰라 #region 프레임관리 부분을 주석처리 하고 실행을 해보니 정상 출력이 되었는데 왜그런지 알 수 있을까요?
-
미해결자바스크립트 비기너: 튼튼한 기본 만들기
Object vs object
안녕하세요! 강의를 듣다가 이해가 되지 않아서 처음부터 돌려 보고 있는데 대문자/소문자 오브젝트가 계속 잘 이해가 되지 않아 질문드립니다. 저는 대문자 오브젝트는 데이터 저장을 위한 프로퍼티 집합이고, 소문자 오브젝트는 데이터 처리를 위한 프로퍼티 집합이라고 이해했습니다. 대문자/소문자 오브젝트 모두 구조는 key: value (프로퍼티)로 이루어져 있지만, 데이터 저장을 위한 것 VS 데이터 처리를 위한 것을 구분하기 위해 선생님께서 대문자 VS 소문자 오브젝트를 구분하셨다고 이해했습니다. (제가 이해한 게 맞나요?...) 그런데 Number object 파트에서 아래처럼 new 연산자를 설명하실 때, var obj = new Number(); console.log(typeof obj); 생성된 인스턴스 type을 찍어보면 object로 나오는데, 이 type이 소문자 오브젝트라고 하신 게 이해가 안 됩니다. 소문자 오브젝트를 복사한 개념이니까 소문자 오브젝트라고 하신 걸까요? console.log(typeof { lang: "JS" }); 이것도 type은 똑같이 object가 나오는데, 이건 데이터 저장 목적이 있는 대문자 오브젝트이니까, 대문자 오브젝트 type이다 라고 하면 맞는 설명인가요? 감사합니다.
-
해결됨모든 개발자를 위한 HTTP 웹 기본 지식
[no-cache]프록시 캐시가 없을 경우 및 관련 질문
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]http 강의를 다 듣고 나서 새로운 세계가 열렸습니다. 너무 감사 드립니다. 강의에서 말씀하시는 프록시 캐시가 프록시 서버 캐시를 말씀하시는 것으로 이해 됩니다. 첫번째 질문은, 캐시에는 웹캐시(브라우저)가 있는 것으로 알고 있는데 no-cache를 사용했을 경우에 프록시 캐시(서버)가 없을 경우에는 웹캐시에서 원 서버에 확인하는 것인지 궁금합니다. 두번째 질문은, http강의를 모두 듣고 배민 공홈은 어떻게 사용하나 궁금해서 들어 가봤는데 js, css 및 이미지는 amazon S3를 사용하고 있었습니다. 아마 별도 프록시 서버가 없는 것으로 보입니다. ( 그렇게 생각한 이유는 '임시 헤더가 표시됩니다. 전체 헤더를 보려면 캐시를 사용 중지하세요' 문구가 없어서 입니다. ) 모두 다 no-cache는 사용하지 않는 것으로 보였고 상태 코드는 200이었습니다. 원격 주소는 동일한데 어떤 것은 200 ( 디스크 캐시에서)가 붙어 있고 어떤 것은 없었습니다. 이 둘의 차이가 무엇인지 궁금합니다. ( 구글을 살펴봤을 때 일부 캐시의 경우 200 OK (메모리 캐시에서)라고 적혀 있었습니다. ) 두번째 질문에 이어서 세번째 질문입니다. no-cache를 사용하는 부분은 https://www.google-analytics.com를 호출하는 부분이었습니다. 아마 사용자 행동 분석 태깅을 위함인 것 같은데 해당 부분은 post로 호출되었습니다. post 호출은 조회가 아닌 수정, 저장 등을 위함으로 알고 있는데 왜 캐시 관련된 ( cache-control: no-cache, no-store, must-revalidate )된 부분을 response로 내려 주는지 궁금합니다.\s 감사합니다.
-
미해결애플 웹사이트 인터랙션 클론!
이미지가 안보입니다...ㅠ(도움이 필요합니다!! 꼭 봐주세요!)
안녕하세요 선생님 강의 잘 듣고 있습니다! 다름이 아니라 밑에 수강생분 처럼 저도 이미지가 안보이고 Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLCanvasElement or HTMLImageElement or HTMLVideoElement or ImageBitmap or OffscreenCanvas or SVGImageElement or VideoFrame)'. 이런 에러가 계속 뜨는데.. 어떻게 해야할지 모르겠습니다..ㅠㅠㅠ 분명 계속 이미지 경로도 확인하고 문제가 없는거같은데...대체 뭐가 문제인지 도움이 필요합니다..!! 너무 해결이 안되니까 꼭...해결하고싶습니다.. 잘되던 텍스트 애니메이션도 작동이 안됩니다. 보니까 playanimaion함수에서 sequence도 console.log에 찍으면 undefined로 찍히는데 도저히 뭐가 잘못 됐는지 모르겠습니다. 선생님이 주신 완성 코드를 대입해도 안뜨네요ㅠㅠㅠ (() => { let yOffset = 0; // window.pageYOffset대신 쓸 변수 let prevScrollHeight = 0; //현재 스크롤 위치(yOffset)보다 이전에 위치한 스크롤 섹션들의 높이값의 합 let currentScene = 0; //현재 활성화된(눈 앞에 보고있는) 씬(scroll-section) // sceneInfo는 애니메이션을 처리하는 정보를 담아놓는 변수 let enterNewScene = false;//새로운 scene이 시작되는 순간 true로 바뀜 const sceneInfo = [ { //0 type: 'sticky', heightNum:5,//브라우저 높이의 5배로 scrollHeight 세팅 scrollHeight: 0, // 애니메이션을 조작할 오브젝트를 objs에 담음 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객체의 메서드인 getContext를 인자 2d를 넣어 호출해 그림을 그려주는 기초를 연다. context: document.querySelector('#video-canvas-0').getContext('2d'), //비디오 이미지를 배열에 넣을 예정이다. videoImages: [] }, //오브젝트를 어느시점에 보이고 안보이게 할지를 담을 곳 css제어 //시작값 :0 끝값 :1 values: { videoImageCount: 300, //스크롤에 따른 이미지 순서의 [초기값,최종값] messageA와 다르게 섹션의 부분에서 실행될 이미지가 아닌 한스크롤에서 쭉 이어지므로 start,end구간이 필요없다 imageSequence:[0 , 299], messageA_opacity_in: [0, 1, { start: 0.1, end: 0.2 }], messageB_opacity_in: [0, 1, { start: 0.3, end: 0.4 }], //30%~ 40% messageC_opacity_in: [0, 1, { start: 0.5, end: 0.6 }], messageD_opacity_in: [0, 1, { start: 0.7, end: 0.8 }], // 글자를 20%에서 0으로 가는건데 %는 css에 나중에 작업할 예정 세번째 인수에는 타이밍이 들어간다(=어느 타이밍에 효과를 줄것인가) 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 }] // messageA_opacity:[200,900] } }, { //1 type: 'normal', //heightNum은 scrollHeight를 결정할 때 innerheight의 몇배로 할지 정해주는 수 였는데 normal은 원래 본인 default높이로 설정하므로 필요가 없다 // heightNum:5, scrollHeight: 0, objs:{ container: document.querySelector('#scroll-section-1') } }, { //2 type: 'sticky', heightNum:5, scrollHeight: 0, objs:{ container: document.querySelector('#scroll-section-2'), 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.5, end: 0.55 }], messageC_translateY_in: [30, 0, { start: 0.72, end: 0.77 }], messageA_opacity_in: [0, 1, { start: 0.15, end: 0.2 }], messageB_opacity_in: [0, 1, { start: 0.5, end: 0.55 }], messageC_opacity_in: [0, 1, { start: 0.72, end: 0.77 }], messageA_translateY_out: [0, -20, { start: 0.3, end: 0.35 }], messageB_translateY_out: [0, -20, { start: 0.58, end: 0.63 }], messageC_translateY_out: [0, -20, { start: 0.85, end: 0.9 }], messageA_opacity_out: [1, 0, { start: 0.3, end: 0.35 }], messageB_opacity_out: [1, 0, { start: 0.58, end: 0.63 }], messageC_opacity_out: [1, 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 }] } }, { //3 type: 'sticky', heightNum:5, scrollHeight: 0, objs:{ container: document.querySelector('#scroll-section-3') } } ]; function setCanvasImages() { let imgElem; for (let i = 0; i < sceneInfo[0].values.videoImageCount; i++){ //이미지 객체가 만들어짐 new Image(); 대신에 document.createElement('img')랑 같은말이다. imgElem = new Image(); imgElem.src = `./video/001/IMG_${6726 + i}.JPG`; sceneInfo[0].objs.videoImages.push(imgElem); } } setCanvasImages(); 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') { //container본연의 높이로 가져와서 그 크기만큼으로만 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}`); // console.log(sceneInfo); //초기화 할 때 실행되는 setLayout은 currentScene이 정해지지 않은 상태에서 currentScene을 구하는 것이고, // 스크롤 할 때마다 실행되는 scrollLoop는 현재 활성화된 currentScene 까지의 스크롤양(prevScrollHeight)을 기준으로 일정량의 스크롤이 지나갔을 때 currentScene을 +1 또는 -1 하는 것이랍니다. } function calcValues(values, currentYOffset) { //여기서 인자 currentYOffset은 현재 씬에서 얼마나 스크롤 됐는지 //현재 섹션에서 얼마나 스크롤 되었는지를 비율로 구한다 스클로의 비율을 0~1사이로 정한다. 비율을 구해서 그 값을 css값에 대입해준다. //yoffset변수는 전체 레이아웃에서 스크롤이 어디 위치해있는지 알려주는 변수이다. 현재 씬에서 스크롤이 얼마나됐는지는 알 수 없다. let rv; const scrollHeight = sceneInfo[currentScene].scrollHeight; //현재 씬(스크롤섹션)에서 스크롤된 범위를 비율로 구하기 ==>let scrollRation = 현재 씬에서 스크롤된 값 / 현재 씬 전체 const scrollRatio = currentYOffset / sceneInfo[currentScene].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) { //스크롤섹션에서 스크롤이 start에 도달하지 못했을 때 rv = values[0]; //opacity가 0이라는 뜻 } else if (currentYOffset > partScrollEnd) { //스크롤섹션에서 스크롤이 end를 완전히 벗어났을 때 rv = values[1]; //opacity가 1이라는 뜻 } else { rv = scrollRatio * (values[1] - values[0]) + values[0]; } // rv = parseInt(scrollRatio * (values[1] - values[0]) + values[0]); return rv; } } //애니메이션 함수 function playAnimation() { // 모든 섹션에 애니메이션을 주는 것은 비효율적이므로 switch문을 이용해서 현재 보고있는 섹션의 요소에만 애니메이션을 준다 const objs = sceneInfo[currentScene].objs; const values = sceneInfo[currentScene].values; const currentYOffset = yOffset - prevScrollHeight; const scrollHeight = sceneInfo[currentScene].scrollHeight; const scrollRatio = currentYOffset / sceneInfo[currentScene].scrollHeight; switch (currentScene) { case 0: let sequence = calcValues(values.imageSequence, currentYOffset); objs.context.drawImage(objs.videoImages[sequence], 0, 0); console.log(sequence); 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.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: // console.log('3 play'); break; } } // keyframe이란: 애니메이션이 진행중에 변화가 있는 지점을 keyframe이라고 한다. function scrollLoop() { enterNewScene = false; prevScrollHeight = 0;//누적을 막기 위해서 // 현재 보고잇는 section이 몇번째 section인지 판별하려고함 for (let i = 0; i < currentScene; i++){ prevScrollHeight = prevScrollHeight + sceneInfo[i].scrollHeight; } // console.log(prevScrollHeight); if (yOffset > prevScrollHeight + sceneInfo[currentScene].scrollHeight) { enterNewScene = true; currentScene++; document.body.setAttribute('id', `show-scene-${currentScene}`); // setLayout함수에서 이미 id값이 정해져있지만 스크롤에 변함에 따라 체크하는 방식으로 쓴다 } if (yOffset < prevScrollHeight) { if (currentScene === 0) return;//브라우저 바운스 효과로 인해 마이너스가 되는 것을 방지(모바일) enterNewScene = true; currentScene--; document.body.setAttribute('id', `show-scene-${currentScene}`); } // console.log(currentScene); // enterNewScene이 참이라는것은 씬이 바뀌는순간인 것이고 참일때 return, 즉 playAnimation함수를 한타임 실행하지 않는다는것으로 음수값이 무시되고 다시 playAnimation함수가 실행된다. if (enterNewScene) return; playAnimation(); } window.addEventListener('scroll', () => { yOffset = window.pageYOffset; scrollLoop(); }); window.addEventListener('load', setLayout); // window의 모든 문서(html, 이미지, 동영상..)가 완료되고 나서 // 레이아웃 잡는 setLayout함수를 실행한다 // window.addEventListener('DOMContentLoaded', setLayout); //반대로 window의 html구조들만 완료되면 반대로 이미지는 로드되지않아도 setlayout함수를 실행하는것 //인데 load보다는 빨리 setlayout을 실행한다. window.addEventListener('resize', setLayout); // 윈도우가 리사이즈 되었을 때 setLayout을 호출한다 })(); <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>AirMug Pro</title> <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@400;900&display=swap" rel="stylesheet"> <link rel="stylesheet" href="css/default.css"> <link rel="stylesheet" href="css/main.css"> <script defer src="js/main.js"></script> </head> <body> <div class="container"> <nav class="global-nav"> <div class="global-nav-links"> <a href="#" class="global-nav-item">Rooms</a> <a href="#" class="global-nav-item">Ideas</a> <a href="#" class="global-nav-item">Stores</a> <a href="#" class="global-nav-item">Contact</a> </div> </nav> <nav class="local-nav"> <div class="local-nav-links"> <a href="#" class="product-name">AirMug Pro</a> <a href="#">개요</a> <a href="#">제품사양</a> <a href="#">구입하기</a> </div> </nav> <section class="scroll-section" id="scroll-section-0"> <h1>AirMug Pro</h1> <!-- p태그의 값들을 sticky, 즉 스티커처럼 고정해놓고 스트롤의 값에 따라 보여지도록 p태그를 감싸고 있는 div에 class를 준다. --> <div class="sticky-elem sticky-elem-canvas"> <canvas id ="video-canvas-0" width="1920px" height="1080px"></canvas> </div> <div class="sticky-elem main-message a"> <p>온전히 빠져들게 하는<br>최고급 세라믹</p></div> <div class="sticky-elem main-message b"> <p>주변 맛을 느끼게 해주는<br>주변 맛 허용 모드</p> </div> <div class="sticky-elem main-message c"> <p>온종일 편안한<br>맞춤형 손잡이</p> </div> <div class="sticky-elem main-message d"> <p>새롭게 입가를<br>찾아온 매혹</p> </div> </section> <section class="scroll-section" id="scroll-section-1"> <p class="description"> <strong>보통 스크롤 영역</strong> Lorem ipsum dolor sit amet consectetur adipisicing elit. Quas minus praesentium incidunt tempora repellendus? Laudantium sed excepturi quo nemo quisquam totam, cumque nam sit incidunt, corrupti libero temporibus obcaecati enim facilis dolore itaque minima dolorem sequi explicabo. Modi alias in ullam labore, minima voluptates ipsa ex laborum deleniti tempora incidunt architecto iure aut, molestias ab! Fugiat aliquam veritatis ad voluptatibus, quaerat officia doloribus aliquid nulla repellat quidem rem magni perferendis labore similique reprehenderit aut. Cum quis omnis ex iusto natus iste nisi magnam, nesciunt fugit aspernatur ullam? Temporibus, dolores ipsa. Odit odio aliquam sunt error corporis ab facere, illum sequi! Explicabo nulla, ipsum necessitatibus laboriosam eligendi aspernatur quam nostrum. Debitis est ad, vel in corrupti voluptas laboriosam quo, reiciendis quos quas culpa, atque voluptate tempora tempore quam accusamus ipsa asperiores voluptatibus adipisci non vero aspernatur eum nesciunt quis. A cum, molestiae eaque repellat similique esse eligendi reprehenderit amet omnis minus quae voluptatum delectus dolores repudiandae? Distinctio aut aspernatur, iure nemo, eum soluta error necessitatibus minus voluptatum laborum rem dignissimos quae. Error ut recusandae ullam magnam quas molestiae repellat culpa. Ab nihil sint voluptatum in? Enim suscipit debitis earum culpa sint maxime hic, repudiandae nulla ad error voluptatem fugiat blanditiis odit! </p> </section> <section class="scroll-section" id="scroll-section-2"> <div class="sticky-elem main-message a"> <p> <small>편안한 촉감</small> 입과 하나 되다 </p> </div> <div class="sticky-elem desc-message b"> <p> 편안한 목넘김을 완성하는 디테일한 여러 구성 요소들, 우리는 이를 하나하나 새롭게 살피고 재구성하는 과정을 거쳐 새로운 수준의 머그, AirMug Pro를 만들었습니다. 입에 뭔가 댔다는 감각은 어느새 사라지고 오롯이 당신과 음료만 남게 되죠. </p> <div class="pin"></div> </div> <div class="sticky-elem desc-message c"> <p> 디자인 앤 퀄리티 오브 스웨덴,<br>메이드 인 차이나 </p> <div class="pin"></div> </div> </section> <section class="scroll-section" id="scroll-section-3"> <p class="mid-message"> <strong>Retina 머그</strong><br> 아이디어를 광활하게 펼칠<br> 아름답고 부드러운 음료 공간. </p> <p class="canvas-caption"> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Eveniet at fuga quae perspiciatis veniam impedit et, ratione est optio porro. Incidunt aperiam nemo voluptas odit quisquam harum in mollitia. Incidunt minima iusto in corporis, dolores velit. Autem, sit dolorum inventore a rerum distinctio vero illo magni possimus temporibus dolores neque adipisci, repudiandae repellat. Ducimus accusamus similique quas earum laborum. Autem tempora repellendus asperiores illum ex! Velit ea corporis odit? Ea, incidunt delectus. Sapiente rerum neque error deleniti quis, et, quibusdam, est autem voluptate rem voluptas. Ratione soluta similique harum nihil vel. Quas inventore perferendis iusto explicabo animi eos ratione obcaecati. </p> </section> <footer class="footer"> 2020, 1분코딩 </footer> </div> </body> </html>
-
미해결유니티 머신러닝 에이전트 완전정복 (기초편)
OnActionReceived 함수 내용 관련 질문
GridAgent 스크립트 내 OnActionReceived 함수에서 처음에 무조건 AddReward(-0.01f); 해주는 정확한 이유를 알고 싶습니다.
-
해결됨HTML+CSS+JS 포트폴리오 실전 퍼블리싱(시즌1)
keyframe만드실 때
keyframe을 처음봤는데 어찌저찌 구글링해서 이론은 가볍게 배워서 다시 보는 중입니다. 저는 keyframes부분을 이렇게 작성했는데, 선생님은 왜 0% 일 때 scale(.5) 50%일 때 scale(1.2) 100%일 때 다시 0.5로 돌아오게끔 하셨는지 궁금합니다. 제가 생각했던 건 애니메이션 진행률 0%일 때 크기가 작았다가 100%일 때 본래 크기로 돌아오는 거라서 0%일 때 scale 0.5(0이면 너무 과하게 작아져서 0.5정도가 적당하더라고요), 100%일 때 1로 적용을 했는데 선생님처럼 하면 0%, 100%일 때 중간크기로 돌아오고 50%일 때 가장 큰 것 아닌가요? 만약 direction을 alternate로 적용한 경우에 저처럼 해도 문제가 되지 않을까요?(결과물은 똑같이?비슷하게?나옵니다) 선생님은 alternate를 지정하지 않으셔서 0%가 시작 50%가 끝 100%가 다시 시작으로 돌아오는 느낌으로 코드를 작성하신 걸까요?.. 아래 제 css전체 코드도 올립니다! @keyframes loading{ 0% { opacity: 0; transform: scale(.5); } 50% { opacity: 50%; } 100% { opacity: 100%; transform: scale(1); } } body{ height: 100vh; text-align: center; display: flex; justify-content: center; align-items: center; } .loading span{ width: 50px; height: 50px; display: inline-block; border-radius: 100%; margin: 2px; animation: loading .5s linear infinite alternate; } .loading span:nth-child(1){ background-color: pink; animation-delay: 0s; } .loading span:nth-child(2){ background-color: rgba(103, 184, 255, 0.753); animation-delay: .3s; } .loading span:nth-child(3){ background-color: rgba(104, 255, 177, 0.842); animation-delay: .5s; }
-
미해결기초부터 따라하는 디지털포렌식
추가 강의는 언제 제작될 예정인가요?
안녕하세요 포렌식이 궁금하여 수강한 학생입니다. 깔끔한 강의 감사드립니다. 다름이 아니라 현재 나온 강의들은 모두 수강하였는데 추가 강의가 언제 나오는지 궁금하여 문의드립니다. 감사합니다.
-
미해결[리뉴얼] 파이썬입문과 크롤링기초 부트캠프 [파이썬, 웹, 데이터 이해 기본까지] (업데이트)
python question 1 연습문제 10번입니다.
문제를 풀며 가장 자연스럽게 익숙해지는 파이썬 기본: 출력 포멧과 입력 강의 15분 5초입니다. 이 문제도 그렇고 저는 자꾸 int가 callable하지 않다는 error가 뜨는데요...ㅠ 이유를 알고 싶습니다. 강의 정말 잘 듣고 유용하게 듣고 있습니다. 감사합니다.
-
미해결Vue.js 끝장내기 - 실무에 필요한 모든 것
vue.config.js 질문드립니다.
vue 5.0.1 node 12.14.0 nvm 0.39.2입니다. 서버와 같이 10.16.3.으로 하려고 했는데 vue cli가 node 버 전을 12이상 요구해서 그냥 12.14.0으로 하였고 vue create 하면 vue.config.js 파일에 이와 같이 있어 eslint 설정을 할 수 가 없네요 방법이 있을까요? const { defineConfig } = require("@vue/cli-service"); module.exports = defineConfig({ transpileDependencies: true, });
-
미해결모든 개발자를 위한 HTTP 웹 기본 지식
컬렉션과 스토어 질문드립니다.
안녕하세요. 컬렉션과 스토어 정리가 잘 되지 않아 질문드립니다. https://www.inflearn.com/questions/265095 를 읽고나서 조금 더 혼란스러워서요..ㅠㅠ 위 질문에서 DELETE /members/{memberid} 는 생성/관리의 역할을 서버가 맡고 있다고 보는것이 맞다라고 답변이 적혀있는데요. 강의에서는 PUT /files/{filename} 은 클라이언트가 리소스의 URI를 알고 관리하기 때문에 /files는 스토어라고 설명되고 있습니다. 형태만 봤을 땐 files나 members의 URI 형태나 처리하는 방식이 비슷해 보여서 정리가 되지 않습니다.ㅠPUT /files/{filename} 은 파일 자체를 만들어주는것이(생성)이 아니라서 스토어이고,DELETE /members/{memberid}는 멤버정보를 DB에 저장해서 하나의 회원을 생성/관리(수정,삭제)하기 때문에 컬렉션이라고 이해하면 될지요?그게 아니라면 파일도 결국 members처럼 파일정보를 넘겨서 파일은 서버에 저장하고, 파일정보는 DB에 저장하므로 서버에서 처리하는게 아닌가하는 의문이 듭니다.매번 답변해주셔서 감사합니다 :)
-
미해결면접과 취업을 부르는 '퍼블리셔 개인 포트폴리오 홈페이지' 제작
포토샵 UI 디자인 질문있습니다.
안녕하세요~ 포트폴리오 제작할때 퍼블리싱전에 포토샵 UI 디자인이 중요하다고 하셨는데 구체적으로 포토샵으로 기능을 이용해서 제작하는건지 어떻게 해야되는지 궁금합니다. 그리고 제가 포토샵은 잘 못다루는데 포토샵 UI 디자인 다루는것도 따로 공부해야되나요?? 포토샵은 어느정도까지 공부해야되는지 궁금합니다..
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
자식의 요소까지 populate를 사용하려면 어떻게 해야할까요?
안녕하세요! 강사님 강의를 보고 여러가지 응용해보고 싶어서 중고장터를 클론코딩 하고 있습니다. 그러던 와중 특정 상품에 들어가면 상품에 달린 문의 글을 불러오는 로직을 작성했습니다. 하지만 문의글을 작성한 유저의 아이디만 불러올 뿐 populate를 할 수 있는 방법이 떠오르지 않아 도움 요청합니다.. DB의 구조는 상품 모델, 유저 모델, 상품문의 모델이 있다고 할 때 상품문의 모델은 문의가 작성된 상품 아이디: ObjectId(62149490b348c807b4337881) 문의를 작성한 유저 아이디: ObjectId(6224a99d95dcdc366868efe8) 문의 내용: "언제 구매한 물품인가요?" 이런식으로 설계되어 있고 특정 상품을 클릭하면 상품에 입력된 여러 정보와 상품 고유 아이디를 통해 상품문의 내용들을 populate 하여 모두 불러왔습니다. 그렇게 되니 최종적으로 { 상품아이디: ObjectId(62149490b348c807b4337881) 상품명: "사과", 설명: "택배 불가능" 문의: [ { 문의가 작성된 상품 아이디: ObjectId(62149490b348c807b4337881) 문의를 작성한 유저 아이디: ObjectId(6224a99d95dcdc366868efe8) 문의 내용: "언제 구매한 물품인가요?" }, { 문의가 작성된 상품 아이디: ObjectId(62149490b348c807b4337881) 문의를 작성한 유저 아이디: ObjectId(498dmek21v2hu3166868efe8) 문의 내용: "2차 구매자 입니까?" } ] 이런식으로 결과가 문의내용은 잘 불러옵니다. 하지만 배열에 담긴 유저 정보도 불러오기 위해 populate를 사용하러면 어떤식으로 사용을 해야할지 모르겠습니다. 모든 배열을 돌면서 해당하는 유저아이디만 찾아서 조합하는 방법을 떠올렸지만 너무 비효율적인것 같아 강사님의 솔루션을 듣고 싶습니다. 깃허브 주소 첨부합니다. https://github.com/nogoduck/Lightning-marketplace-Clone