개발 기술/css 애니메이션 (with js)

글자가 그려지는 애니메이션(with, stroke-dashoffset)

by GicoMomg (Lux) 2021. 10. 11.

이번 시간에는 stroke-dashoffset, stroke-dasharray를 사용해, svg의 text 애니메이션을 만들어본다.

1. 미리보기

See the Pen alpha-svg by KumJungMin (@kumjungmin) on CodePen.



2. 코드 분석

1) html

(1) 전체 구조

  • content는 svg의 부모로, svg를 수직 중앙 정렬시킨다.
  • svg 내부에서는 여러 text태그가 존재하며 글자 각각을 의미한다.

(2) 전체 코드

  • 위 그림을 코드로 보면 아래와 같다.
    만약 svg태그에 대해 궁금하면 바로 (3)을 읽어보는 걸 추천 :)
    <div class="content">
    <svg width=400 height=200 viewBox="0 0 400 200"> 
      <text x="40" y="65%">S</text> 
      <text x="85" y="60%">V</text>
      <text x="130" y="60%">G</text>
      <text x="190" y="60%">T</text>
      <text x="230" y="65%">E</text>
      <text x="275" y="70%">S</text>
      <text x="320" y="66%">T</text>
    </svg>
    </div>

(3) svg태그란?

html에서 사용된 svg에 대해 간단히 알아보자

  • 우리가 image로 주로 사용하는 png, jpg는 픽셀을 이용하여 그림을 그린다.
  • 하지만 svg는 벡터 기반으로 이미지 표현한다.
  • 벡터 기반이기 때문에, 크기를 조절해도 이미지가 깨지지 않는 장점이 있다 👍
  • 또한 svg태그에 rect, test태그를 사용하면 도형과 글자를 표현할 수 있다.
  • 사용법은 아래와 같다.

A. svg로 직선 그리기

  • 먼저, svg에 width, height속성으로 너비, 높이를 지정한다.
    <svg width="300" height="300"></svg>
  • line은 직선을 나타내며, 시작(x1, y1) ~ 끝(x2, y2)지점을 지정하면 된다.
    <svg width="300" height="300">
    <line x1="0" y1="0" x2="200" y2="200"/>
    </svg>

    See the Pen svg-line by KumJungMin (@kumjungmin) on CodePen.


B. svg로 사각형 그리기

  • rect는 사각형을 그리며, width, height만 지정하면 된다.
    <svg width="300" height="300">
    <rect width="300" height="100"/>   <!--너비, 높이 지정-->
    </svg>

    See the Pen svg_rect by KumJungMin (@kumjungmin) on CodePen.


C. svg로 글자 나타내기

  • text로 글자를 나타낼 수 있으며 x, y로 글자의 위치를 지정한다.
    <svg width="300" height="300">
    <text x="0" y="15" fill="red">hello world</text>
    </svg>

    See the Pen svg-text by KumJungMin (@kumjungmin) on CodePen.




2) scss

(1) content 설정하기

[1] content가 수평&수직 중앙 정렬이 되도록 그림과 같이 지정한다.

.content {
  width: 400px;
  height: 400px;
  position: absolute;  /*[1] 꼭 필요*/
  top: 50%;            /*[1]*/
  left: 50%;           /*[1]*/
  transform: translate(-50%, -50%); /*[1]*/
  ...
}

[2] content 내부 요소가 수평&수직 중앙정렬이 되도록 flex를 사용한다.

.content {
  ...
  display: flex;           /*[2]*/ 
  align-items: center;     /*[2] 수직 중앙*/
  justify-content: centent;/*[2] 수평 중앙*/
  background: ...;  /*배경색은 자유*/
}

(2) text 기본 설정하기

애니메이션을 지정하기에 앞서, text에 기본적인 디자인을 입혀보자!

svg text { 
  font-family: 'Anton', sans-serif;  /*글씨체*/
  font-size: 6rem;    /*[1]*/
  stroke-width: 3px;  /*[2]*/
  stroke: #fff;       /*[3]*/
  fill: transparent;  /*[4]*/
  ...
}

[1] font-size를 사용해 text의 글자 크기를 6rem으로 지정한다.
[2] 그 다음 stroke-width를 사용해 외곽선 굵기를 변경한다.
[3] stroke로 외곽선 색상을 흰색으로 한다.
[4] 마지막으로 fill: transparent를 하여 글자 내부색은 투명으로 한다.


위와 같이 적용하면 아래와 같은 모습이 된다.


(3) 글자 효과의 핵심, stroke-dashXXXX

text태그에 그려지는 효과를 주기위해서는 stroke-dashoffset
stroke-dasharray이 필요하다! 그렇다면 이 녀석들은 무슨 역할을 할까?
한 번 알아보자! 💪

A. stroke-dasharray?

  • 외곽선(stroke)을 대쉬형태로 만든다.
  • 값을 부여한 만큼 대쉬길이가 늘어난다.
  • 만약 대쉬를 글자 길이(750)로 지정하면 하나의 대쉬가 글자를 다 채우게 된다.

B. stroke-dashoffset?

  • 어느 지점에서부터 대쉬(dash)를 시작할지 결정한다.
  • 그림은 대쉬길이를 글자길이(750)로 하고 offset(시작점)만 변경한 모습이다.

그렇다면, 글자가 그려지는 효과를 내려면 이 두 속성을 어떻게 써야 할까?
바로 dash를 글자 길이로 하고, 대쉬 시작지점이 변하게 하면 된다 😀

  • offset은 대쉬 시작 지점을 변경하므로, 이 값이 낮아질수록 글자를 나타낼 수 있는 범위가 넓어진다.
  • 결국, gif처럼 offset을 낮추면 글자가 더 나타나게 되는 것이다.



(4) text에 애니메이션 적용하기

  • 앞서 말했듯이 우리는 dash를 글자 길이로 하고, 대쉬 시작지점이 변하게하는 애니메이션이 필요하다.
  • keyframes를 이용해 아래와 같은 애니메이션을 만든다.
@keyframes stroke { 
  0% { 
    stroke-dashoffset: 750;   /*끝지점에서 대쉬를 그림*/
  } 
  70% {
    fill: #fff;
  }
  100% { 
    stroke-dashoffset: 0;     /*시작지점에서 대쉬를 그림*/
    fill: #fff;
  } 
}

  • 그 다음, text태그에 stroke-dashoffset, stroke-dasharray 초기값을 설정한다.
    svg text { 
    ...
    stroke-dashoffset: 750;  /*끝지점*/
    stroke-dasharray: 750;   /*하나의 대쉬가 글자를 다 그리게함*/
    ...
    }

  • 만들어 둔 애니메이션을 animation속성을 이용해 추가한다.
    svg text { 
    ...
    animation: stroke 1.5s linear;  /*애니메이션명 시간 부드럽게*/
    ...
    }

  • 우리는 글자가 다 나타난 시점에서 애니메이션을 멈추게 하고 싶다.
  • animation-fill-mode: forwards로 하여 100% 지점에서 멈추게 한다.
    svg text { 
    ...
    animation-fill-mode: forwards;  /*100%에서 멈추게*/
    }

(5) 글자 효과가 순차적으로 발생하게 하기

  • preview를 보면 글자가 나타날 때, 글자 하나가 끝나면 다른 글자가 그려지는 걸 확인할 수 있다.
  • 이 효과를 위해서 글자별로 애니메이션 시작지점을 달리해야 하는데,
    animation-delay로 지연시간을 이용하면 된다.

$total: 7;                        /*글자개수 변수*/
@for $i from 1 through $total {   /*1~7까지 반복*/
  text:nth-child(#{$i}) {         /*같은 부모의 N번째 요소*/
    animation-delay: $i - 1 + s;  /*애니메이션 지연시간*/
  }
}





출처
아래 출처로 이동하면 더 자세히 알 수 있다고? 꼭 가봐야 겠는데~ 🤔

반응형

댓글