Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

nomad-programmer

[Programming/HTML|CSS] SVG 태그 본문

Programming/HTML|CSS

[Programming/HTML|CSS] SVG 태그

scii 2020. 12. 23. 16:57

SVG(Scalable Vector Graphics)는 벡터 그래픽을 표현할 때 사용하는 형식이다. 원래 SVG 태그는 인터넷 익스플로러 8 버전 이후의 인터넷 익스플로러에서만 지원하는 기능이었다. 하지만 HTML5부터는 SVG 태그가 표준으로 제정되어 모든 웹 브라우저에서 사용할 수 있게 되었다. 기존의 플래시가 벡터 이미지를 사용했으므로 SVG 태그를 사용하면 플래시 콘텐츠를 쉽게 HTML5로 변환할 수 있다.

기본적인 사용 방법

다음과 같이 HTML 페이지를 구성하고 body 태그안에 sav 태그를 입력한다.

svg 태그는 width 속성과 height 속성을 반드시 사용해야 한다.
<body>
    <svg width="700" height="500">
    </svg>
</body>

svg 태그 내부에는 SVG 관련 태그를 입력한다. 

<body>
    <svg width="700" height="300">
      <rect width="700" height="300" fill="green" />
      <circle cx="350" cy="150" r="100" fill="orange" />
    </svg>
</body>

fill 속성을 사용해 색을 칠한다. 선은 stroke 속성을 사용해 그린다.

생성된 SVG 태그

이미지를 사용했을 경우와 SVG 태그를 사용했을 경우의 차이는 무엇일까?

SVG는 Scalable Vector Graphics의 약자이다. 즉, 벡터 그래픽을 표현할 때 사용하는 코드이다. 일반적인 래스터 그래픽 이미지는 확대했을 경우 계단처럼 끊기는 것을 볼 수 있따.

하지만 벡터 이미지는 다르다. 웹 브라우저에서 CTRL 키를 누르고 마우스를 드래그해서 확대하여도 비트맵처럼 잔상 없이 부드러운 곡선이 만들어지는 것을 볼 수 있다.

게다가 SVG 태그는 이벤트를 연결해 사용자와 동적으로 반응할 수 있다. 또한 서버에서 실시간으로 데이터를 받아 반영하는 것도 가능하다.


SVG 추가 설명

SVG 태그에는 다음의 코드처럼 현재 코드가 어떠한 표준을 따르고 있는지 명시해준다.

<svg xmlns="http://www.w3.org/2008/svg" version="1.2">
</svg>

라파엘 플러그인

라파엘 플러그인은 자바스크립트를 사용해 SVG 태그를 쉽게 생성할 수 있는 플러그인이다. 

라파엘 공식 홈페이지

dmitrybaranovskiy.github.io/raphael/

 

Raphaël—JavaScript Library

 What is it? Raphaël is a small JavaScript library that should simplify your work with vector graphics on the web. If you want to create your own specific chart or image crop and rotate widget, for example, you can achieve it simply and easily with this

dmitrybaranovskiy.github.io

위의 사이트에서 라파엘 라이브러리를 다운받고 다음과 같이 설정한다.

<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script src="raphael.min.js"></script>
<body>
    <div id="canvas"></div>
</body>
<script>
      $(document).ready(function () {
        // 변수 선언
        var canvas = document.getElementById("canvas");
        var paper = Raphael(canvas, 700, 400);
        // 원 생성
        var rect = paper.rect(0, 0, 700, 300);
        var circle = paper.circle(350, 150, 100);
        // 색상 및 선 지정
        rect.attr("fill", "green");
        circle.attr("fill", "orange");
        circle.attr("stroke", "black");
      });
</script>

라파엘 플러그인 레퍼런스

dmitrybaranovskiy.github.io/raphael/reference.html

 

Raphaël Reference

Adds transformation to the element which is separate to other attributes, i.e. translation doesn’t change x or y of the rectange. The format of transformation string is similar to the path string syntax: "t100,100r30,100,100s2,2,100,100r45s1.5" Each lett

dmitrybaranovskiy.github.io


SVG 태그를 사용한 지도

대한민국 지도의 SVG 파일은 아래의 사이트에서 구할 수 있다.

commons.wikimedia.org/wiki/File:Administrative_divisions_map_of_South_Korea.svg

 

File:Administrative divisions map of South Korea.svg - Wikimedia Commons

 

commons.wikimedia.org

벡터 이미지를 SVG 파일로 변환할 때는 일러스트레이터를 사용하면 된다. 그리고 SVG 파일은 JSON 파일로 변환해야 쉽게 자바스크렙트에서 활용할 수 있다.

SVG 파일에서 불필요한 부분을 제거하거 XML to JSON 플러그인을 사용해 변경하면 된다.

참고로, SVG to JSON 컨버트는 구글에서 검색하면 여러 사이트들이 나오는데 원하는 곳에서 변경하면 된다.

korea.svg
0.10MB

대한민국 지도의 SVG 파일

//extending the attr function to return all attrs
(function ($) {
    // duck-punching to make attr() return a map
    var _old = $.fn.attr;
    $.fn.attr = function () {
        var a, aLength, attributes, map;
        if (this[0] && arguments.length === 0) {
            map = {};
            attributes = this[0].attributes;
            aLength = attributes.length;
            for (a = 0; a < aLength; a++) {
                map[attributes[a].name.toLowerCase()] = attributes[a].value;
            }
            return map;
        } else {
            return _old.apply(this, arguments);
        }
    }
}(jQuery));

$(document).ready(function () {
    $(".alert").css('display', 'none');
    $('#translate_button').click(function () {
        var rectar = true;
        var tag = $('#tag').val() || 'path';
        var name = $('#name').val();
        var file = $('#svg_file').val();
        var message = '';

        if (/ /.test(name)) {
            message += '<li>Variable Name Error</li>'
            rectar = false;
        }
        if (name == '') {
            message += '<li>Empty Name Error</li>'
            rectar = false;
        }
        if (/ /.test(tag)) {
            message += '<li>Tag Name Error</li>'
            rectar = false;
        }
        if (!(/</.test(file))) {
            message += '<li>Invalid File Error</li>'
            rectar = false;
        }
        if (!rectar) {
            $(".alert").css('display', 'block');
            $('#error_message').html(message);
        } else {
            $(".alert").css('display', 'none');
            
            var child = window.open();
            child.document.write(file);
            var paths = child.document.getElementsByTagName(tag);
            var condrasa = [];
            for (var i = 0; i < paths.length; i++) {
                var path = paths[i];
                condrasa.push($(path).attr());
            }
            var output = 'var ' + $('#name').val() + ' = ' + JSON.stringify(condrasa);
            $('#output').text(unescape(output));
            child.close();
            // window.clipboardData.setData('Text', output);
        }
    });
});

위의 코드를 사용하여 만든 JSON 파일은 다음과 같다.

KoreaMapData.js
0.10MB

SVG파일을 JSON파일로 변환한 파일

이 파일을 다음과 같이 불러와서 작업한다.

<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script src="KoreaMapData.js"></script>
<script src="raphael.min.js"></script>
<body>
  <figure id="map_image"></figure>
</body>
<script>
      $(document).ready(function () {
        function randomColor() {
          var letters = "0123456789ABCDEF".split("");
          var color = "#";
          for (var i = 0; i < 6; i++) {
            color += letters[Math.round(Math.random() * 15)];
          }
          return color;
        }

        var canvas = document.getElementById("map_image");
        var paper = Raphael(canvas, 500, 716);

        $.each(koreaMapPathData, function (index, item) {
          var path = paper.path(item["d"]);
          path.attr("stroke", item["stroke"]);
          if (item["fill"] != "none") {
            path.attr("fill", randomColor());
          }
        });
      });
</script>

웹 브라우저에서 확인해보면 지도 데이터가 랜덤한 색이 입혀서 보이는 것을 볼 수 있다.

SVG 태그를 사용해 랜덤한 색상을 적용한 지도

최근 데이터 시각화가 뜨면서 통계 자료와 SVG 태그를 합치는 일이 늘어나고 있다. SVG 태그와 통계 자료를 사용하면 실시간으로 반응하는 데이터 시각화 프로그램을 만들 수 있다.

또한 이벤트를 넣을 수 있으므로 각각의 지역을 클릭했을 때 팝업 화면도 띄울 수 있다.

 

Comments