본문 바로가기
Tutorial/port2023

34. 포트폴리오 사이트 만들기 : Next-Site : 인트로 영역

by @webstoryboy 2023. 8. 1.
Tutorial/portfolio

포트폴리오 사이트 만들기 - Next

by @webs 2023. 08. 01.
04
포트폴리오 사이트 만들기 : 인트로 영역
난이도 중간

소개

안녕하세요! 웹스토리보이입니다. next.js를 작업하기 전에 기본 셋팅을 완성하겠습니다. 기존 프레이워크랑 차이점이 무엇인지 알아보고, 좋은 점이 무엇이 있는지 알아보겠습니다. 그럼 바로 시작해보겠습니다.

포트폴리오 사이트 만들기

VITE SITE

  • 1. 셋팅하기
    • 1_1. vite 설치하기
    • 1_2. vite 폴더 정리하기
    • 1_3. gsap/lenis 설치하기
    • 1_4. git 연동하기
  • 2. 레이아웃
    • 2.1 레이아웃 구조 만들기
    • 2.2 메인 레이아웃 구조 만들기
    • 2.3 CSS 셋팅하기
    • 2.4 JavaScript 셋팅하기
  • 3. 헤더 영역
    • 3.1 헤더 구조 잡기
    • 3.2 헤더 디자인 설정
    • 3.3 반응형 작업하기
    • 3.4 메뉴 자바스크립트 설정
  • 4. 인트로 영역
    • 4.1 인트로 구조 잡기
    • 4.2 인트로 디자인 설정
    • 4.3 반응형 작업하기
  • 5. 스킬 영역
    • 5.1 스킬 구조 잡기
    • 5.2 스킬 디자인 설정
    • 5.3 반응형 작업하기
  • 6. 사이트 영역
    • 6.1 사이트 구조 잡기
    • 6.2 사이트 디자인 설정
    • 6.3 반응형 작업하기
  • 7. 포트폴리오 영역
    • 7.1 사이트 구조 잡기
    • 7.2 사이트 디자인 설정
    • 7.3 반응형 작업하기
    • 7.4 스크립트 작업하기
  • 8. 연락처 영역
    • 8.1 연락처 구조 잡기
    • 8.2 연락처 디자인 설정
    • 8.3 반응형 작업하기
  • 9. 푸터 영역
    • 9.1 푸터 구조 잡기
    • 9.2 푸터 디자인 설정
    • 9.3 반응형 작업하기
  • 10. 마무리
    • 10.1 스무스 효과주기
    • 10.2 링크 연결하기
    • 10.3 netlify에 배포하기

REACT SITE

  • 1. 셋팅하기
    • 1_1. React 설치하기
    • 1_2. React 폴더 정리하기
    • 1_3. 라이브러리 설치하기
    • 1_4. git 연동하기
  • 2. 라우팅 및 컴퍼넌트
    • 2_1. 라우팅 설정하기
    • 2_2. 컴퍼넌트 설정하기
    • 2_3. SCSS 설정하기
  • 3. 헤더 영역
    • 3_1. 헤더 구조잡기
    • 3_2. 헤더 디자인 설정
    • 3_3. 헤더 데이터 작업
    • 3_4. 헤더 토글 메뉴 작업하기
  • 4. 인트로 영역
    • 4_1. 인트로 구조잡기
    • 4_2. 인트로 디자인 설정
    • 4_3. 인트로 데이터 작업
  • 5. 스킬 영역
    • 5_1. 스킬 구조잡기
    • 5_2. 스킬 디자인 설정
    • 5_3. 스킬 데이터 작업
  • 6. 사이트 영역
    • 6_1. 사이트 구조잡기
    • 6_2. 사이트 디자인 설정
    • 6_3. 사이트 데이터 작업
  • 7. 포트폴리오 영역
    • 7_1. 포트폴리오 구조잡기
    • 7_2. 포트폴리오 디자인 설정
    • 7_3. 포트폴리오 데이터 작업
  • 8. 연락처 영역
    • 8_1. 연락처 구조잡기
    • 8_2. 연락처 디자인 설정
    • 8_3. 연락처 데이터 작업
  • 9. 푸터 영역
    • 9_1. 푸터 구조잡기
    • 9_2. 푸터 디자인 설정
    • 9_3. 푸터 데이터 작업
  • 10. 마무리
    • 10_1. 데이터 통합하기
    • 10_2. 스무스 효과 넣어주기
    • 10_3. 가로모드 구현하기
    • 10_4. netlify에 배포하기

VUE SITE

  • 1. 셋팅하기
    • 1_1. Vue 설치하기
    • 1_2. Vue 폴더 정리하기
    • 1_3. 라이브러리 설치하기
    • 1_4. git 연동하기
  • 2. 라우팅 및 컴퍼넌트
    • 2_1. 라우팅 설정하기
    • 2_2. 컴퍼넌트 설정하기
    • 2_3. SCSS 설정하기
  • 3. 헤더 영역
    • 3_1. 헤더 구조잡기
    • 3_2. 헤더 디자인 설정
    • 3_3. 헤더 데이터 작업
    • 3_4. 헤더 토글 메뉴 작업하기
  • 4. 인트로 영역
    • 4_1. 인트로 구조잡기
    • 4_2. 인트로 디자인 설정
    • 4_3. 인트로 데이터 작업
  • 5. 스킬 영역
    • 5_1. 스킬 구조잡기
    • 5_2. 스킬 디자인 설정
    • 5_3. 스킬 데이터 작업
  • 6. 사이트 영역
    • 6_1. 사이트 구조잡기
    • 6_2. 사이트 디자인 설정
    • 6_3. 사이트 데이터 작업
  • 7. 포트폴리오 영역
    • 7_1. 포트폴리오 구조잡기
    • 7_2. 포트폴리오 디자인 설정
    • 7_3. 포트폴리오 데이터 작업
  • 8. 연락처 영역
    • 8_1. 연락처 구조잡기
    • 8_2. 연락처 디자인 설정
    • 8_3. 연락처 데이터 작업
  • 9. 푸터 영역
    • 9_1. 푸터 구조잡기
    • 9_2. 푸터 디자인 설정
    • 9_3. 푸터 데이터 작업
  • 10. 마무리
    • 10_1. 스무스 효과 넣어주기
    • 10_2. 가로모드 구현하기
    • 10_3. 링크 클릭 구현하기
    • 10_4. netlify에 배포하기

NEXT SITE

  • 1. 셋팅하기
    • 1_1. Next 설치하기
    • 1_2. Next 폴더 정리하기
    • 1_3. 라이브러리 설치하기
    • 1_4. git 연동하기
  • 2. 라우팅 및 컴퍼넌트
    • 2_1. 라우팅 설정하기
    • 2_2. 컴퍼넌트 설정하기
    • 2_3. SCSS 설정하기
    • 2_4. Script 설정하기
  • 3. 헤더 영역
    • 3_1. 헤더 구조잡기
    • 3_2. 헤더 디자인 설정
    • 3_3. 헤더 데이터 작업
    • 3_4. 헤더 토글 메뉴 작업하기
  • 4. 인트로 영역
    • 4_1. 인트로 구조잡기
    • 4_2. 인트로 디자인 설정
    • 4_3. 인트로 데이터 작업

4. 인트로 영역

4.1 인트로 구조잡기

Next.js는 이미지를 불러오는 방법은 리액트랑 다릅니다. 우선 이미지를 불러오려면 import Image from "next/image";를 해주어야 합니다. 그리고 Image 메서드를 사용한 다음 width={300}height={300}를 설정해주어야 합니다.

import React from "react";

const Intro = () => {
    return (
        <section id="intro">
            <div className="intro__inner">
                <h2 className="intro__title">
                    port developer
                </h2>
                <div className="intro__lines" aria-hidden="true">
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                </div>
                <div className="intro__text">
                    <div className="text">
                        <div>talent is</div>
                        <div>found at the end of the</div>
                        <div>effort</div>
                    </div>
                    <div className="img">
                        <Image
                            src="/assets/img/about.jpg"
                            alt="어바웃"
                            width={300}
                            height={300}
                        />
                    </div>
                </div>
                <div className="intro__lines bottom" aria-hidden="true">
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                </div>
            </div>
        </section>
    ) 
}

export default Intro;

4.2 인트로 디자인 설정

CSS로 SCSS로 변형하여 작업하였습니다.

#intro {
    height: 100vh;
}
.intro__inner {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: flex-start;
    justify-content: flex-end;
    flex-direction: column;
    padding: 16px;

    @media (max-width: 800px){
        justify-content: center;
    }

    .intro__title {
        font-size: 10vw;
        text-transform: uppercase;
        line-height: 1;
        font-weight: 800;
        white-space: nowrap;
        text-indent: -0.5vw;
        letter-spacing: -0.3vw;

        @media (max-width: 320px){ 
            display: none;
        }
    }
    .intro__text {
        width: 100%;
        height: 40vh;
        background-color: var(--black);
        color: var(--white);
        display: flex;
        align-items: center;
        justify-content: center;
        flex-direction: column;
        position: relative;

        .text {
            font-size: 3vw;
            line-height: 1;
            font-weight: 900;
            text-transform: uppercase;
            text-decoration: underline;
            text-align: center;
            position: relative;
            z-index: 100;
            transition: all 0.3s;
            cursor: all-scroll;

            @media (max-width: 800px){ 
                font-size: 24px;
            }
        }
        .img {
            position: absolute;
            left: 50%;
            top: 50%;
            transform: translate(-50%, -50%);
            width: 30vh;
            height: 30vh;
            border-radius: 50%;
            overflow: hidden;
            filter: grayscale(100%);
            transition: all 0.3s;

            @media (max-width: 320px){ 
                width: 20vh;
                height: 20vh;
            }
        }

        &:hover .text {
            opacity: 0;
        }
        &:hover .img {
            filter: grayscale(0);
        }
    }
    .intro__lines {
        width: 100%;

        .line {
            display: block;
            width: 100%;
            height: 1px;
            background-color: var(--black);
            margin-bottom: 0.5vw;

            &:nth-child(1){
                height: 1px;
            }
            &:nth-child(2){
                height: 2px;
            }
            &:nth-child(3){
                height: 5px;
            }
            &:nth-child(4){
                height: 9px;
            }
            &:nth-child(5){
                height: 13px;
            }
            &:nth-child(6){
                height: 17px;
            }
            &:nth-child(7){
                height: 25px;
            }
        }

        &.bottom {
            .line {
                margin-top: 0.5vw;
                margin-bottom: 0;
                display: none;

                @media (max-width: 800px){ 
                    display: block;
                }

                &:nth-child(1){
                    height: 25px;
                }
                &:nth-child(2){
                    height: 17px;
                }
                &:nth-child(3){
                    height: 13px;
                }
                &:nth-child(4){
                    height: 9px;
                }
                &:nth-child(5){
                    height: 5px;
                }
                &:nth-child(6){
                    height: 2px;
                }
                &:nth-child(7){
                    height: 1px;
                }
            }
        }
    }
}

4.3 인트로 데이터 작업

데이터화 작업은 간단합니다. 아래를 참고해주세요!

import React from "react";
import Image from "next/image";

import { introText } from "../constants";

const Intro = () => {
    return (
        <section id="intro">
            <div className="intro__inner">
                <h2 className="intro__title">
                    {introText.title}
                </h2>
                <div className="intro__lines" aria-hidden="true">
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                </div>
                <div className="intro__text">
                    <div className="text">
                        <div>{introText.desc[0]}</div>
                        <div>{introText.desc[1]}</div>
                        <div>{introText.desc[2]}</div>
                    </div>
                    <div className="img">
                        <Image
                            src="/assets/img/about.jpg"
                            alt="어바웃"
                            width={300}
                            height={300}
                        />
                    </div>
                </div>
                <div className="intro__lines bottom" aria-hidden="true">
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                    <span className="line"></span>
                </div>
            </div>
        </section>
    ) 
}

export default Intro;

3. 마무리

인트로 섹션도 작업을 마무리 했습니다. Next.js에서는 이미지 최적화를 따로 해주기 때문에 Image 메서드를 사용해야 합니다. 소스를 확인해 보면 해상도 별로 이미지가 셋팅되어 있는 것을 확인 할 수 있습니다. 그럼 오늘도 수고하셨습니다. 🙄


예제 목록

댓글