SVGをぬるぬる動かしたいので勉強中
SVGアニメーション習作。
D3のトランジション機能を使うことで殆どの用途を満たせるとは思うのですが、一定間隔でループするようなアニメーション(例えば点滅するマーカーなど)は、svgのanimate機能を使って最初に定義してしまった方が書きやすいかな?と思っていろいろ試しています。
今のところ詳しく解説できるほどSVGアニメーションについて理解できていないのですが、ひとまず習作として作ったもののサンプルコードだけ載せておきます。
参考
An Intro to SVG Animation with SMIL by Noah Blon on CodePen
The State of SVG Animation : Adobe Dreamweaver Team Blog
アニメーションパス
上記参考サイトからパクったものです。なので詳細については上記サイトをご覧ください。
pathの子要素としてanimate要素を登録してあります。ひとつめのanimate要素はパスの変形を、ふたつめのanimate要素はfill(塗り)の変移を指定しています。
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
<svg> <path fill="#1EB287"> <animate attributeName="d" dur="3000ms" repeatCount="indefinite" keyTimes=" 0; .0625; .208333333; .3125; .395833333; .645833333; .833333333; 1" calcMode="spline" keySplines=" 0,0,1,1; .42,0,.58,1; .42,0,1,1; 0,0,.58,1; .42,0,.58,1; .42,0,.58,1; .42,0,.58,1" values=" M 0,0 C 50,0 50,0 100,0 100,50 100,50 100,100 50,100 50,100 0,100 0,50 0,50 0,0 Z; M 0,0 C 50,0 50,0 100,0 100,50 100,50 100,100 50,100 50,100 0,100 0,50 0,50 0,0 Z; M 50,0 C 75,25 75,25 100,50 75,75 75,75 50,100 25,75 25,75 0,50 25,25 25,25 50,0 Z; M 25,50 C 37.5,25 37.5,25 50,0 75,50 75,50 100,100 50,100 50,100 0,100 12.5,75 12.5,75 25,50 Z; M 25,50 C 37.5,25 37.5,25 50,0 75,50 75,50 100,100 50,100 50,100 0,100 12.5,75 12.5,75 25,50 Z; M 50,0 C 77.6,0 100,22.4 100,50 100,77.6 77.6,100 50,100 22.4,100, 0,77.6, 0,50 0,22.4, 22.4,0, 50,0 Z; M 50,0 C 77.6,0 100,22.4 100,50 100,77.6 77.6,100 50,100 22.4,100, 0,77.6, 0,50 0,22.4, 22.4,0, 50,0 Z; M 100,0 C 100,50 100,50 100,100 50,100 50,100 0,100 0,50 0,50 0,0 50,0 50,0 100,0 Z;"/> <animate attributeName="fill" dur="3000ms" repeatCount="indefinite" keyTimes=" 0; .0625; .208333333; .3125; .395833333; .645833333; .833333333; 1" calcMode="spline" keySplines=" 0,0,1,1; .42,0,.58,1; .42,0,1,1; 0,0,.58,1; .42,0,.58,1; .42,0,.58,1; .42,0,.58,1" values=" #1eb287; #1eb287; #1ca69e; #188fc2; #188fc2; #bb625e; #ca5f52; #1eb287;"/> </path> </svg> |
再利用
アニメーション指定してあるpath要素をdefsの中に入れ、use要素で呼び出して使うことで再利用が可能です。
また今回はuse要素のtransform属性でスケールを1/4に縮小して表示しています。
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
<svg> <defs> <path id="anim-path" fill="#1EB287"> <animate attributeName="d" dur="3000ms" repeatCount="indefinite" keyTimes=" 0; .0625; .208333333; .3125; .395833333; .645833333; .833333333; 1" calcMode="spline" keySplines=" 0,0,1,1; .42,0,.58,1; .42,0,1,1; 0,0,.58,1; .42,0,.58,1; .42,0,.58,1; .42,0,.58,1" values="M 0,0 C 50,0 50,0 100,0 100,50 100,50 100,100 50,100 50,100 0,100 0,50 0,50 0,0 Z; M 0,0 C 50,0 50,0 100,0 100,50 100,50 100,100 50,100 50,100 0,100 0,50 0,50 0,0 Z; M 50,0 C 75,25 75,25 100,50 75,75 75,75 50,100 25,75 25,75 0,50 25,25 25,25 50,0 Z; M 25,50 C 37.5,25 37.5,25 50,0 75,50 75,50 100,100 50,100 50,100 0,100 12.5,75 12.5,75 25,50 Z; M 25,50 C 37.5,25 37.5,25 50,0 75,50 75,50 100,100 50,100 50,100 0,100 12.5,75 12.5,75 25,50 Z; M 50,0 C 77.6,0 100,22.4 100,50 100,77.6 77.6,100 50,100 22.4,100, 0,77.6, 0,50 0,22.4, 22.4,0, 50,0 Z; M 50,0 C 77.6,0 100,22.4 100,50 100,77.6 77.6,100 50,100 22.4,100, 0,77.6, 0,50 0,22.4, 22.4,0, 50,0 Z; M 100,0 C 100,50 100,50 100,100 50,100 50,100 0,100 0,50 0,50 0,0 50,0 50,0 100,0 Z;"/> <animate attributeName="fill" dur="3000ms" repeatCount="indefinite" keyTimes=" 0; .0625; .208333333; .3125; .395833333; .645833333; .833333333; 1" calcMode="spline" keySplines=" 0,0,1,1; .42,0,.58,1; .42,0,1,1; 0,0,.58,1; .42,0,.58,1; .42,0,.58,1; .42,0,.58,1" values=" #1eb287; #1eb287; #1ca69e; #188fc2; #188fc2; #bb625e; #ca5f52; #1eb287;"/> </path> </defs> <use xlink:href="#anim-path" transform="translate(0, 10) scale(0.25,0.25)"/> <use xlink:href="#anim-path" transform="translate(50,10) scale(0.25,0.25)"/> <use xlink:href="#anim-path" transform="translate(100, 10) scale(0.25,0.25)"/> </svg> |
D3.jsで使う
D3を使ってアニメーションパスを散布図の点として表示してみました。
見やすくはありません。あまり使いどころは無いかもしれませんが、D3で表示した地図上のマーカーをアニメーションさせたいときなどに便利かもしれません。
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <title>SVG animate example 3</title> <style> .axis path, .axis line { fill: none; stroke: black; shape-rendering: crispEdges; } .axis text { font-family: sans-serif; font-size: 11px; } </style> </head> <body> <svg> <defs> <path id="anim-path" fill="#1EB287"> <animate attributeName="d" dur="3000ms" repeatCount="indefinite" keyTimes=" 0; .0625; .208333333; .3125; .395833333; .645833333; .833333333; 1" calcMode="spline" keySplines=" 0,0,1,1; .42,0,.58,1; .42,0,1,1; 0,0,.58,1; .42,0,.58,1; .42,0,.58,1; .42,0,.58,1" values="M 0,0 C 50,0 50,0 100,0 100,50 100,50 100,100 50,100 50,100 0,100 0,50 0,50 0,0 Z; M 0,0 C 50,0 50,0 100,0 100,50 100,50 100,100 50,100 50,100 0,100 0,50 0,50 0,0 Z; M 50,0 C 75,25 75,25 100,50 75,75 75,75 50,100 25,75 25,75 0,50 25,25 25,25 50,0 Z; M 25,50 C 37.5,25 37.5,25 50,0 75,50 75,50 100,100 50,100 50,100 0,100 12.5,75 12.5,75 25,50 Z; M 25,50 C 37.5,25 37.5,25 50,0 75,50 75,50 100,100 50,100 50,100 0,100 12.5,75 12.5,75 25,50 Z; M 50,0 C 77.6,0 100,22.4 100,50 100,77.6 77.6,100 50,100 22.4,100, 0,77.6, 0,50 0,22.4, 22.4,0, 50,0 Z; M 50,0 C 77.6,0 100,22.4 100,50 100,77.6 77.6,100 50,100 22.4,100, 0,77.6, 0,50 0,22.4, 22.4,0, 50,0 Z; M 100,0 C 100,50 100,50 100,100 50,100 50,100 0,100 0,50 0,50 0,0 50,0 50,0 100,0 Z;"/> <animate attributeName="fill" dur="3000ms" repeatCount="indefinite" keyTimes=" 0; .0625; .208333333; .3125; .395833333; .645833333; .833333333; 1" calcMode="spline" keySplines=" 0,0,1,1; .42,0,.58,1; .42,0,1,1; 0,0,.58,1; .42,0,.58,1; .42,0,.58,1; .42,0,.58,1" values=" #1eb287; #1eb287; #1ca69e; #188fc2; #188fc2; #bb625e; #ca5f52; #1eb287;"/> </path> </defs> </svg> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.min.js"></script> <script src="index.js"></script> </body> </html> |
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
//ステージの 幅( Width )と高さ( height ) var w = 600; var h = 300; var padding = 30; //ランダムなデータセットを作る var dataset = []; var numDataPoints = 30; var xRange = Math.random() * 1000; var yRange = Math.random() * 1000; for (var i = 0; i < numDataPoints; i++) { var newNumber1 = Math.round(Math.random() * xRange); var newNumber2 = Math.round(Math.random() * yRange); dataset.push([newNumber1, newNumber2]); } // スケール関数の生成 var xScale = d3.scale.linear() .domain([0, d3.max(dataset, function(d) { return d[0]; })]) .range([padding, w - padding * 2]); var yScale = d3.scale.linear() .domain([0, d3.max(dataset, function(d) { return d[1]; })]) .range([h - padding, padding]); var rScale = d3.scale.linear() .domain([0, d3.max(dataset, function(d) { return d[1]; })]) .range([2, 5]); // X 軸の定義 var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom") .ticks(5); // Y 軸の定義 var yAxis = d3.svg.axis() .scale(yScale) .orient("left") .ticks(5); // SVG 要素の生成 var svg = d3.select("svg") .attr("width", w) .attr("height", h); // グループの生成 var cell = svg.selectAll("g") .data(dataset) .enter() .append('g'); //アニメーションセル cell.append('use') .attr({ 'xlink:href': '#anim-path', 'transform':function(d){ return 'translate('+[xScale(d[0])-(25/2), yScale(d[1])-(25/2)]+') scale(0.25,0.25)' } }); // X 軸の生成 svg.append("g") .attr("class", "axis") .attr("transform", "translate(0," + (h - padding) + ")") .call(xAxis); // Y 軸の生成 svg.append("g") .attr("class", "axis") .attr("transform", "translate(" + padding + ",0)") .call(yAxis); |