D3.js, SVG를 이용한 나만의 로딩 아이콘 만들어보기

Jake Seo·2020년 5월 8일
3
post-thumbnail

D3.js, SVG를 이용한 나만의 로딩 아이콘 만들어보기

개요

SVG는 시각화, 상호작용하는 웹을 만들 때 자주 사용되는 스펙이다. D3.js는 SVG를 조금 다루기 쉽게 만들어준다.

SVG와 D3.js를 이용하여 나만의 로딩 아이콘을 만들어보자.

색이 변하는 글씨로 로딩 표기하기

아래와 같은 결과물을 만들어보자!

먼저, HTML에 svg 태그를 생성하고, 그 안에 text태그를 넣어서 글씨를 쓴다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <style>
      .heavy {
        font: bold 30px sans-serif;
      }
    </style>
  </head>
  <body>
    <svg height="200" width="400">
      <text id="loading_text" x="0" y="50" fill="black" class="heavy">
        Loading ...
      </text>
      SVG를 지원하지 않는 브라우저입니다.
    </svg>
  </body>
</html>

기본 색상은 블랙으로 했고, 글씨를 조금 강조시키기 위해 Heavy라는 스타일을 입혔다.

여기까지 하면 결과는 다음과 같다.

이제 여기서 빨간색과 검은색을 왔다갔다하도록 d3 라이브러리를 임포트하고 코드를 넣어보자.

    <script src="https://d3js.org/d3.v4.js"></script>
    <script>

      repeat();

      function repeat() {
        d3.select('#loading_text') // 셀렉터로 태그 잡기
          .transition() // 변환을 주는 함수
          .duration(1000) // 변환까지 걸리는 시간 설정 (ms) 및 빨간색으로 변환
          .attr('fill', 'red') // 빨간색 채우기
          .transition() // 변환을 다시 주기
          .attr('fill', 'black') // 검정색으로 변환
          .on('end', repeat); // 변환이 끝나면 repeat 함수를 다시 호출하여 반복하기
      }
    </script>

결과 소스코드

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
    <style>
      .heavy {
        font: bold 30px sans-serif;
      }
    </style>
  </head>
  <body>
    <svg height="200" width="400">
      <text id="loading_text" x="0" y="50" fill="black" class="heavy">
        Loading ...
      </text>
      SVG를 지원하지 않는 브라우저입니다.
    </svg>
    <script src="https://d3js.org/d3.v4.js"></script>
    <script>
      // d3.select('#loading_text').transition().duration(1000).attr('fill', 'red');

      repeat();

      function repeat() {
        d3.select('#loading_text') // 셀렉터로 태그 잡기
          .transition() // 변환을 주는 함수
          .duration(1000) // 변환까지 걸리는 시간 설정 (ms) 및 빨간색으로 변환
          .attr('fill', 'red') // 빨간색 채우기
          .transition() // 변환을 다시 주기
          .attr('fill', 'black') // 검정색으로 변환
          .on('end', repeat); // 변환이 끝나면 repeat 함수를 다시 호출하여 반복하기
      }
    </script>
  </body>
</html>

동그라미가 왔다갔다하며 로딩 표기하기

위에 글씨 로딩과 같은 맥락으로 진행하면 된다.

단, 움직이는 좌표를 생각하고 동그라미 순서대로 애니메이션이 진행될 수 있게 해주면 된다.

코드는 다음과 같다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>
  <body>
    <svg height="200" width="400">
      <circle cx="50" , cy="50" r="10"></circle>
      <circle cx="80" , cy="50" r="10"></circle>
      <circle cx="110" , cy="50" r="10"></circle>
      <circle cx="140" , cy="50" r="10"></circle>
      <circle cx="170" , cy="50" r="10"></circle>
      SVG를 지원하지 않는 브라우저입니다.
    </svg>
    <script src="https://d3js.org/d3.v4.js"></script>
    <script>
      repeat();

      function turnToRed(selector) {
        d3.selectAll(`${selector}`).each(function (d, i, x) {
          var event = d3
            .select(this)
            .transition()
            .delay(i * 100)
            .duration(100)
            .attr('fill', 'red')
            .attr('cy', function (a, b, c) {
              return 50 - 17;
            })
            .transition()
            .attr('cy', function (a, b, c) {
              return 50 + 17;
            })
            .transition()
            .attr('cy', function (a, b, c) {
              return 50;
            })
            .transition()
            .attr('fill', 'black');

          if (i === x.length - 1) {
            event.on('end', () => {
              turnToRed('circle');
            });
          }
        });
      }

      function repeat() {
        turnToRed('circle');
      }
    </script>
  </body>
</html>

위에 소스를 이해했다면 이해에 큰 어려움은 없을 것 같다.

참고자료

https://css-tricks.com/svg-properties-and-css/
https://www.d3-graph-gallery.com/graph/interactivity_transition.html#button

profile
풀스택 웹개발자로 일하고 있는 Jake Seo입니다. 주로 Jake Seo라는 닉네임을 많이 씁니다. 프론트엔드: Javascript, React 백엔드: Spring Framework에 관심이 있습니다.

0개의 댓글

관련 채용 정보