ねっとぱんだ-プログラミング勉強ブログ-

Webデザイン、プログラミングの勉強ブログ。

【javascript・SVG】SVGの基本とjavascriptを使ってのアニメーション

svg

  • scalable Vector Graphics
  • 拡大縮小してもきれいに見える
  • XMLで書かれている

svgタグの書き方

<svg width="600" height="300" viewBox="0 0 400 200">
<rect width="400" height="400" fill="red"/>
<rect width="100" height="50" fill="blue"/>
</svg>
  • 閉じタグない物には「/」を末尾につける。
  • 下に書いたものの方が描画するとき上に描画される
rect
四角形を作れる。
viewbox
svgのどの位置を枠の中に表示させるかという指定。
例えば「<svg width="600" height="300" viewBox="0 0 400 200">」なら左上(0 0)の座評からx軸400、y軸200の位置までを600 x 300の中に描画するという命令。

基本的な記述

fill
色を塗りつぶす設定

色指定方法と重なり

<svg width="600" height="300">
<rect width="600" height="300" fill="red"/>
<rect width="500" height="250" fill="#00ff00"/>
<rect width="400" height="200" fill="rgb(0,0,255)"/>
<rect width="300" height="150" fill="rgba(255,255,255,0.4)"/>
</svg>
stroke
線の描画の設定
stroke-width
線の太さの設定
stroke-dasharray
破線を指定。
「stroke-dasharray="20,5"」=20px幅の破線を5px置きに描画。
<svg width="600" height="300">
<rect width="600" height="300" fill="red" stroke="#000" stroke-width="10"/>
  • styleタグを使う場合
<rect width="600" height="300" style="fill:red; stroke:#000; stroke-width:10; stroke-dasharray:20,5;"/>
  • defsタグの中に記述

分りやすいためこの書き方が推奨されている。
https://developer.mozilla.org/ja/docs/Web/SVG/Element/defs

<svg width="600" height="300">
<defs>
<style type="text/css"><![CDATA[
    #box{
        fill:red;
        stroke:#000;
        stroke-width:10;
        stroke-dasharray:20,5; 
    }
]]></style>
</defs>
<rect width="600" height="300" id="box"/>
</svg>
g
gタグで囲んだものはgタグ内のスタイルが適用される。
上書きしたい場合は個別に指定していく。
<svg width="600" height="300">
<g stroke="black" stroke-width="10">
<rect width="600" height="300" fill="red"/>
<rect width="400" height="200" fill="green" stroke="blue"/>
<rect width="200" height="100" fill="blue"/>
</g>
</svg>
linearGradient
線形のグラデーションを作れる。
offset
グラデーションのどの位置か
stop-color
その地点での色
stop-opacity
その地点での透明度
x1,y1
開始地点の座標。0~1を入力する。
x2,y2
修了地点の座標。0~1を入力する。
<svg width="600" height="300">
<defs>
<linearGradient id="g1" x1="0.3" y1="0.3" x2="0.7" y2="0.7">
<stop offset="0" stop-color="#faa"/>
<stop offset="0.5" stop-color="#afa"/>
<stop offset="1" stop-color="#aaf" stop-opacity="0"/>
</linearGradient>
</defs>
<rect width="200" height="100" fill="url(#g1)"/>
</svg>
radialGradient
円形のグラデーションを作れる。
cx,cy
開始地点の座標。0~1を入力する。
r
半径の値
<svg width="600" height="300">
<defs>
<radialGradient id="g1" cx="0.5" cy="0.5" r="0.7">
<stop offset="0" stop-color="#faa"/>
<stop offset="0.5" stop-color="#afa"/>
<stop offset="1" stop-color="#aaf" stop-opacity="0"/>
</radialGradient>
</defs>
<rect width="200" height="100" fill="url(#g1)"/>
</svg>
ry,rx
角をまるくする
<svg width="600" height="300">
<defs>
</defs>
<rect width="600" height="300" fill="blue"/>
<rect x="50" y="50" width="200" height="100" rx="20" ry="20" fill="red"/>
</svg>
line
線を引ける
x1,y1
開始座標
x2,y2
終了座標
stroke-linecap
終端の形を変えられる。
<svg width="600" height="300">
<defs>
</defs>
<rect width="600" height="300" fill="blue"/>
<rect x="50" y="50" width="200" height="100" rx="20" ry="20" fill="red"/>
<rect x="50" y="50" width="200" height="100" rx="20" ry="20" fill="red"/>
<line x1="100" y1="100" x2="200" y2="200" stroke-width="20" stroke="black" stroke-linecap="round"/>
</svg>
circle
円形を書ける
<circle cx="200" cy="100" r="40" fill="green" />
ellipse
楕円を書ける
<ellipse cx="100" cy="100" rx="40" ry="80" fill="white" />
polyline
x,y座標を指定していってその線をつなげる線を描画していく。
<polyline points="100 50 150 100 20 100" stroke="black" fill="none"/>
polygon
最後閉じた図形にしたい場合。
<polygon points="100 50 150 100 20 100" stroke="black" fill="none"/>
path
線を指定して描画する
<path d="M100 50 l50 50 h100 v100 h100" stroke="black" fill="none"/>
text
テキストを描画する。
<svg width="600" height="300">
<defs>
</defs>
<rect width="600" height="300" fill="blue"/>
<text x="100" y="100" font-size="50" fill="white" stroke="black" width="2" rotate="20">ねっとぱんだ</text>
</svg>

transform

変形させる

translate
移動させる
<rect width="100" height="100" fill="green"  transform="translate(50,50)" />
skewX,skewY
x方向かy方向に変形させる
<rect width="100" height="100" fill="green"  transform="skewX(50)" />
rotate
回転させる
<rect width="100" height="100" fill="green"  transform="rotate(50)" />
scale(x方向,y方向)
拡大
<rect width="100" height="100" fill="green"  transform="scale(3,2)" />
animate
アニメーションさせる

アニメーションさせたい要素の閉じタグを作りその中にanimationタグを書き込んでいく。

attributeName
アニメーションさせたい値を指定する。
例「attributeName="r"」ならrがアニメーションしていく。
from
始まりの値
to
終わりの値
dur
duration
何秒かけて変化させるか
repeatCount
何回リピートするか。無制限にしたい場合はindefiniteと指定。
brgin
アニメーションが始まるまでの時間を指定。
<svg width="600" height="300">
<defs>
</defs>
<rect width="600" height="300" fill="blue"/>
<circle cx="100" cy="100" r="20" fill="white">
<animate attributeName="r" from="20" to="80" dur="2s" repeatCount="indefinite"/>
</circle>
</svg>
<svg width="600" height="300">
<rect width="600" height="300" fill="blue"/>
<circle cx="100" cy="100" r="20" fill="white">
<animate attributeName="r" from="20" to="80" dur="2s" repeatCount="indefinite"/>
</circle>
<circle cx="200" cy="100" r="20" fill="red">
<animate attributeName="r" from="10" to="130" dur="1s" begin="1s" repeatCount="indefinite"/>
</circle>
</svg>

javascriptを使用したSVGアニメーション

タイマー処理と擬似乱数で円のサイズ、表示位置、色を変える

html

<svg width="600" height="300">
<rect width="600" height="300" fill="#9afff7"/>
<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"/>
<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"/>
<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"/>
<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"/>
<circle cx="100" cy="100" r="20" fill="white"/>
<circle cx="100" cy="100" r="20" fill="white"/>
</circle>
</svg>

javascript

<script>
var c = document.getElementsByTagName('circle');
function svgAnimation(){
for(var i=0; i<c.length;i++){
c[i].setAttribute('cx',r(600));
c[i].setAttribute('cy',r(400));
c[i].setAttribute('r',r(100));
c[i].setAttribute('fill','rgba('+r(255)+','+r(255)+','+r(255)+','+'0.'+r(9)+')');
}
function r(n){
return Math.floor(Math.random() * (n+1));
}
console.log('animation');
setTimeout(svgAnimation,120);
}
svgAnimation();
</script>