묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결퍼블리셔 개인 포트폴리오 홈페이지 제작 완벽 가이드(PDF)
참고자료
안녕하세요,pdf 192페이지 내용 "수강생 참고자료에서 다운받을 수 있습니다." 라고 나와있는데자료 압축 풀면 animation 폴더 빼고 나머지는 빈폴더인데, 제가 못찾는 걸까요?확인 부탁드립니다.
-
미해결피그마(Figma)를 활용한 UI디자인 입문부터 실전까지 A to Z
레퍼런스 참고
dribble에서 캡쳐해서 따라서 제작하려 하는데요제작하려는 프레임 치수로 이미지의 사이즈를 변경해서 디자인 하면 되는건가요?? 이미지 픽셀도 많이깨지고, 레퍼런스 이미지마다 제품 테두리 디자인이 포함되있기도 해서 레퍼런스 참고 사이트들에서 캡처해서 따라하는 방법이 이방법이 맞는지 궁금합니다! 추가로 따라하려는 이미지상에 그리드를 표현하지는 못하는건가요?
-
미해결피그마(Figma)를 활용한 UI디자인 입문부터 실전까지 A to Z
뷰포인트 프레임
뷰포인트가핸드폰 캡처본만 필요시 되는거고 그 원리들은 PC모니터, 태블릿에는 적용이 안되는건가요?PC캡쳐본은 직접 해보니 동일한것같은데태블릿 도 뷰포인트 프레임에 디자인하는게 맞나요?
-
미해결피그마(Figma)를 활용한 UI디자인 입문부터 실전까지 A to Z
핸드오프 관련해서 궁금한 점이 있습니다.
안녕하세요. 강의를 보던 와중에 헷갈리는 부분이 있어서 질문드립니다.개발자에게 핸드오프 공 유시 특정 스크린만 공유하고 싶을 때는 스크린을 선택하여 링크를 보내면 된다고 하셨는데요.강의로 볼 때는 전체가 다 공유된 것 같은데 특정 스크린만 선택하여 공유하여도 다른 화면도 같이 보이게 되는 걸까요?그럼 특정 스크린과 전체 스크린을 공유할 때 개발자가 보는 화면에서 어떤 차이점이 있는지 궁금합니다.감사합니다.
-
미해결피그마(Figma)를 활용한 UI디자인 입문부터 실전까지 A to Z
하단바 프레임
안녕하세요 질문드립니다.올려주신 ios키트 에서 강의에서 사용하신 하단바는 아니지만다른 하단바를 가져와서 연습중입니다. 하단바를 제작할때 그룹을 짓거나 하지않고하단바의 아이콘과 텍스트를 각각 묶어서 프레임을 지어놓으시더라고요.이유가 무엇인가요?그룹지어서 놓는게 더 편할꺼같은데디자이너분들이 프레임으로 묶어놓는 이유가 있나요? 그리고저 분홍색 부분이 배경 컬러를 넣으신게 아니라하단바 자체를 그리드위에 만들어 놓았던데굳이 그렇게 할 이유가 있는건가요? 어떤상황에는 프레임으로 묶고, 어떤상황에는 그룹으로 묶어서 정리하는지 정확히 잘모르겠습니다.
-
미해결[2024년 출제기준] 웹디자인기능사 실기시험 완벽 가이드(HTML+CSS+JQUERY)
D3 유형 우측 메가 메뉴 질문
안녕하세요저는 전에 배우던 스타일이 있어서메뉴 만들때.menu를 .gnb로 하고.sub-menu를 div로 대신 ul로 해서 .lnb로 만듭니다.이대로 스타일 적용하고 메가 메뉴 만들 때 혹시 주의 사항이 있는지, 시험 때 이대로 풀어도 되는지 궁금합니다.이대로 적용했을 때는 브라우저에 결과는 잘 나왔었습니다. html css js 저는 와이어프레임 만들 때 border를 사용하지 않고background-color로 사용하였습니다. 혹시 문제가 있는지 여쭈어봅니다. 코드 복사해서 수정합니다. html<div class="navi"> <ul class="gnb"> <li><a href="#">OnSale</a> <ul class="lnb"> <li><a href="#">할인행사</a></li> <li><a href="#">덤증정</a></li> </ul> </li> <li><a href="#">기획전</a> <ul class="lnb"> <li><a href="#">봄 먹거리</a></li> <li><a href="#">여름 먹거리</a></li> <li><a href="#">가을 먹거리</a></li> <li><a href="#">겨울 먹거리</a></li> </ul> </li> <li><a href="#">푸른마을 레시피</a> <ul class="lnb"> <li><a href="#">메인요리</a></li> <li><a href="#">밑반찬</a></li> <li><a href="#">간식</a></li> <li><a href="#">브런치</a></li> </ul> </li> <li><a href="#">매장안내</a> <ul class="lnb"> <li><a href="#">신규매장</a></li> <li><a href="#">추천매장</a></li> <li><a href="#">공지사항</a></li> </ul> </li> </ul> </div>css.navi { width: 90%; margin: 20px auto; background-color: greenyellow; } .gnb {} .gnb>li { text-align: center; position: relative; } .gnb>li>a { display: block; padding: 5px; border: 1px solid black; background-color: #fff; transition: 0.5s; } .gnb>li:hover>a { background-color: gray; } .lnb { display: none; position: absolute; top: 0; left: 100%; width: calc(100vw - 210px); padding: 6px; background-color: rgba(0, 0, 0, 0.5); } .lnb>li { float: left; } .lnb>li>a { display: inline-block; width: 120px; transition: 0.5s; } .lnb>li>a:hover { color: white; background-color: gray; }js$('.gnb>li').mouseenter(function(){ $('.lnb').stop().fadeIn() }); $('.gnb>li').mouseleave(function(){ $('.lnb').stop().fadeOut() });
-
미해결피그마(Figma)를 활용한 UI디자인 입문부터 실전까지 A to Z
디자인 씽킹이라는 과정이 제품출시를 위한 과정인가요?
공감하기 정의하기 부분의 설명을 보고 조금 혼동되어서 질문을 올립니다.공감하기 정의하기 부분은 Product가 나오고 나서 사용자들의 피드백을 받고 진행하는 부분인가요?아니면 시장조사를 하고 제작자들이 이미 시중에 나와있는 페이지를 봤을때 문제점을 집어서 해당 문제를 보안하는 페이지를 만드는 것을 목표하는 부분인가요?
-
미해결[2024년 출제기준] 웹디자인기능사 실기시험 완벽 가이드(HTML+CSS+JQUERY)
저는 잘 만들었다고 생각했는데 Tab키로 옵젝전환을 시켜보니..
<!DOCTYPE html> <html lang="ko"> <head> <meta charset="UTF-8"> <title>JUST 쇼핑몰</title> <link rel="stylesheet" href="css/style.css"> </head> <body> <div class="container"> <header> <div class="header-logo"> <a href="#none"><img src="images/logo-header.png" alt="headerlogo 1"></a> </div> <div class="navi"> <ul class="menu"> <li> <a href="#none">재단소개</a> <div class="sub-menu"> <a href="#none">설립취지</a> <a href="#none">연혁</a> <a href="#none">찾아오시는길</a> </div> </li> <li> <a href="#none">후원하기</a> <div class="sub-menu"> <a href="#none">국내후원</a> <a href="#none">국외후원</a> <a href="#none">맞춤후원</a> </div> </li> <li> <a href="#none">자료실</a> <div class="sub-menu"> <a href="#none">서식자료실</a> <a href="#none">사진자료실</a> <a href="#none">후원양식</a> </div> </li> <li> <a href="#none">스토리</a> <div class="sub-menu"> <a href="#none">웹진</a> <a href="#none">보고서</a> <a href="#none">나의 후원</a> </div> </li> </ul> </div> <div class="sub-back"></div> </header> <div class="slide"> <div> <a href="#none"><img src="images/slide-01.jpg" alt="slide 1"></a> <a href="#none"><img src="images/slide-02.jpg" alt="slide 2"></a> <a href="#none"><img src="images/slide-03.jpg" alt="slide 3"></a> </div> </div> <div class="items"> <div class="news"> <div class="tab-inner"> <span>공지사항</span> <div class="tab1"> <a class="open-modal" href="#none"><em>SMS 발송 모바일 서비스 개선작업 안내입니다.</em><b>2020.01.09</b></a> <a href="#none"><em>휴대폰 인증 서비스 개선 작업 기간 연장</em><b>2020.01.07</b></a> <a href="#none"><em>카드사 부분 무이자 할부 이벤트</em><b>2019.12.31</b></a> <a href="#none"><em>올앳 시스템 작업 안내</em><b>2019.12.20</b></a> <a href="#none"><em>휴대폰 결제 시스템 작업이 완료되었습니다.</em><b>2019.12.20</b></a> </div> </div> </div> <div class="gallery"> <div class="tab-inner"> <span>갤러리</span> <div class="tab2"> <a href="#none"><img src="images/gallery-01.jpg" alt="gallery 1"></a> <a href="#none"><img src="images/gallery-02.jpg" alt="gallery 2"></a> <a href="#none"><img src="images/gallery-03.jpg" alt="gallery 3"></a> </div> </div> </div> <div class="banner"> <a href="#none"><img src="images/banner-01.jpg" alt="banner 1"></a> <a href="#none"><img src="images/banner-02.jpg" alt="banner 2"></a> </div> </div> <footer> <div class="footer-logo"> <a href="#none"><img src="images/logo-footer.png" alt="footerlogo 1"></a> </div> <div class="copyright"> <a href="#none">법적고지</a> <a href="#none">개인정보취급방침</a> <a href="#none">개인정보처리방침</a> <p> 상호 : 엣지컴퍼니 | 대표자 : 홍길동 | 개인정보관리책임자 : 장길산 차장<br> 사업장주소 : 서울특별시 강남구 테헤란로 123-56 </p> </div> <div class="familysite"> <select> <option value="">Familysite</option> <option value="">연습용입니다</option> <option value="">이쪽도 재밌어요</option> <option value="">저쪽은 낭떠러지</option> </select> </div> </footer> </div> <div class="modal"> <div class="modal-content"> <h2>SNS비회원주문하기 종료 안내</h2> <p> 안녕하세요, JUST 쇼핑몰 MD 홍길동입니다. 안타깝게도 SNS비회원 주문하기 서비스가 한달 뒤 종료될 예정입니다.<br> 회원가입없이 SNS계정을 이용해 그동안 제품주문을 하실수 있었는데, 금번 강화된 개인정보보호법 시행령 제 9조 (부칙 3조 3항)에 의거, SNS를 이용한 상품 주문/결제등이 근래에 많은 보안잇슈로 문제가 되고 있음에 다라 KISA의 권고조치의 일환으로 했습니다.<br> 따라서, 한달뒤인 2019.03.10 이후 모든 비회원 고객님들께서는 회원가입으로 전환 후 실명인증이 되어야 하며, 이는 모든 쇼핑몰/오픈마켓등의 전자상거래서비스의 공통된 사항이라는 점을 안내해드립니다. </p> <a class="close-modal" href="#none">닫기</a> </div> </div> <script src="script/jquery-1.12.4.js"></script> <script src="script/custom.js"></script> </body> </html> @charset "utf-8"; body { margin: 0; background-color: #fff; color: #333333; font-size: 15px; } a { text-decoration: none; color: #333333; } .container { margin: auto; /* border: 1px solid red; */ width: 1200px; } header { height: 100px; position: relative; z-index: 10; } header > div { height: 100px; /* border: 1px solid green; */ } .header-logo { width: 200px; float: left; } .header-logo > a { line-height: 130px; } .navi { width: 600px; float: right; } .menu { padding: 0; width: 600px; } .menu li { text-align: center; list-style: none; float: left; width: 25%; padding-top: 55px; } .menu li > a{ border: 1px solid black; display: block; padding: 5px; transition: 0.5s; } .menu li:hover > a { background-color: #000; color: #fff; } .sub-menu { position: relative; display: none; } .sub-menu > a{ display: block; padding: 8px; transition: 0.5s; color: #fff; } .sub-menu > a:hover { background-color: #fff; color: #333333; } .sub-back { display: none; width: 100%; height: 150px; top: 100%; left: 0; background-color: #000; position: absolute; z-index: -1; } .slide { height: 300px; width: 1200px; position: relative; overflow: hidden; } .slide > div { position: absolute; width: 3600px; /* border: 1px solid black; */ left: 0; top: 0; height: 300px; font-size: 0; animation: slide 10s linear infinite; } @keyframes slide { 0% { left: 0; } 30% { left: 0; } 35% { left: -1200px; } 65% { left: -1200px; } 70% { left: -2400px; } 95% { left: -2400px; } 100% { left: 0; } } .items { overflow: hidden; margin-top: 10px; } .items > div { /* border: 1px solid blue; */ height: 200px; float: left; box-sizing: border-box; } .news { width: 425px; } .gallery { width: 425px; } .tab-inner { width: 95%; margin: auto; } .tab-inner span { border: 1px solid black; border-radius: 5px 5px 0 0; display: inline-block; width: 80px; padding: 8px; text-align: center; background-color: #fff; border-bottom: 0; } .tab1 { border: 1px solid black; padding: 0 4px; height: 150px; background-color: #fff; margin-top: -2px; } .tab1 em { width: 50%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-style: normal; position: relative; } .tab1 b { float: right; } .tab1 a { display: block; border-bottom: 1px solid black; padding: 2.5px; } .tab1 a:last-child { border-bottom: 0px; } .tab1 a b{ font-weight: normal; } .tab2 { background-color: #fff; margin-top: -2px; border: 1px solid black; text-align: center; padding-top: 20px; height: 130px; } .tab2 img { width: 120px; } .banner { width: 350px; } footer { overflow: hidden; } footer > div { height: 100px; float: left; box-sizing: border-box; } .footer-logo { width: 200px; } .footer-logo > a { line-height: 130px; } .copyright { width: 800px; text-align: center; padding-top: 10px; overflow: hidden; } .copyright > a { box-sizing: border-box; } .copyright > p { padding-bottom: 10px; } .familysite { width: 200px; text-align: center; padding-top: 35px; } .modal { position: absolute; background-color: #00000049; top: 0; left: 0; width: 100%; height: 100%; z-index: 100; display: none; } .modal-content { position: absolute; transform: translate(-50%,-50%); width: 350px; background-color: #fff; top: 50%; left: 50%; padding: 20px; border-radius: 5px; box-shadow: 0 0 20px rgba(0, 0, 0, 0.356); } .modal-content span { } .close-modal { float: right; border: 1px solid black; padding: 5px; } $('.menu li').mouseenter(function(){ $('.sub-menu,.sub-back').stop().slideDown() }); $('.menu li').mouseleave(function(){ $('.sub-menu,.sub-back').stop().slideUp() }); $('.open-modal').click(function(){ $('.modal').fadeIn() }); $('.close-modal').click(function(){ $('.modal').fadeOut() });이게 이렇게해서 Html, css ,jQuery 3개 잘 만들어 보았으나, 직접 웹 페이지에서 탭키로 누르려고하면 아이템 부분의 공지사항이랑 갤러리가 없어져버립니다.. 왜 이렇게 되는걸까요!..
-
미해결피그마(Figma)를 활용한 UI디자인 입문부터 실전까지 A to Z
프레임 질문 입니다.
프레임상에 그리드를 두고 디자인을하면반응형 웹디자인으로서핀터레스트 웹사이트 예시 처럼 웹사이트의 크기를 줄여나가면 컨텐츠들이그 웹사이트 조정한 크기에 맞게 변하는것 처럼.그리드 상에 디자인을 하면 화면 픽셀 단위 에 맞게 컨텐츠들이 조정된다고 이해를 하였습니다.모바일 반응형 디자인을 한다고 가정했을때모바일용 프레임 비율 한가지에다가 그리드 위에 디자인을 하면모바일 모든 디바이스에 디자인이 각 디바이스 해상도에 맞게 조정 되는것으로 이해를 했습니다.그렇다면피그마 상에서 위 사진처럼 모바일 디바이스별 프레임을 분류를 해놓는데제가 사진 위에 설명처럼 이해를 한다면,아이폰8 디바이스 프레임을 선택해서 그리드위에 디자인을 한다고 가정했을때그 디자인한 앱을아이폰11, 또는 아이폰12 등등 을 사용해도똑같은 디자인으로 결과값이 도출되는지가 궁금합니다.또한 아이폰 8 디바이스 프레임을 선택해서 그리드 위에 디자인한 앱과아이폰 11 디바이스 프레임을 선택해서 그리드 위에 디자인한 앱과똑같은 결과값이 나오는건가요?즉 그리드 를 사용해서 디자인을 한다면모바일 프레임이라면 어떤 프레임을 사용해도 상관이 없는건가요?또한그리드상 위에 디자인을하면 반응형으로서 각 디바이스 해상도에 맞게 조정이 되는것이라면왜 모바일용 해상도 프레임 or PC용 해상도 프레임 이런식으로 통일하지않고위 사진처럼 각 디바이스별로 프레임 해상도를 분류해놓는것인가요?모바일 프레임이라면 어떤 프레임을 선택해도 모든 모바일 디바이스상에 결과값이 동일한가요?질문이 많아서 불편드려 죄송합니다!위의 모든 질문은 디자인을 할시에어떤 프레임 상에 디자인을 해야되는지 궁금증에서 나왔으며어떤 프레임상에 디자인을 해도 결과값이 모두 동일한지 궁금증이 해결되지않습니다!저 많은 디바이스별 프레임중에 어떤 프레임에다가 디자인을 해야되는건가요?PC용 디자인을 하더라도 디자이너 분마다 디자인을 하게되는 프레임의 해상도 비율값이전부 다르시고 추천하시는 프레임 해상도 비율값도 전부 다르신데이 프레임의 해상도 비율값이 달라도 그리드 상에 디자인을 하면모두 동일한 디자인값이 나오는지가 궁금합니다!
-
미해결피그마(Figma)를 활용한 UI디자인 입문부터 실전까지 A to Z
웹 또는 앱 디자인 따라할때 질문.
실제 웹 따라할때 실제 픽셀 과 오브젝트 사이의 픽셀크기들 , 글꼴의 크기 어떻게 아는건가요??따라하려는 사이트 화면 확대축소 비율 100%로 캡처한후에피그마로 사진 가져온후 피그마 상의 확대비율 100%로 맞추면동일한 픽셀인것인가요? 추가로 만약 따라해서 제작한후에 피그마상에서 실제 사이트처럼 구현되는것을 확인할수있는 방법이 있을까요?
-
미해결피그마(Figma)를 활용한 UI디자인 입문부터 실전까지 A to Z
디자인 시스템 버튼 상태 질문입니다.
디자인 시스템 contenent 설명해주시는도중에버튼의 상태인normal / hover / press / focus / disabled 상태로 나타내셨고 text Field 상태를blank / filled / activated / error 로 표현하셨는데요 normal , press, disabled 등 몇가지는 어느정도 알겠는데hover focus activated 등등 무슨 상태를 표현하는 단어인건지 사전을 찾아봐도 정확히 감이오질않습니다. normal / hover / press / focus / disabled blank / filled / activated / error이상태들이 정확히 무슨상태인지 여쭈어 봐도될까요?
-
미해결피그마(Figma)를 활용한 UI디자인 입문부터 실전까지 A to Z
아이콘 제작 질문드립니다.
오브젝트의 라운딩값을 전체에 주는게 아닌일부만 라운딩 안줄수 있는 방법이 있을까요?
-
미해결애플 웹사이트 인터랙션 클론!
페이지가 처음 로딩 되었을 때 애니메이션 처리가 되지 않는 느낌입니다
페이지가 맨 처음 로딩 되었을 때에는 애니메이션이 작동하지 않다가... 페이지 섹션을 일정 부분 진행하고 다시 윗방향 스크롤을 걸었을때 애니메이션이 정상작동을 합니다.그 후부터는 페이지의 시작 위치로 이동해서 시작부터 차근차근 내렸을때 정상작동을 합니다.원인이 잘 생각이 나지 않네요 Main.js(() => { let yOffset = 0; // window.pageYOffset 대신에 쓸 변수 let prevScrollHeight = 0; // 현재 스크롤 위치(yOffset) 보다 이전에 위치한 스크롤 섹션들의 스크롤 높이값의 합 let currentScene = 0; // 현재 활성화된 (눈 앞에 보고있는) 씬 (Scrollsection) let enterNewScene = false; // 새로운 Scene이 시작된 순간 true // sceneInfo는 각 scene에 대한 정보를 담고 있다. const sceneInfo = [ { // 0 type: 'sticky', heightNum: 5, // 브라우저 높이의 5배로 scrollHeight 세팅 scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-0'), messageA: document.querySelector('#scroll-section-0 .main-message.a'), messageB: document.querySelector('#scroll-section-0 .main-message.b'), messageC: document.querySelector('#scroll-section-0 .main-message.c'), messageD: document.querySelector('#scroll-section-0 .main-message.d') }, values: { messageA_opacity_in: [0, 1, { start: 0.1, end: 0.2 }], messageB_opacity_in: [0, 1, { start: 0.3, end: 0.4 }], 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 }] } }, { // 1 type: 'normal', // heightNum: 5, // type normal에서는 필요 없음 scrollHeight: 0, objs: { container: document.querySelector('#scroll-section-1'), content: document.querySelector('#scroll-section-1 .description') } }, { // 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'), canvasCaption: document.querySelector('.canvas-caption') }, values: { } } ]; function setLayout() { // 각 스크롤 섹션의 높이 세팅 for (let i = 0; i < sceneInfo.length; i++) { if(sceneInfo[i].type === 'sticky') { sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight; // window.innerHeight는 브라우저 창의 높이 } else if(sceneInfo[i].type === 'normal') { sceneInfo[i].scrollHeight = sceneInfo[i].objs.container.offsetHeight } sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px` } yOffset = window.scrollY; let totalScrollHeight = 0; for (let i = 0; i < sceneInfo.length; i++) { totalScrollHeight += sceneInfo[i].scrollHeight; if(totalScrollHeight >= yOffset) { // 이미지로 그려보면 이해가 쉬움 currentScene = i; break; } } document.body.setAttribute('id', `show-scene=${currentScene}`) } function calcValues (values, currentYOffset) { // currentYOffset은 현재 씬에서 얼마나 스크롤 됐는지를 의미 let rv; // 현재 씬(스크롤섹션)에서 스크롤된 범위를 비율로 구하기 const scrollHeight = sceneInfo[currentScene].scrollHeight 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) / partScrollStart * (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: // console.log('0 play'); if (scrollRatio <= 0.22) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.42) { // in objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.62) { // in objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.82) { // in objs.messageD.style.opacity = calcValues(values.messageD_opacity_in, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageD.style.opacity = calcValues(values.messageD_opacity_out, currentYOffset); objs.messageD.style.transform = `translate3d(0, ${calcValues(values.messageD_translateY_out, currentYOffset)}%, 0)`; } break; case 2: // console.log('2 play'); if (scrollRatio <= 0.32) { // in objs.messageA.style.opacity = calcValues(values.messageA_opacity_in, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_in, currentYOffset)}%, 0)`; } else { // out objs.messageA.style.opacity = calcValues(values.messageA_opacity_out, currentYOffset); objs.messageA.style.transform = `translate3d(0, ${calcValues(values.messageA_translateY_out, currentYOffset)}%, 0)`; } if (scrollRatio <= 0.67) { // in objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_in, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_in, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } else { // out objs.messageB.style.transform = `translate3d(0, ${calcValues(values.messageB_translateY_out, currentYOffset)}%, 0)`; objs.messageB.style.opacity = calcValues(values.messageB_opacity_out, currentYOffset); objs.pinB.style.transform = `scaleY(${calcValues(values.pinB_scaleY, currentYOffset)})`; } if (scrollRatio <= 0.93) { // in objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_in, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_in, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } else { // out objs.messageC.style.transform = `translate3d(0, ${calcValues(values.messageC_translateY_out, currentYOffset)}%, 0)`; objs.messageC.style.opacity = calcValues(values.messageC_opacity_out, currentYOffset); objs.pinC.style.transform = `scaleY(${calcValues(values.pinC_scaleY, currentYOffset)})`; } break; case 3: // console.log('3 play'); break; } } function scrollLoop() { enterNewScene = false; prevScrollHeight = 0; // PrevScrollHeight의 초기화가 함수 내에 있어야 맥북 기준 4 scene의 총합 11540이 찍히고 다음 scrollLoop() 이 실행될 때 다시 초기화 된다. (값이 누적되지 않는다.) 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; // scene 0에서 바운싱 스크롤이 일어났을 때 콘솔에 -값을 찍히지 않게 방지 currentScene--; document.body.setAttribute('id', `show-scene-${currentScene}`); } if (enterNewScene) return; playAnimation(); } window.addEventListener('scroll', () => { yOffset = window.scrollY; // window.pageYOffset은 deprecated 되었다. scrollLoop() }); // window.addEventListener('DOMContentLoaded', setLayout) window.addEventListener('load', setLayout) window.addEventListener('resize', setLayout) // 화면 크기가 바뀌었을때를 기준으로 setLayout을 정의하기 })();main.css@charset "utf-8"; html { font-family: 'Noto Sans KR' , sans-serif; font-size: 14px; } body { overflow-x: hidden; color: rgb(29, 29, 31); letter-spacing: -0.05em; background: white; } p { line-height: 1.6; } a { color: rgb(29, 29, 31); text-decoration: none; } .global-nav { position: absolute; top: 0; left: 0; width: 100%; height: 44px; padding: 0 1rem; } .local-nav { position: absolute; top: 45px; left: 0; width: 100%; height: 52px; padding: 0 1rem; border-bottom: 1px solid #ddd; } .global-nav-links, .local-nav-links { display: flex; align-items: center; max-width: 1000px; height: 100%; margin: 0 auto; /* background-color: gold; */ } .global-nav-links { justify-content: space-between; } .local-nav-links .product-name { margin-right: auto; font-size: 1.4rem; font-weight: bold; } .local-nav-links a { font-size: 0.8rem; } .local-nav-links a:not(.product-name) { margin-left: 2em; } .scroll-section { border: 3px solid red; padding-top: 50vh; } #scroll-section-0 h1 { font-size: 4rem; text-align: center; } .main-message { display: flex; align-items: center; justify-content: center; top: 35vh; margin: 5px 0; height: 3em; font-size: 2.5rem; opacity: 0; } .main-message p { font-weight: bold; text-align: center; line-height: 1.2; } .main-message small { display: block; margin-bottom: 0.5em; font-size: 1.2rem; } #scroll-section-2 .main-message { font-size: 3.5rem; } .description { max-width: 1000px; margin: 0 auto; padding: 0 1rem; font-size: 1.2rem; color: #888 } .description strong { float: left; margin-right: 0.2em; /* font-size: 3rem; */ color: rgb(29, 29, 31); } .desc-message { width: 50%; font-weight: bold; } .pin { width: 1px; height: 100px; background: rgb(29,29,31); } #scroll-section-2 .b { top: 10%; left: 40%; } #scroll-section-2 .c { top: 15%; left: 45%; } .mid-message { max-width: 1000px; margin: 0 auto; padding: 0 1rem; font-size: 2rem; color: #888; } .mid-message strong { color: rgb(29,29,31); } .canvas-caption { max-width: 1000px; margin: 0 auto; padding: 0 1rem; font-size: 1.2rem; color: #888; } .footer { display: flex; align-items: center; justify-content: center; height: 7rem; color: white; background: darkorange; } .sticky-elem { display: none; position: fixed; left: 0; width: 100%; } body#show-scene-0 #scroll-section-0 .sticky-elem, body#show-scene-1 #scroll-section-1 .sticky-elem, body#show-scene-2 #scroll-section-2 .sticky-elem, body#show-scene-3 #scroll-section-3 .sticky-elem { display: block; } @media(min-width: 1024px) { #scroll-section-0 h1 { font-size: 9vw; } .main-message { font-size: 4vw; } .description { font-size: 2rem; } .description strong { font-size: 6rem; } #scroll-section-2 .main-message { font-size: 6vw; } .main-message small { font-size: 1.5vw; } .desc-message { width: 20%; } #scroll-section-2 .b { top: 20%; left: 53%; } #scroll-section-2 .c { left: 55%; } .mid-message { font-size: 4vw; } .canvas-caption { font-size: 2rem; } }blank.html<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-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"> </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> <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. Dolore explicabo commodi facere nisi expedita eaque quasi doloremque eligendi natus architecto, facilis velit nobis voluptatum suscipit autem soluta debitis neque illum quibusdam similique odio maiores. Ab optio laborum eum sit praesentium, aperiam voluptatem nihil modi tempore a magni necessitatibus hic exercitationem temporibus doloremque error omnis. Sequi, repudiandae dolor eaque non soluta praesentium doloremque, doloribus, ea consequuntur sit perferendis ex! Repellendus natus harum soluta dolorem voluptas alias qui, ipsa vero! Alias voluptate libero, facilis molestias nam aspernatur, amet accusantium consequatur a nostrum temporibus. Qui obcaecati optio quod iusto totam, aut iste dolor ea. Explicabo dolorem ducimus natus, officiis aut minima, ad sapiente voluptatem repellat aliquid suscipit at. Architecto nostrum perferendis, fugiat velit perspiciatis illum dignissimos, vitae delectus magnam blanditiis omnis ratione nihil minus deserunt repudiandae necessitatibus et, tempore cupiditate sapiente? Debitis obcaecati repellendus corrupti odit incidunt deleniti exercitationem dolorum ipsum consequatur rerum maxime, corporis placeat deserunt veniam cum qui dolorem nulla fugit eius ipsam quibusdam saepe! Aut culpa excepturi perferendis, sint animi tempora. Officia necessitatibus libero impedit alias commodi excepturi accusamus molestiae modi laudantium voluptates totam earum autem eos numquam at consequuntur ipsam repellat, perspiciatis veniam? Expedita nobis ducimus quisquam accusantium! Velit! </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> 아름답고 부드러운 음료 공간. </p> <p class="canvas-caption"> Lorem ipsum dolor sit amet consectetur adipisicing elit. Expedita nulla nesciunt tempora asperiores culpa, illo et assumenda vel odio voluptatem? Saepe rerum qui accusamus maiores ex libero natus obcaecati accusantium aperiam eligendi ut et facere quis molestias quos repudiandae, omnis facilis deserunt cum! Expedita ipsam aliquid beatae doloremque, officia explicabo non neque reprehenderit qui quo, recusandae incidunt saepe totam! Adipisci dolorem inventore soluta. Natus pariatur sit quisquam dicta placeat! Molestias voluptas eos asperiores maxime, dolorem corporis eum quos iste dolores eveniet, cumque officiis beatae adipisci! Corporis quibusdam voluptates explicabo officiis quis cupiditate qui officia expedita. Praesentium placeat debitis recusandae ipsa similique optio accusamus, omnis vero a ducimus blanditiis fugit asperiores maiores mollitia? Pariatur exercitationem culpa, fugiat accusantium soluta incidunt beatae debitis laborum, harum neque aliquam, asperiores quod! Error numquam voluptate aut corrupti nam! Iusto illum accusamus sapiente asperiores quo eum perspiciatis aliquam blanditiis dolorem natus, modi magnam molestiae accusantium porro quisquam iure tempora laborum deserunt recusandae omnis dolore eos pariatur eveniet. Exercitationem mollitia inventore at quasi aperiam blanditiis minima accusantium, delectus, possimus quidem labore sapiente eius sint molestias doloribus est autem cupiditate iure veniam optio! Placeat dolor et, eos, saepe nemo tempore aliquid alias, facere pariatur optio sint nam ea. </p> </section> <footer class="footer"> 2023-08-01 Jun </footer> </div> <script src="js/main.js"></script> </body> </html>
-
미해결피그마(Figma)를 활용한 UI디자인 입문부터 실전까지 A to Z
제품마다 맞는 그리드 디자인
안녕하세요. 그리드 개념에 대해 배우다 궁금한 점 이 있어 여쭈어 봅니다. 각 제품마다 화면 크기가 다르니까, 그에 맞는 픽셀의 프레임으로 디자인을 해야 한다고 이해를 했습니다. 그렇다면 한 회사의 앱 또는 웹을 출시한다고 했을 때실무에서 디자이너는 현재 존재하는 모든 제품들의 화면의 픽셀에 맞는 프레임들을 따로 전부 각각 디자인을 해야하는건가요?아니면 그리드 상에 디자인을 하면 자동으로 맞추어 주는건가요? 그리고핀터레스트 웹사이트 예시 보여주시면서웹사이트의 크기를 줄여나가면 컨텐츠들이알아서 맞게 변하는것을 보고 이게 반응형 디자인이고 이를 하려면 그리드로 디자인을해야한다고 이해를 했습니다.이또한 그 화면마다 디자이너가 그화면 프레임에 맞게 각각 디자인을 한건가요?아니면 그리드상에 디자인을 하면 자동으로 맞추어 주는건가요? 그리드상에 디자인을 하면 자동으로 맞추어 주는것이 정답이라 한다면,모바일 디자인이라 가정했을때아이폰8 프레임 / 아이폰 11 프레임 등등어떤 프레임으로 디자인하는 모든제품에 대응이 되는것인지 궁금하며또 이것이 대응이된다면각 제품마다 프레임이 나누어놓는 이유가 무엇인가요? 아이폰8 사용자를 대상으로아이폰11 프레임으로 디자인 했을때대응이 되는지 / 또 대응이 된다면 차이는 없으며 왜 프레임을 제품마다 나누는지 궁금합니다.
-
미해결피그마(Figma)를 활용한 UI디자인 입문부터 실전까지 A to Z
안녕하세요 질문 드립니다!
화면과 같은 아이콘 제작을연습하고 있습니다.화살표를 만들려 하는데아이콘 아래 방법들 처럼 진행해서 화살표를 만들 생각을 했습니다.이 화살표의 크기가 무족건 소수점이 되어서아이콘상으로 옮겼을때 keyline 프레임상에 딱 중심으로 가게할수가 없더라고요, 위치랑 크기가 소수점으로 떨어집니다.소수점 이동해서 최대한 중앙으로 맞춰도 끝부분은 약간 빗나가게 되버립니다.이방법으로 화살표 만드는게 맞는지 여쭈어 봅니다.또한 딱 중앙으로 맞추는 방법이 있을까요??
-
미해결피그마(Figma)를 활용한 UI디자인 입문부터 실전까지 A to Z
안녕하세요 피그마 조작법 질문드립니다.
다른분이 질문올리신거 보고 궁금증이 생겨서요.화살표 이전단계까지 원형의 일부처럼 보이는 형상을 만드는 방법은원형을 subtract selection으로 잘라내는것 밖에 방법이 없나요? 이렇게 선분으로는 만들지 않는건가요?
-
미해결[2024년 출제기준] 웹디자인기능사 실기시험 완벽 가이드(HTML+CSS+JQUERY)
A1타입 최종본 만들기
최종본 만들때 슬라이드 안에 있는 사진 사이즈와 텍스트는 포토샵으로 만든건가요?
-
미해결[2024년 출제기준] 웹디자인기능사 실기시험 완벽 가이드(HTML+CSS+JQUERY)
모달 닫기 버튼
모달 창 만들 때 X 닫기 를 a태그로 사용하셨는데 button 태그로 사용하면 안되나요?
-
미해결피그마(Figma)를 활용한 UI디자인 입문부터 실전까지 A to Z
피그마 질문입니다.
안녕하세요.선생님 강의처럼 동그라미들과 틀을 동시선택후에 가운데 정렬 Align horizental cental를 눌렀는데선생님처럼 3개의 동그라미가 하나로 취급되어 중앙으로 맞추어 지지않고그냥 3개의 동그라미가 하나로 모여버립니다.어떻게 하는건가요?
-
미해결[2024년 출제기준] 웹디자인기능사 실기시험 완벽 가이드(HTML+CSS+JQUERY)
vscode emmet 핵심 단축키 파일 관련
안녕하세요!vscode에서 emmet 사용법 강좌 끝에 보면 첨부파일에 핵심 단축키 정리된 파일을 다운로드 받으라고 되어 있는데, 아무리 찾아도 다운로드할 파일을 찾지 못하여... 제가 못찾는건지, 다운이 안되는 상황인건지 문의드립니다!