SVGを使ってみる


## 概要

SVGは「Scalable Vector Graphics」の略。
ラスタ画像に対する、ベクタ画像ですね。
d3.jsを使おうと思ったらでてきて、使ったことなかったので使ってみる。

Android2.0, IE8以前では使用できないので注意。


## サンプル

### 図形を描画してみる

```html
<!DOCTYPE html>
<html lang="ja">
<head
    <meta charset="utf-8">
    <title>SVG Test</title>
</head>
<body>
    <svg width="640" height="480" viewBox="0 0 640 480">
        <defs>
            <style type="text/css"><![CDATA[
                #myBox {
                    stroke: black;
                    stroke-width: 3;
                    stroke-dasharray:20 5;
                }
            ]]></style>
            <linearGradient id="g1" x1="0" y1="0" x2="1" y2="1">
                <stop offset="0" stop-color="skyblue" />
                <stop offset="0.5" stop-color="pink" />
                <stop offset="1" stop-color="yellow" stop-opacity="0.5" />
            </linearGradient>
            <radialGradient id="g2" cx="0.5" cy="0.5" r="0.5">
                <stop offset="0" stop-color="skyblue" />
                <stop offset="0.8" stop-color="pink" />
                <stop offset="1" stop-color="yellow" stop-opacity="0.5" />
            </radialGradient>
        </defs>
        <g stroke="black">
            <rect width="30%" height="30%" fill="red" />
            <rect width="600" height="400" fill="#00ff00" style="stroke-width: 3; stroke-dasharray:20 5;"/>
            <rect width="500" height="300" fill="rgb(0,0,255)" stroke="blue" stroke-width="3" stroke-dasharray="20,5"/>
            <rect width="400" height="200" fill="rgba(255,255,255,0.4)" id="myBox"/>
            <rect x="50" y="100" rx="20" ry="20" width="300" height="100" fill="url(#g1)"/>
            <rect width="50" height="50" fill="url(#g2)"/>
            <line x1="100" y1="100" x2="200" y2="200" stroke-width="5" stroke="black" stroke-linecap="round"/>
            <circle cx="200" cy="100" r="40" fill="white"/>
            <ellipse cx="400" cy="400" rx="40" ry="80" fill="green"/>
            <polyline points="100 50 150 100 50 100" stroke="black" fill="none"/>
            <polygon points="200 150 250 200 150 200" stroke="black" fill="none"/>
            <path d="M100 50 l50 50 h100 v100 h100" stroke="black" stroke-width="20" fill="none"/>
            <text x="10" y="400" font-size="64" fill="white" stroke="black" stroke-width="2" rotate="20">
                Unlimited Blaze Works.
            </text>
        </g>
    </svg>
</body>
</html>
```

### transformを使ってみる

```html
<!DOCTYPE html>
<html lang="ja">
<head
    <meta charset="utf-8">
    <title>SVG Test</title>
</head>
<body>
    <svg width="640" height="480" viewBox="0 0 640 480">
        <rect width="600" height="300" fill="red"/>
        <rect width="100" height="100" fill="green" opacity="0.2" transform="translate(50,50)"/>
        <rect width="100" height="100" fill="green" opacity="0.2" transform="skewX(30)"/>
        <rect width="100" height="100" fill="green" opacity="0.2" transform="rotate(30)"/>
        <rect width="100" height="100" fill="green" opacity="0.2" transform="scale(2, 1.5)"/>
        <rect width="100" height="100" fill="white" opacity="0.5"/>
    </svg>
</body>
</html>
```

### animateを使ってみる

```html
<!DOCTYPE html>
<html lang="ja">
<head
    <meta charset="utf-8">
    <title>SVG Test</title>
</head>
<body>
    <svg width="640" height="480" viewBox="0 0 640 480">
        <rect width="600" height="300" fill="red"/>
        <circle cx="100" cy="100" r="20" fill="white">
            <animate attributeName="r" from="20" to="100" dur="2s" repeatCount="indefinite"/>
        </circle>
        <circle cx="300" cy="100" r="20" fill="blue">
            <animate attributeName="r" from="20" to="100" dur="2s" begin="1s" repeatCount="indefinite"/>
        </circle>
    </svg>
</body>
</html>
```


### JavaScriptで操作してみる

```html
<!DOCTYPE html>
<html lang="ja">
<head
    <meta charset="utf-8">
    <title>SVG Test</title>
</head>
<body>
    <svg width="640" height="480" viewBox="0 0 640 480">
        <rect width="600" height="300" fill="red"/>
        <circle cx="100" cy="100" r="20" fill="white">
            <animate attributeName="r" from="20" to="100" dur="2s" repeatCount="indefinite"/>
        </circle>
        <circle cx="300" cy="100" r="20" fill="blue">
            <animate attributeName="r" from="20" to="100" dur="2s" begin="1s" repeatCount="indefinite"/>
        </circle>
    </svg>
    <svg width="640" height="480" viewBox="0 0 640 480" onload="
        var c = document.getElementsByTagName('circle');
        for (var i = 0; i < c.length; i++) {
            c[i].setAttribute('cx', r(640));
            c[i].setAttribute('cy', r(480));
            c[i].setAttribute('r', r(100));
            c[i].setAttribute('fill', 'rgb(' + r(255) + ',' + r(255) + ',' + r(255) + ')');
            c[i].onmousedown = function(e) { alert(e.target.tagName); };
        }
        document.getElementById('myLine').onmousedown = function(e) { alert(e.target.tagName + ':' + e.offsetX + ',' + e.offsetY); };
        function r(n) {
            return Math.floor(Math.random() * (n + 1));
        }
    ">
        <rect width="600" height="300" fill="red"/>
        <circle cx="100" cy="100" r="20" fill="white" onmousedown="alert('hoge')" />
        <circle cx="100" cy="100" r="20" fill="white"/>
        <circle cx="100" cy="100" r="20" fill="white"/>
        <circle cx="100" cy="100" r="20" fill="white"/>
        <circle cx="100" cy="100" r="20" fill="white"/>
        <line x1="0" y1="0" x2="100" y2="100" stroke="black" stroke-width="10" id="myLine" />
    </svg>
</body>
</html>
```

### グループ化して部品化

```html
<!DOCTYPE html>
<html lang="ja">
<head
    <meta charset="utf-8">
    <title>SVG Test</title>
</head>
<body>
    <svg width="640" height="480" viewBox="0 0 640 480" onload="
        var list = document.getElementsByTag('g');
    ">
        <rect width="600" height="300" fill="red"/>
        <g transform="translate(100,100)">
            <line x1="0" y1="0" x2="100" y2="100" stroke="black" stroke-width="10" id="testLine" />
            <text x="50" y="50" stroke="black" font-size="32">とりゃー</text>
        </g>
    </svg>
</body>
</html>
```


## 参考

- [マークアップエンジニアのためのSVG入門](https://app.codegrid.net/entry/svg-basic)