
解説:
D3ではtransition()の後に新しい位置や色などを設定することで、自動的にアニメーションが作れます。
アニメーションの途中の動きをどうするかは、ease()の中で設定できます。たとえばease(“exp”)なら、最初は遅く、到達点に近づくほど指数関数的に早く変化します。bounceを入れるとボールが跳ねるように行きつ戻りつつ到達点に落ち着きます。backは車のバックを真似た動きになります。elasticはヒモがしなるように、到達点を一度超えてから到着します。
さらにオプションもあります。-inはそのままの動き。-outをつけるとその逆の動きになります。-in-outは途中まではinで後半はoutになり、-out-inなら途中までoutで後半はinになります。
例えば下のコードのようになります。
var circles = svg.selectAll("circle").data(data).enter() .append("circle") .attr("cx", function(d){ return d;}) .attr("cy", function(d){ return d;}) .attr("r", 30) .attr("fill", "green"); circles.transition() .ease("bounce-in-out") // easeを設定する。 .attr("r",0);
ですからD3で標準で使えるアニメーションの遷移は、次のように2つのリストの組み合わせになります。[linear,quad,cubic,sin,exp,circle,elastic,back,bounce]X[-in,-out,-in-out,-out-in]
詳しくは上のリンク先のアニメーションのページで実際に見てください。
実際のコード:
var width = 760, height = 500; var data = [100,200,300]; var eases = ["linear","quad","cubic","sin","exp","circle","elastic","back","bounce"]; var inouts = ["-in","-out","-in-out","-out-in"]; var easesCount = 0; var inoutCount = 0; var roundEasesCount = 0; var roundInoutCount = 0; var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height); var circles = svg.selectAll("circle").data(data).enter() .append("circle") .attr("cy", 40) .attr("cx", function(d){ return d;}) .attr("r", 10) .attr("fill", "green"); var description = svg.append("text") .attr("x",200) .attr("y",400) .attr("text-anchor","middle") .attr("stroke","blue") function easeCircle(){ // easeのカウントが一周して0に戻ったならintoutのカウントを上げる。 if (roundEasesCount == 8){ inoutCount++; } // easesのリストを循環する。 roundEasesCount = easesCount%eases.length; var ease = eases[roundEasesCount]; // inoutsのリストを循環する。 roundInoutCount = inoutCount%inouts.length; var inout = inouts[roundInoutCount]; // easeとinoutを足して組み合わせをつくる。 var currentEasing = ease+inout; console.log(currentEasing); description.text(currentEasing); // 今のeaseを使ってアニメーション。 var moving = circles.transition() .duration(function(d){return d*3; }) .ease(currentEasing) .attr("cy", function(d){ return d;}) .attr("fill", "red"); // 元の位置に戻る。 moving.transition() .delay(1100) .duration(0) .attr("cy", 40) .attr("fill", "green"); easesCount++; console.log(roundEasesCount); console.log(inoutCount); } setInterval(easeCircle,1900);