How To Move Along A Path But Only Between Two Specified Path Points
Solution 1:
Well, I have to agree with LeBeau, and I see that you also do. Since I answered your last question, I just needed to do some minor changes in the function. However, keep his advise in mind for the next times: when asking a question, show us some code you've tried, even if it doesn't work, because it shows effort.
Back to the question.
For this solution, I'll wrap everything inside a function named move
, which accepts two arguments, the initial position and the final position (both in percentages):
functionmove(initialPosition, finalPosition) {
The initial position, as the name implies, set the initial position of the circle along the path. The math is this:
var start = path.node()
.getPointAtLength(path.node().getTotalLength() * initialPosition);
Then, I slightly changed the function from my last answer to accept the initial and final positions:
functiontranslateAlong(path) {
var l = path.getTotalLength() * (finalPosition - initialPosition);
returnfunction() {
returnfunction(t) {
var p = path.getPointAtLength(t * l +
(path.getTotalLength() * initialPosition));
return"translate(" + p.x + "," + p.y + ")";
};
};
}
Here is the demo. Clicking on the button calls move
with 0.25
(initial position) and 0.5
(final position) as arguments:
var points = [
[240, 100],
[290, 200],
[340, 50],
[390, 150],
[90, 150],
[140, 50],
[190, 200]
];
var svg = d3.select("body").append("svg")
.attr("width", 500)
.attr("height", 300);
var path = svg.append("path")
.data([points])
.attr("d", d3.svg.line()
.tension(0) // Catmull–Rom
.interpolate("cardinal-closed"));
var color = d3.scale.category10();
var dataPositions = [{
initial: 0.25,
final: 0.5
}, {
initial: 0.5,
final: 0.6
}];
svg.selectAll(".point")
.data(points)
.enter().append("circle")
.attr("r", 4)
.attr("transform", function(d) {
return"translate(" + d + ")";
});
d3.select("button").on("click", function() {
move(0.25, 0.5);
});
functionmove(initialPosition, finalPosition) {
var start = path.node().getPointAtLength(path.node().getTotalLength() * initialPosition);
var circle = svg.append("circle")
.attr("r", 13)
.attr("fill", function(d, i) {
returncolor(i)
})
.attr("transform", "translate(" + start.x + "," + start.y + ")");
circle.transition()
.duration(1000)
.attrTween("transform", function() {
returntranslateAlong(path.node())()
});
functiontranslateAlong(path) {
var l = path.getTotalLength() * (finalPosition - initialPosition);
returnfunction() {
returnfunction(t) {
var p = path.getPointAtLength(t * l +
(path.getTotalLength() * initialPosition));
return"translate(" + p.x + "," + p.y + ")";
};
};
}
}
path {
fill: none;
stroke: #000;
stroke-width: 3px;
}
circle {
stroke: #fff;
stroke-width: 3px;
}
<scriptsrc="//d3js.org/d3.v3.min.js"></script><button>Move</button><br>
PS: The function in this answer does not accept values bigger than 1. But you can try to change it if you need to do more than "one lap" in the path.
Post a Comment for "How To Move Along A Path But Only Between Two Specified Path Points"