Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: 메인 페이지 강의 생성/참여하기 카드를 사용자가 확인할 수 있다 (UI 작업) #16

Closed
4 tasks done
Byeonjin opened this issue Nov 14, 2023 · 0 comments · Fixed by #151
Closed
4 tasks done
Assignees
Labels
FE 프론트엔드 작업 ✨ Feat 기능 개발
Milestone

Comments

@Byeonjin
Copy link
Collaborator

Byeonjin commented Nov 14, 2023

Feature Description

메인 페이지 기본 UI 작업 close #16

To-Do

  • 메인 페이지 기본 UI 구성
  • 메인 페이지 카드 flip 애니메이션 구현
  • 메인 페이지 새로운 강의 카드 뒷면 구현
  • 메인 페이지 강의 참여하기 카드 뒷면 구현

추가 사항

카드 flip 애니메이션 구현

메인 페이지에서 카드를 뒤집는 애니메이션을 구현하기 위해 다음과 같은 방법을 사용하였습니다.

<div id="wrapper">
  <div id="card">
    <div id="front"/>
    <div id="back"/>
  </div>
</div>
  • wrapper : 카드의 사이즈를 결정합니다. 해당 요소의 크기를 기준으로 카드 크기를 결정합니다. 추가적으로 해당 요소를 hover시에 하위의 card를 뒤집도록 할 수 있습니다. (card 요소를 hover시에 뒤집도록 할 경우, 뒤집하는 과정에서 해당 요소의 hover가 정상적으로 작동하지 않을 가능성이 있음)
  • card : 해당 요소 내부에 frontback이 겹쳐 존재하여 이를 뒤집는 것으로 카드를 뒤집는 애니메이션을 구현할 수 있습니다.

각 id별로 필요한 css 속성은 아래와 같습니다.

.wrapper {
  // 요소의 크기를 여기서 결정
  perspective: 1000px;
}

.card {
  width: 100%;
  height: 100%;
  position: relative;
  transition: all 0.5s;
  perspective-origin: center;
  transform-style: preserve-3d;
}

.front {
  width: 100%;
  height: 100%;
  z-index: 2;
  position: absolute;
  backface-visibility: hidden;
}

.back {
  width: 100%;
  height: 100%;
  z-index: 1;
  transform: rotateY(180deg);
}
  • 상위에 relative를 지정하고 하위 요소 2개에 absolute를 지정하는 것으로 카드가 겹치도록 하였습니다.
  • backtransform: rotateY(180deg);를 적용하여 뒤집힌 상태로 겹쳐지도록 하였으며, 카드가 뒤집혔을 때 정상적으로 보이기 위해 해당 속성을 추가하였습니다.
  • frontback에 비해 앞에 위치해야 하기 때문에 z-index를 달리하여 front가 더 높은 값을 가지도록 하였습니다.
  • frontbackface-visibility: hidden;속성을 지정하여 뒤집었을 때, 뒷면이 front의 뒷면이 보이지 않도록 하여 back이 정상적으로 표시될 수 있도록 하였습니다.
  • 카드가 뒤집히는 애니메이션을 사실적으로 표현하기 위해 transform-style: preserve-3d;card에 추가하였습니다. 해당 속성은 해당 컨테이너를 3D 공간에서 렌더링하도록 지정합니다.
  • 관련하여 원근감을 줄 수 있는 perspective: 1000px;를 지정하였습니다. perspective의 값이 높을 수록 더욱 멀리서 보는 효과를 줄 수 있습니다.
  • perspective와 같이 사용되는 perspective-origin: center;perspective의 기준점을 설정해줍니다. 중앙을 기준으로 효과를 줄 수 있도록 추가하였습니다.

여기서 요소 내부의 특정 버튼을 클릭하거나 요소를 hover할 경우에 card에 아래 속성을 추가하는 것으로 카드를 뒤집을 수 있습니다.

// wrapper hover 시나 특정 이벤트 발생 시 카드 뒤집기
transform: rotateY(180deg);

해당 구조를 시각화하면 아래와 같습니다.

image

메인 페이지에는 카드가 2개 존재하며, 각 카드별로 state를 두어 뒤집혔는지를 판단하였습니다. 한 쪽이 뒤집힌다면, 다른 한 쪽은 다시 앞면을 보이도록 하며, 관련된 state들을 초기화하도록 하였습니다.

강의 코드 입력창 구현

총 6자리의 숫자로 구성된 강의 코드를 입력받기 위해 총 6개의 input을 추가하여 이를 구현하였습니다. typenumber로 지정할 경우, 기본값이 0으로 지정될 뿐더러 각 input마다의 입력 자릿수를 제한할 수 없기 때문에 이를 위해 string으로 지정하였습니다.

<div className="w-full h-16 flex flex-row justify-between gap-2 mt-2">
      {inputs.map((value, index) => (
        <input
          key={index}
          type="string"
          maxLength={1}
          value={value}
          onChange={handleChange(index)}
          onKeyDown={handleBackspace(index)}
          ref={(element) => (inputRefs.current[index] = element)}
          className="border-black flex-grow w-full rounded-xl text-center align-middle medium-32"
        />
      ))}
    </div>

각 자리별로 숫자를 입력했을 경우에 다음 input으로 넘어가도록 처리하기 위해 index를 활용하였습니다.

const inputRefs = useRef<(HTMLInputElement | null)[]>([]);
const [inputs, setInputs] = useState<string[]>(Array(6).fill(""));

 const handleChange = (index: number) => (e: React.ChangeEvent<HTMLInputElement>) => {
    const value = e.target.value;

    if (value === "" || /^[0-9]$/i.test(value)) {
      const newInputs = [...inputs];
      newInputs[index] = value;
      setInputs(newInputs);

      if (value && index < inputs.length - 1) {
        inputRefs.current[index + 1]?.focus();
      }
    }
  };

  const handleBackspace = (index: number) => (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === "Backspace" && !inputs[index] && index > 0) {
      inputRefs.current[index - 1]?.focus();
    }
  };

배열의 형태로 state를 관리하여 각 자리에 입력된 값을 반영하였습니다. 입력되었을 경우, 다음 index에 위치하는 inputfocus되도록 처리하였습니다. 반대로 Backspace가 입력된 경우, 이전 indexfocus되도록 처리하였습니다.

focus 시에 input박스 테두리 변경

tailwind의 동일한 속성과 관련하여 중복해서 지정할 경우, 정상적으로 작동하지 않는 경우가 있었습니다. 이를 해결하기 위해 아래와 같은 방식으로 해결하였습니다.

<input
            type="text"
            className="rounded-xl border-black w-full flex-grow medium-12 p-3 focus:outline-none focus:ring-1 focus:ring-boarlog-100 focus:border-transparent"
            placeholder="강의 제목을 입력해주세요"
            maxLength={50}
          />
  • border-black으로 기본 border의 색상을 지정합니다.
  • focus되었을 경우, 아래 속성이 적용됩니다.
  • outline-none : focus시의 브라우저의 기본 outline을 제거합니다.
  • ring-1, ring-boarlog-100 : focus 시에 ring을 추가하고 색상을 지정합니다.
  • border-transparent : 요소가 focus될 때 테두리를 투명하게 처리합니다.

border 대신에 ring만 표시하는 것으로 focus시에 border 색상이 변경되는 것처럼 처리하였습니다.

카드 flip 애니메이션

2023-11-28.11-53-54.mp4

강의 코드 입력

2023-11-28.11-54-09.mp4

input창 focus

2023-11-28.11-54-27.mp4
@Byeonjin Byeonjin added the ✨ Feat 기능 개발 label Nov 14, 2023
@Jw705 Jw705 added the FE 프론트엔드 작업 label Nov 14, 2023
@LellowMellow LellowMellow self-assigned this Nov 23, 2023
LellowMellow added a commit to LellowMellow/web13_Boarlog that referenced this issue Nov 23, 2023
- 중앙 카드를 표시할 HomeSection component를 추가하였습니다
@LellowMellow LellowMellow added this to the 4주차 milestone Nov 27, 2023
LellowMellow added a commit to LellowMellow/web13_Boarlog that referenced this issue Nov 27, 2023
- 메인페이지 타이틀과 더불어 카드 flip 애니메이션을 추가하였습니다.
- 관련된 스타일을 global.css에 정의하였습니다.
LellowMellow added a commit to LellowMellow/web13_Boarlog that referenced this issue Nov 27, 2023
- 카드 UI 작업과 더불어 추가적인 Toast 연결까지의 작업 내역을
  복구하였습니다.
LellowMellow added a commit to LellowMellow/web13_Boarlog that referenced this issue Nov 28, 2023
- 카드를 클릭했을 경우, 카드가 뒤집히도록 front에 event를
  추가하였습니다.
LellowMellow added a commit to LellowMellow/web13_Boarlog that referenced this issue Nov 28, 2023
- 강의 코드 입력 중에 enter를 눌렀을 경우의 event를 추가하였습니다.
LellowMellow added a commit to LellowMellow/web13_Boarlog that referenced this issue Nov 28, 2023
- 불필요한 ref를 제거하였습니다.
LellowMellow added a commit to LellowMellow/web13_Boarlog that referenced this issue Nov 28, 2023
- 메인 페이지의 일부 문구를 피드백에 따라 수정하였습니다.
LellowMellow added a commit that referenced this issue Nov 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FE 프론트엔드 작업 ✨ Feat 기능 개발
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants