[D3.js]トランジションをpromiseを使って管理する。
タイトルのまんまの内容です。
仕事でデータビジュアライゼーションを作成していると、「AとBの要素のトランジションが完了してから、Bのトランジションを始める」など複雑なアニメーションが必要になることが多々有ります。
複数の要素を動かしつつトランジションを繋ぐのにコールバックでは複雑になりすぎて管理が難しいので、最近はpromiseを使っています。まだ使いこなせていませんが、便利なのでサンプルコードを載せておきます。
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 |
const svg = d3.select('svg') const circle = svg.append("circle") .attr("cx", 100) .attr("cy", 50) .attr("r", 20) const rect = svg.append("rect") .attr("x", 100) .attr("y", 100) .attr("width", 30) .attr("height", 30) const line = svg.append("line") .attr("x1", 100) .attr("y1", 150) .attr("x2", 100) .attr("y2", 150) .attr("stroke", "black") //D3のトランジションをpromiseで包む const p1 = () => { return new Promise((resolve, reject) => { circle.transition().duration(Math.floor(Math.random()*5000)) .attr("cx", 800) .on("end", resolve) }) } const p2 = () => { return new Promise((resolve, reject) => { rect.transition().duration(Math.floor(Math.random()*5000)) .attr("x", 800) .on("end", resolve) }) } const p3 = () => { return new Promise((resolve, reject) => { line.transition().duration(Math.floor(Math.random()*5000)) .attr("x2", 800) .on("end", resolve) }) } d3.select("button").on("click", function(){ //ポジションをリセット d3.select("body").style("background-color", "white") circle.attr("cx", 100) rect.attr("x", 100) line.attr("x2", 100) //トランジション開始 Promise.all([p1(), p2(), p3()]).then(endFn) }) //トランジションが終了したら背景色を変える function endFn(){ d3.select("body").style("background-color", "pink") } |