본문 바로가기

카테고리 없음

웹 퍼블리셔 - 웹퍼블리싱 (Tesla 웹페이지)

약 일주일동안 포트폴리오에 필요한 첫번째 웹페이지를 만들어보았다.

 

지금 구성 중인 포트폴리오는 만들어보고싶은 웹페이지의 UI만 참고하고 나머지는 다 스스로 만들어 보는것이다.

 

그것을 총 6개의 웹페이지를 만들어보고 해당 웹페이지를 보여주는 이력서 포트폴리오를 만들어 볼 것이다.

 

그 중 첫번째 Tesla 웹페이지를 완성했다.

 

먼저 Tesla 웹페이지를 만들면서 많이 힘들었던 부분이 Full page 웹이였던 점이다. Full Page라는 점은 그렇게 크게 힘들지 않는데, 스크롤을 부드럽게 하는 부분들과, 스크롤 위치에 따른 효과를 주기위해서 조금 어려운 부분들이 있었다.

 

처음 사용해 보는 scroll-snap 기능들과 animation의 transition효과들 내가 만들어야하는 것에 있어서 중요한것들을 처음 사용 해 보아서 조금 올래 걸렸다.

 

그렇다면 코드 리뷰를 시작하자면,

 

 

테슬라 로고, 메뉴, 사이드 아이콘

<div className="header_menu">
                        <h1>
                            <a href="/" className="tesla_logo">
                                <svg width="120px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 342 35">
                                    <path d={tesla_logo_path} fill="white"></path>
                                </svg>
                            </a>
                        </h1>
                        <ol className="menu">{/*메뉴*/}
                            <li onMouseOver={handleMouse}>차량</li>
                            <li onMouseOver={handleCharger}>충전</li>
                            <li onMouseOver={handleMore}>살펴보기</li>
                            <li onMouseOver={handleShop}>shop</li>
                        </ol>
                        <ol className="icon">{/*아이콘*/}
                            <li>
                                <a href="/">
                                    <svg width="24px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                                        <path d={support_logo_path} fill="white"></path>
                                    </svg>
                                </a>
                            </li>
                            <li>
                                <a href="/">
                                    <svg width="24px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                                        <path d={lang_logo_path} fill="white"></path>
                                    </svg>
                                </a>
                            </li>
                            <li>
                                <a href="/">
                                    <svg width="24px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                                        <path d={person_logo_path} fill="white"></path>
                                    </svg>
                                </a>
                            </li>
                        </ol>
                    </div>

먼저 jsx로 만든 테슬라 로고와 메뉴, 사이드 메뉴 아이콘이다.

 

해당 메뉴에 보면은 MouseOver 이벤트가 존재하는데 해당 li에 마우스를 가져가면 메뉴가 부드럽게 내려오면서 추가 정보들을 보여준다.

 

그리고 svg를 가져올때 알게 된 점인데, svg를 가져올때에는 xlmns 의 주소와 path가 필요하다. 이 두개를 가져와야지만 svg를 정상적으로 사용이 가능하다. 옆에 존재하는 fill이라는것은 해당 svg의 색상을 정해줄수있다.

 

style에서 color로 조정이 불가능 하기 때문에 fill로 rgb값을 주거나 색상을 정해주면 변경이 가능하다.

 

 

먼저 메뉴바에 차량을 마우스 오버 하면 나타는것들을 만들어주었다.

 

 <div className="mouseover_car" ref={car_mouseover} onMouseLeave={handleMouseLeave}>
                        <div className="mega_menu">
                            <div className="mega_menu_container1">
                                <a>
                                    <img width="180px"src="https://digitalassets.tesla.com/tesla-contents/image/upload/f_auto,q_auto/Mega-Menu-Vehicles-Model-S.png" alt="model s"/>
                                </a>
                                <div className="mega_menu_model">
                                    <h3>Model S</h3>
                                    <div>
                                        <a href="#">자세히 알아보기</a>
                                        <a href="#">주문하기</a>
                                    </div>
                                </div>
                            </div>
                            <div className="mega_menu_container2">
                                <a>
                                    <img width="180px"src="https://digitalassets.tesla.com/tesla-contents/image/upload/f_auto,q_auto/Mega-Menu-Vehicles-Model-3.png" alt="model 3"/>
                                </a>
                                <div className="mega_menu_model">
                                    <h3>Model 3</h3>
                                    <div>
                                        <a href="#">자세히 알아보기</a>
                                        <a href="#">주문하기</a>
                                    </div>
                                </div>
                            </div>
                            <div className="mega_menu_container3">
                                <a>
                                    <img width="180px"src="https://digitalassets.tesla.com/tesla-contents/image/upload/f_auto,q_auto/Mega-Menu-Vehicles-Model-X.png" alt="model s"/>
                                </a>
                                <div className="mega_menu_model">
                                    <h3>Model X</h3>
                                    <div>
                                        <a href="#">자세히 알아보기</a>
                                        <a href="#">주문하기</a>
                                    </div>
                                </div>
                            </div>
                            <div className="mega_menu_container4">
                                <a>
                                    <img width="180px"src="https://digitalassets.tesla.com/tesla-contents/image/upload/f_auto,q_auto/Mega-Menu-Vehicles-Model-Y.png" alt="model s"/>
                                </a>
                                <div className="mega_menu_model">
                                    <h3>Model Y</h3>
                                    <div>
                                        <a href="#">자세히 알아보기</a>
                                        <a href="#">주문하기</a>
                                    </div>
                                </div>
                            </div>
                        </div>

해당 Dom에 직접적으로 필요한것이 있어서 useRef를 사용하여 연결시켜주었다.

그리고 메뉴에 올리면 이러한 것들이 생기는데, 생기고 없어지지 않아서 해당 영역을 벗어나면 display:none;를 해주기위한 MouseLeave를 만들어주었다.

 

 

똑같은 원리로, 충전, 살펴보기, shop에 해당하는 추가적인 것들을 만들어주었다.

 

<div className="mega_menu_list">
                            <ul>
                                <li><a href="#">인벤토리</a></li>
                                <li><a href="#">인증중고 차량</a></li>
                                <li><a href="#">시승 신청</a></li>
                                <li><a href="#">보상 판매</a></li>
                                <li><a href="#">법인 차량</a></li>
                                <li><a className="text_bold" href="#">Cybertruck</a></li>
                                <li><a className="text_bold" href="#">Roadster</a></li>
                            </ul>
                        </div>
                    </div>
                    <div className="mouseover_charge" ref={charger_mouseover} onMouseLeave={chargerLeave}>
                        <div className="mega_menu">
                            <div className="mega_menu_container1">
                                <a>
                                    <img width="176px"src="https://digitalassets.tesla.com/tesla-contents/image/upload/f_auto,q_auto/Mega-Menu-Charging-Charging.png" alt="충전"/>
                                </a>
                                <div className="mega_menu_model">
                                    <h3>충전</h3>
                                    <div>
                                        <a href="#">자세히 알아보기</a>
                                        <a href="#">shop</a>
                                    </div>
                                </div>
                            </div>
                            <div className="mega_menu_container2">
                                <a>
                                    <img width="176px"src="https://digitalassets.tesla.com/tesla-contents/image/upload/f_auto,q_auto/Mega-Menu-Charging-Home-Charging.png" alt="홈차징"/>
                                </a>
                                <div className="mega_menu_model">
                                    <h3>홈차징</h3>
                                    <div>
                                        <a href="#">자세히 알아보기</a>
                                        <a href="#">shop</a>
                                    </div>
                                </div>
                            </div>
                            <div className="mega_menu_container3">
                                <a>
                                    <img width="180px"src="https://digitalassets.tesla.com/tesla-contents/image/upload/f_auto,q_auto/Mega-Menu-Charging-Supercharging.png" alt="슈퍼 차져"/>
                                </a>
                                <div className="mega_menu_model">
                                    <h3>수퍼차저</h3>
                                    <div>
                                        <a href="#">자세히 알아보기</a>
                                        <a href="#">검색</a>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div className="mega_menu_list">
                            <ul>
                                <li><a href="#">수퍼차저 투표</a></li>
                                <li><a href="#">수퍼차저 호스트 지원하기</a></li>
                                <li><a href="#">월커넥터 호스트</a></li>
                                <li><a href="#">공공 충전</a></li>
                            </ul>
                        </div>
                    </div>
                    <div className="mouseover_more" ref={more_mouseover} onMouseLeave={moreLeave}>
                        <div className="mega_menu_more">
                            <div className="mega_menu_container1">
                                <div className="mega_menu_model_more">
                                    <h5>고객 리소스</h5>
                                    <div>
                                        <a href="#">시승 신청</a>
                                        <a href="#">고객 경험담</a>
                                        <a href="#">이벤트</a>
                                    </div>
                                </div>
                            </div>
                            <div className="mega_menu_container2">
                                <div className="mega_menu_model_more">
                                    <h5>위치 서비스</h5>
                                    <div>
                                        <a href="#">Tesla 찾기</a>
                                        <a href="#">정비소 찾기</a>
                                    </div>
                                </div>
                            </div>
                            <div className="mega_menu_container3">
                                <div className="mega_menu_model_more">
                                    <h5>회사</h5>
                                    <div>
                                        <a href="#">소개</a>
                                        <a href="#">채용정보</a>
                                        <a href="#">투자자 정보</a>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div className="mouseover_shop" ref={shop_mouseover} onMouseLeave={shopLeave}>
                        <div className="mega_menu">
                                <div className="mega_menu_container1">
                                    <a>
                                        <img width="180px"src="https://digitalassets.tesla.com/tesla-contents/image/upload/f_auto,q_auto/Mega-Menu-Shop-Charging.png" alt="model s"/>
                                    </a>
                                    <div className="mega_menu_model">
                                        <h3>충전</h3>
                                    </div>
                                </div>
                                <div className="mega_menu_container2">
                                    <a>
                                        <img width="180px"src="https://digitalassets.tesla.com/tesla-contents/image/upload/f_auto,q_auto/Mega-Menu-Shop-Vehicle-Accessories.png" alt="model 3"/>
                                    </a>
                                    <div className="mega_menu_model">
                                        <h3>차량 액세서리</h3>
                                    </div>
                                </div>
                                <div className="mega_menu_container3">
                                    <a>
                                        <img width="180px"src="https://digitalassets.tesla.com/tesla-contents/image/upload/f_auto,q_auto/Mega-Menu-Shop-Apparel.png" alt="model s"/>
                                    </a>
                                    <div className="mega_menu_model">
                                        <h3>의류</h3>
                                    </div>
                                </div>
                                <div className="mega_menu_container4">
                                    <a>
                                        <img width="180px"src="https://digitalassets.tesla.com/tesla-contents/image/upload/f_auto,q_auto/Mega-Menu-Shop-Lifestyle.png" alt="model s"/>
                                    </a>
                                    <div className="mega_menu_model">
                                        <h3>라이프 스타일</h3>
                                    </div>
                                </div>
                            </div>
                        </div>
                </div>

 

 

 

 

이제는 scroll box에 해당되는 부분들을 만들었다.  이부분이 전체적인 full Page가 되는 부분이다.

 

<div className="scroll-box">
                <div className="scroll-box vertical" onScroll={handleScorll}>
                        <div className="item">
                            <video muted autoPlay loop src="https://digitalassets.tesla.com/tesla-contents/video/upload/f_auto,q_auto/Homepage-Demo-Drive-Desktop-NA.mp4"/>
                            <div className="banner">
                                <div className="banner_column">
                                    <h2>Tesla 경험하기</h2>
                                    <p><a href="/">Model 3/ Model Y 시승 신청하기</a></p>
                                </div>
                                <div className="banner_row">
                                    <button>Model S 시승 신청하기</button>
                                    <button>Model X 시승 신청하기</button>
                                </div>
                            </div>
                        </div>
                        <div className="item">
                            <div className="banner1">
                                <div className="banner_column1">
                                    <h2>Model Y</h2>
                                </div>
                                <div className="banner_row1">
                                    <button>시승 신청하기</button>
                                    <button>시승 신청하기</button>
                                </div>
                            </div>
                        </div>
                        <div className="item">
                            <div className="banner1">
                                <div className="banner_column1">
                                    <h2>Model 3</h2>
                                </div>
                                <div className="banner_row1">
                                    <button>뉴스레터 받기</button>
                                    <button>자세히 알아보기</button>
                                </div>
                            </div>
                        </div>
                        <div className="item">
                            <div className="banner1">
                                <div className="banner_column1">
                                    <h2>Model x</h2>
                                </div>
                                <div className="banner_row1">
                                    <button>주문하기</button>
                                    <button>자세히 알아보기</button>
                                </div>
                            </div>
                        </div>
                        <div className="item">
                            <div className="banner1">
                                <div className="banner_column1">
                                    <h2>Model s</h2>
                                </div>
                                <div className="banner_row1">
                                    <button>주문하기</button>
                                    <button>자세히 알아보기</button>
                                </div>
                            </div>
                        </div>
                        <div className="item">
                            <div className="banner2">
                                <div className="banner_column1">
                                    <h2>태양광과 Powerwall</h2>
                                </div>
                                <div className="banner_row2">
                                    <button>자세히 알아보기</button>
                                </div>
                            </div>
                        </div>
                        <div className="item">
                            <div className="banner2">
                                <div className="banner_column1">
                                    <h2>액세서리</h2>
                                </div>
                                <div className="banner_row2">
                                    <button>지금 쇼핑하기</button>
                                </div>
                            </div>
                        </div>
                </div>
            </div>
        </div>

보면 onScroll이라는 이벤트가 하나 존재하는데 해당 이벤트는 해당 박스의 스크롤 위치를 파악해서 display를 조정하거나,

animation효과를 주거나 하는 부분이다.

 

const handleScorll = (event) => {
        if((event.target.children[0].offsetTop) <= event.target.scrollTop && (event.target.children[1].offsetTop* 0.9) > event.target.scrollTop){
            menubar_white();
            //1.메인
            event.target.children[0].children[1].style.display = "flex";
            //2.배너
            event.target.children[1].children[1].style.display = "none";
            //3.배너
            event.target.children[2].children[1].style.display = "none";
            //4.메인
            event.target.children[3].children[1].style.display = "none";
            //5.배너
            event.target.children[4].children[1].style.display = "none";
            //6.배너
            event.target.children[5].children[1].style.display = "none";
            //7.배너
            event.target.children[6].children[1].style.display = "none";
        }
        else if((event.target.children[1].offsetTop* 0.9) <= event.target.scrollTop && (event.target.children[2].offsetTop* 0.9) > event.target.scrollTop) {
            menubar_black()
            //1.배너
            event.target.children[0].children[1].style.display = "none";
            //2.메인
            event.target.children[1].children[1].style.display = "flex";
            //3.배너
            event.target.children[2].children[1].style.display = "none";
            //4.메인
            event.target.children[3].children[1].style.display = "none";
            //5.배너
            event.target.children[4].children[1].style.display = "none";
            //6.배너
            event.target.children[5].children[1].style.display = "none";
            //7.배너
            event.target.children[6].children[1].style.display = "none";

        }
        else if((event.target.children[2].offsetTop* 0.9) <= event.target.scrollTop && (event.target.children[3].offsetTop* 0.9) > event.target.scrollTop) {
            menubar_black()
            //1.배너
            event.target.children[0].children[1].style.display = "none";
            //2.배너
            event.target.children[1].children[1].style.display = "none";
            //3.메인
            event.target.children[2].children[1].style.display = "flex";
            //4.메인
            event.target.children[3].children[1].style.display = "none";
            //5.배너
            event.target.children[4].children[1].style.display = "none";
            //6.배너
            event.target.children[5].children[1].style.display = "none";
            //7.배너
            event.target.children[6].children[1].style.display = "none";
        }
        else if((event.target.children[3].offsetTop* 0.9) <= event.target.scrollTop && (event.target.children[4].offsetTop* 0.9) > event.target.scrollTop) {
            menubar_black()
            //1.배너
            event.target.children[0].children[1].style.display = "none";
            //2.배너
            event.target.children[1].children[1].style.display = "none";
            //3.배너
            event.target.children[2].children[1].style.display = "none";
            //4.메인
            event.target.children[3].children[1].style.display = "flex";
            //5.배너
            event.target.children[4].children[1].style.display = "none";
            //6.배너
            event.target.children[5].children[1].style.display = "none";
            //7.배너
            event.target.children[6].children[1].style.display = "none";
        }
        else if((event.target.children[4].offsetTop* 0.9) <= event.target.scrollTop && (event.target.children[5].offsetTop* 0.9) > event.target.scrollTop) {
            menubar_black()
            //1.배너
            event.target.children[0].children[1].style.display = "none";
            //2.배너
            event.target.children[1].children[1].style.display = "none";
            //3.배너
            event.target.children[2].children[1].style.display = "none";
            //4.배너
            event.target.children[3].children[1].style.display = "none";
            //5.메인
            event.target.children[4].children[1].style.display = "flex";
            //6.배너
            event.target.children[5].children[1].style.display = "none";
            //7.배너
            event.target.children[6].children[1].style.display = "none";
        }
        else if((event.target.children[5].offsetTop* 0.9) <= event.target.scrollTop && event.target.children[6].offsetTop > event.target.scrollTop) {
            menubar_black()
            //1.배너
            event.target.children[0].children[1].style.display = "none";
            //2.배너
            event.target.children[1].children[1].style.display = "none";
            //3.배너
            event.target.children[2].children[1].style.display = "none";
            //4.배너
            event.target.children[3].children[1].style.display = "none";
            //5.메인
            event.target.children[4].children[1].style.display = "none";
            //6.배너
            event.target.children[5].children[1].style.display = "flex";
            //7.배너
            event.target.children[6].children[1].style.display = "none";
        }
        else if((event.target.children[6].offsetTop* 0.8) <= event.target.scrollTop) {
            menubar_black()
            //1.배너
            event.target.children[0].children[1].style.display = "none";
            //2.배너
            event.target.children[1].children[1].style.display = "none";
            //3.배너
            event.target.children[2].children[1].style.display = "none";
            //4.배너
            event.target.children[3].children[1].style.display = "none";
            //5.배너
            event.target.children[4].children[1].style.display = "none";
            //6.메인
            event.target.children[5].children[1].style.display = "none";
            //7.배너
            event.target.children[6].children[1].style.display = "flex";
        }
    };

핸들 스크롤에 대한 코드이다. 해당 박스의 위치값을 구하고, 그 위치값에 스크롤이 도달하면 화면에 변화를 주는것이다.

그리고 , 도착하면 순간적으로  팍 하고 바뀌는 느낌이 있어서 해당 위치에 오기전 80%도달했을때 변화를 주어서 부드럽게 만들어주었다.

 

메뉴 마우스 오버에 대한 스크립트는 이렇다.

 

const handleMouse = () => {
        car_mouseover.current.style.display = "flex";
        charger_mouseover.current.style.display = "none";
        more_mouseover.current.style.display = "none";
        shop_mouseover.current.style.display = "none";
        menucolor.current.style.backgroundColor = "white";
        menucolor.current.style.animation = "accodian 0.8s";
        menubar_black();
    }
    const handleMouseLeave = () =>{
        car_mouseover.current.style.display = "none";
        menucolor.current.style.backgroundColor = "";
        menucolor.current.style.animation = "";
        menubar_white();
    }

display에 대한 부분이 제일 중요했고, 또한 애니메이션 효과를 주어서 더 부드럽게 만들어보았다.

 

그렇다면 애니메이션 효과와 , scroll-snap을 사용한 css를 보면

.scroll-box {
    display: flex;
    width: 100vw;
    height: 100vh;
    overflow-y:auto
}
.scroll-box.vertical {
    flex-direction: column;
    overflow: hidden auto;
    scroll-snap-type: y mandatory;
}
.item {
    scroll-snap-align: center;
    align-items: center;
    justify-content: center;
}

스크롤 박스를 만들부분에 overflow-y를 적용하면 해당 부분이 넘어서면 스크롤 바가 생긴다.

나는 그것을 이용해서 full page를 만들었다 body에서 overflow히든을 사용하여 원래 있는 스크롤바를 숨겨주고,

박스에서 만들어진 스크롤바를 사용한것이다.

 

scroll-snap에서 중요한부분은 바로 타입이다. y mandatory라는 것이 있는데 첫번째는 x, y 방향을 나타내주고, mandatory는 이 스크롤을 좀더 유연하게 만들어주는 것이다.

 

@keyframes accodian {
    0% {
        opacity: 0;
        transform: translate3d(0, -10px, 0);
    }
    100% {
        opacity: 1;
        transform: none;
      }
}

다음으로 애니메이션을 만들어주기 위한 Keyframes이다 Keyframe에는 꼭 뒤에 이름이 필요하다.

0% ~ 100%순으로 효과가 다르게 나타나게 되고,

opacity는 화면에 보여주는 값이다 0이면 안보여주고 1이면 보여준다.

translate3d는 x, y, z값을 줄 수 있어서 여러가지 방면에서 더 활용이 높다.

 

.tesla_logo{
    display:flex;
    padding: 0px 16px 0px 16px;
    margin-left:32px;
    animation: menu 1s;
}

animaiotn효과는 아까 만들었던 이름에다가 옆에는 이 것을 실행시킬 시간초를 설정해주면 된다.

 

아 참고로 박스에 있는 것들을 absolute를 지정해주어서 스크롤이 안되는 부분이 있었는데 이부분을 주의 하면 좋을것같다.

 

나머지 css부분은 레이아웃 관련된 내용이어서 생략하도록 하겠다.

처음으로 css로 animation효과와 scroll효과를 사용해보았는데 정말 유용한 기능인것같다. 더 공부를 해도 좋을것같다.

 

그럼 만들어진 웹페이지를 공개하겠다.