CSS와 JavaScript로 타이핑 애니메이션 만들기

Document
Typing Animation.

전체 코드

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<style>
.typing {
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  place-items: center; 
  justify-content: center;
  width: 100%;
  height: 100%;
}

@keyframes typing {
  from {
      width: 0
  }
  to {
      width: 100%;
  }
}
      
@keyframes blink {
  50% {
      border-color: transparent
  }
}
</style>
<body>
  <div class="typing">
    Typing Animation...
  </div>
<script>
  const typing = document.querySelector('.typing')
  const line = document.createElement('div')

  line.textContent = typing.textContent 
  typing.textContent = ''

  const lineStyle = {
    margin: '0 auto',
    color: 'black',
    animation: `
        typing 3s steps(${line.textContent.length}, end) forwards, 
        blink .5s step-end infinite alternate
    `,
    whiteSpace: 'nowrap',
    overflow: 'hidden',
    borderRight: '1px solid',
    fontSize: '1em',
  }
  
  Object.keys(lineStyle).forEach(
    key => {
      line.style[key] = lineStyle[key]
    }
  )
  
  typing.append(line)
</script>
</body>
</html>

HTML 부분

<div class="typing">
  Typing Animation
</div>

화면 중앙에 “Typing Animation”이라는 문구를 표시할 div 태그를 생성합니다. 이후 JavaScript로 이 문구를 한 글자씩 출력하는 효과를 추가할 것입니다.

CSS로 타이핑 애니메이션 만들기

@keyframes typing {
  from { width: 0; }
  to { width: 100%; }
}

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

.typing {
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  place-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

@keyframes typing → width: 0 → 100%을 통해 텍스트가 점점 길어지도록 함.

@keyframes blink → 커서 깜빡이는 효과를 추가함.

.typing → 텍스트를 화면 중앙에 배치하는 역할.

JavaScript로 애니메이션 적용하기

const typing = document.querySelector('.typing')
const line = document.createElement('div')

line.textContent = typing.textContent 
typing.textContent = ''

  const lineStyle = {
    margin: '0 auto',
    color: 'black',
    animation: `
        typing 3s steps(${line.textContent.length}, end) forwards, 
        blink .5s step-end infinite alternate
    `,
    animationDelay: '1s',
    animationIterationCount: 'infinite',
    whiteSpace: 'nowrap',
    overflow: 'hidden',
    borderRight: '1px solid',
    fontSize: '1em',
  }

Object.keys(lineStyle).forEach(
  key => {
    line.style[key] = lineStyle[key]
  }
)

typing.append(line)

animation 속성에서 steps(글자 수, end)를 사용해 한 글자씩 출력되도록 설정.

borderRight: ‘1px solid’ → 타이핑 커서 효과 추가.

animationIterationCount: ‘infinite’, 이부분을 제거하면 무한반복되지 않습니다.

타이핑 속도 조절: typing 3s steps(글자 수, end)에서 3s 이부분을 수정하면 타이핑 속도 조절 가능

무한반복용

애니메이션을 반복을 사용할거면 애니메이션이 종료 후 delay가 필요합니다. 그러지 않으면 바로 다음 애니메이션이 진행되어 글자가 완성되지 않은 거처럼 보이는 거 같습니다.

const typing = document.querySelector('.typing');
const line = document.createElement('div');

line.textContent = typing.textContent;
typing.textContent = '';

const lineStyle = {
  margin: '0 auto',
  color: 'black',
  whiteSpace: 'nowrap',
  overflow: 'hidden',
  borderRight: '1px solid',
  fontSize: '1em',
};

Object.keys(lineStyle).forEach(
  key => {
    line.style[key] = lineStyle[key];
  }
);

typing.append(line);

const startTypingAnimation = () => {
  line.style.animation = `typing 3s steps(${line.textContent.length}, end) forwards, blink .5s step-end infinite alternate`;
};

startTypingAnimation();

line.addEventListener('animationend', (e) => {
  if (e.animationName === 'typing') {
    setTimeout(() => {
      line.style.animation = 'none';  // 애니메이션을 초기화
      void line.offsetWidth;  // 리플로우를 강제하여 다시 애니메이션 적용 가능하도록 함
      startTypingAnimation();
    }, 1000); // 1초 후 재실행
  }
});

Leave a Comment