본문 바로가기
개발/React

리액트 CSS - styled-components로 타이핑 효과 만들기 (Make Simple Typing Effect with styled-components)

by 피로물든딸기 2023. 6. 27.
반응형

리액트 전체 링크

 

참고

- https://styled-components.com/

 

styled-components로 타이핑 효과 만들기
module.css로 CSS 스타일 관리하기
classnames로 CSS 스타일 조건부 렌더링하기

 

아래 링크를 참고하여 타이핑 애니메이션 효과를 그대로 리액트에 재현해보자.

https://dabblet.com/gist/b04ab9f41084b0a66960

 

코드는 다음과 같다.

 

App.js

import React from "react";
import "./App.css";

const App = () => {
  return (
    <div>
      <h1>Blood StrawBerry</h1>
    </div>
  );
};

export default App;

 

App.css

@keyframes typing {
  from { width: 0 }
}

@keyframes caret {
  50% { border-right-color: transparent; }
}

h1 {
  font: bold 200% Consolas, Monaco, monospace;
  /*width: 8.25em;*/
  width: 16ch;
  white-space: nowrap;
  overflow: hidden;
  border-right: .05em solid;
  animation: typing 8s steps(16),
	           caret 1s steps(1) infinite;
}

 

위의 효과는 글자 크기가 일정한 Consolas 같은 글꼴에만 적용된다.

만약에 글자 수가 변하면 (Blood StrawBerry = 16 → length

width: [length]ch; 와 animation: typing 8s steps(length), 를 수정해야 한다.


styled-components 적용하기

 

styled-components를 이용하면 리액트 js 코드에 css 코드를 쉽게 합칠 수 있다.

위와 같이 애니메이션이 포함된 경우도 수정이 가능하다.

npm install styled-components

 

npm으로 설치가 완료되면 import 하자.

import styled, { keyframes } from "styled-components";

 

예시 코드는 다음과 같다.

import React from "react";
import styled, { keyframes } from "styled-components";

const App = () => {
  const typing = keyframes`
    from {width : 0}
  `;

  const caret = keyframes`
  50% { border-right-color: transparent; }
`;

  const TypeAnimation = styled.div`
    h1 {
      font: bold 200% Consolas, Monaco, monospace;
      width: 16ch;
      white-space: nowrap;
      overflow: hidden;
      border-right: 0.05em solid;
      animation: ${typing} 8s steps(16),
        ${caret} 1s steps(1) infinite;
    }
  `;

  return (
    <div>
      <TypeAnimation>
        <h1>Blood StrawBerry</h1>
      </TypeAnimation>
    </div>
  );
};

export default App;

 

css 애니메이션은 아래와 같이 변경한다.

@keyframes typing {
  from { width: 0 }
}

---------------------------

const typing = keyframes`
  from {width : 0}
`;

 

그리고 애니메이션의 이름을 템플릿 리터럴에 넣어주면 된다.

  const TypeAnimation = styled.div`
  h1 {
    font: bold 200% Consolas, Monaco, monospace;
    width: 16ch;
    white-space: nowrap;
    overflow: hidden;
    border-right: .05em solid;
    animation: ${typing} 8s steps(16),
               ${caret} 1s steps(1) infinite;
  }
`;

 

위에서 만든 styled-components를 아래와 같이 감싸주면 된다.

<TypeAnimation>
  <h1>Blood StrawBerry</h1>
</TypeAnimation>

 

조금 더 응용하면 props를 이용해 글자 수가 변할 때 마다 고칠 필요가 없게 만들 수도 있다.

먼저 글자 수에 따라 바뀌는 부분에 16 → props.length를 받도록 하자.

  const TypeAnimation = styled.div`
    h1 {
      font: bold 200% Consolas, Monaco, monospace;
      width: ${(props) => props.length}ch;
      white-space: nowrap;
      overflow: hidden;
      border-right: 0.05em solid;
      animation: ${typing} 8s steps(${(props) => props.length}),
        ${caret} 1s steps(1) infinite;
    }
  `;

 

length를 다음과 같이 넘겨주면 된다.

  const title = "Blood StrawBerry";

  return (
    <div>
      <TypeAnimation length={title.length}>
        <h1>{title}</h1>
      </TypeAnimation>
    </div>
  );
};

 

어떻게 수정하더라도 모두 잘 적용된다.

 

전체 코드는 다음과 같다.

import React from "react";
import styled, { keyframes } from "styled-components";

const App = () => {
  const typing = keyframes`
    from {width : 0}
  `;

  const caret = keyframes`
  50% { border-right-color: transparent; }
`;

  const TypeAnimation = styled.div`
    h1 {
      font: bold 200% Consolas, Monaco, monospace;
      width: ${(props) => props.length}ch;
      white-space: nowrap;
      overflow: hidden;
      border-right: 0.05em solid;
      animation: ${typing} 8s steps(${(props) => props.length}),
        ${caret} 1s steps(1) infinite;
    }
  `;

  const title = "Blood StrawBerry";

  return (
    <div>
      <TypeAnimation length={title.length}>
        <h1>{title}</h1>
      </TypeAnimation>
    </div>
  );
};

export default App;
반응형

댓글