Reputation: 1290
I have a d3.selectAll().each()
function that animates each of the path
s in my svg
container. Now I would like that the first path has a d3.easePolyIn
animation whereas the rest has a d3.easeLinear
animation.
However, my following code does not work (no animation happens at all):
d3.selectAll(".myPaths").each(function(d,i) {
d3.select(this)
.attr("stroke-dasharray", d3.select(this).node().getTotalLength() + " " + d3.select(this).node().getTotalLength())
.attr("stroke-dashoffset", d3.select(this).node().getTotalLength())
.transition()
.duration(d3.select(this).node().getTotalLength())
.ease(function(d) {if (i == 0) {return d3.easePolyIn} else {return d3.easeLinear}})
.attr("stroke-dashoffset", 0)
})
How can I achieve my goal?
Upvotes: 1
Views: 64
Reputation: 102219
Since you already have the index i
from the outer function (selection.each
), just use it in the ease
method directly:
.ease(i ? d3.easeLinear : d3.easePolyIn)
Here, the ternary returns d3.easeLinear
for all truthy values of i
(that is, all indices except 0
), and d3.easePolyIn
for the falsy value (the first index, 0
).
Here is a demo:
const svg = d3.select("svg")
const circles = svg.selectAll(null)
.data([1, 1])
.enter()
.append("circle")
.attr("r", 15)
.attr("cx", 15)
.attr("cy", (_, i) => i ? 100 : 50)
.each(function(_, i) {
d3.select(this)
.transition()
.ease(i ? d3.easeLinear : d3.easePolyIn)
.duration(1000)
.attr("cx", 280)
});
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>
The problem with your attempt is that transition.ease
expects a function itself. So, when you just return d3.easeLinear
or d3.easePolyIn
, that's not going to work. For using your approach, you have to pass the normalised time, idiomatically named t
:
.ease(function(t) {
if (i == 0) {
return d3.easePolyIn(t)
} else {
return d3.easeLinear(t)
}
})
And here is the corresponding demo:
const svg = d3.select("svg")
const circles = svg.selectAll(null)
.data([1, 1])
.enter()
.append("circle")
.attr("r", 15)
.attr("cx", 15)
.attr("cy", (_, i) => i ? 100 : 50)
.each(function(_, i) {
d3.select(this)
.transition()
.ease(function(t) {
if (i == 0) {
return d3.easePolyIn(t)
} else {
return d3.easeLinear(t)
}
})
.duration(1000)
.attr("cx", 280)
});
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>
Upvotes: 1