Reputation: 376
What needs to be done that the second transition of the green circle behaves like the second transition of the blue circle?
I would have expected that the transitions of both circles behave the same. However it seems that the first transition of the green circle is applied in place of the second transition.
const svg = d3.select("svg");
const blueCircle = svg.append("circle")
.attr("cx", 10)
.attr("cy", 10)
.attr("r", 5)
.style("fill", "blue");
const greenCircle = svg.append("circle")
.attr("cx", 10)
.attr("cy", 30)
.attr("r", 5)
.style("fill", "green");
blueCircle
.transition()
.duration(4000)
.ease(d3.easeLinear)
.attr("cx", 100)
.transition()
.duration(2000)
.ease(d3.easeElastic)
.attr("cx", 200);
const firstTransition = d3.transition()
.duration(4000)
.ease(d3.easeLinear);
const secondTransition = d3.transition()
.duration(2000)
.ease(d3.easeElastic);
greenCircle
.transition(firstTransition)
.attr("cx", 100)
.transition(secondTransition)
.attr("cx", 200);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.14.2/d3.min.js"></script>
<svg width="250" height="50"></svg>
Update
Thanks to Coola's answer and this question, I found a possibility to make the second transition of the green circle work as expected:
const greenCircle = svg.append("circle")
.attr("class", "green")
.attr("cx", 10)
.attr("cy", 30)
.attr("r", 5)
.style("fill", "green");
const firstTransition = d3.transition()
.duration(4000)
.ease(d3.easeLinear);
const secondTransition = firstTransition.transition()
.duration(2000)
.ease(d3.easeElastic);
firstTransition
.select("circle.green")
.attr("cx", 100);
secondTransition
.select("circle.green")
.attr("cx", 200);
However, this code has still the following flaws:
Does anybody know a solution without these issues, especially for the first point?
Upvotes: 3
Views: 78
Reputation: 3162
In order to chain the transitions you have to use the on("end", function(){<do something>})
.
You can read more about advanced control flows in the documentation.
greenCircle
.transition(firstTransition)
.attr("cx", 100)
.on("end", () => {
greenCircle.transition(secondTransition)
.attr("cx", 200);
});
Full Snippet:
const svg = d3.select("svg");
const blueCircle = svg.append("circle")
.attr("cx", 10)
.attr("cy", 10)
.attr("r", 5)
.style("fill", "blue");
const greenCircle = svg.append("circle")
.attr("cx", 10)
.attr("cy", 30)
.attr("r", 5)
.style("fill", "green");
blueCircle
.transition()
.duration(4000)
.ease(d3.easeLinear)
.attr("cx", 100)
.transition()
.duration(2000)
.ease(d3.easeElastic)
.attr("cx", 200);
const firstTransition = d3.transition()
.duration(4000)
.ease(d3.easeLinear);
const secondTransition = d3.transition()
.duration(2000)
.ease(d3.easeElastic);
greenCircle
.transition(firstTransition)
.attr("cx", 100)
.on("end", () => {
greenCircle.transition(secondTransition)
.attr("cx", 200);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.14.2/d3.min.js"></script>
<svg width="250" height="50"></svg>
UPDATE:
The above code solves only part of the problem. You will notice the animation is not exactly identical between the blue and green circles.
You also need to chain the firstTransition
into the secondTransition
const
. Like:
const secondTransition = firstTransition.transition()
.duration(2000)
.ease(d3.easeElastic);
Full snippet:
const svg = d3.select("svg");
const blueCircle = svg.append("circle")
.attr("cx", 10)
.attr("cy", 10)
.attr("r", 5)
.style("fill", "blue");
const greenCircle = svg.append("circle")
.attr("cx", 10)
.attr("cy", 30)
.attr("r", 5)
.style("fill", "green");
blueCircle
.transition()
.duration(4000)
.ease(d3.easeLinear)
.attr("cx", 100)
.transition()
.duration(2000)
.ease(d3.easeElastic)
.attr("cx", 200);
const firstTransition = d3.transition()
.duration(4000)
.ease(d3.easeLinear);
const secondTransition = firstTransition.transition()
.duration(2000)
.ease(d3.easeElastic);
greenCircle
.transition(firstTransition)
.attr("cx", 100)
.on("end", function () {
greenCircle.transition(secondTransition)
.attr("cx", 200);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.14.2/d3.min.js"></script>
<svg width="250" height="50"></svg>
Upvotes: 1